From patchwork Wed Aug 18 18:43:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12444989 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75732C4338F for ; Wed, 18 Aug 2021 18:43:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 55AFE610FF for ; Wed, 18 Aug 2021 18:43:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232772AbhHRSn7 (ORCPT ); Wed, 18 Aug 2021 14:43:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232584AbhHRSny (ORCPT ); Wed, 18 Aug 2021 14:43:54 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9BB6C0613CF for ; Wed, 18 Aug 2021 11:43:19 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id r35-20020a635d230000b0290239a31e9f24so1957355pgb.9 for ; Wed, 18 Aug 2021 11:43:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=sybk7YcBeZufJ2AiOux9y0QLju0ZjmiMoQ+rDeqF05I=; b=KyWRMVB2YjHXSj3SrlXBQ1vUcQjS4upaB1ecKlUekeQMP3aw4uhnG6uXijlPT/31ui Z28ax39JzZAx1Z7J8FJei5MIVv98GH6r7vIQCEG3PfaFCvB4WEuqVRxab5ga+fSTQmeY j5QUx4OUcKTj4AdUaQMpWPvrugwRMTrM64LTE1De5ouxE5IHLW5fPrrULhaBEHdcoHGo hmbDITScovX72Zyu4nY8lVbvpgAGK8k1T0EtpyvDMXvLOlNKXz+0BX/BgPjyaT1zNHnT rqsSfheHhwSn27ZcOd/7GIFehJ32fm81DLLxjUIGrGL2qdhydKSCw30/2SGJncJylHge 2juw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=sybk7YcBeZufJ2AiOux9y0QLju0ZjmiMoQ+rDeqF05I=; b=ZPdDvQhRP4EJb7sAdvzD+YD5jutRdfY+XRnluGR101tsdPg1KsR1HQ4TLSi9Iom7UJ b1gfXddb9vK0wXK6i126WSo0b4bgntwOAtke8UJ0T+Agi0RQETsHXF8FIVHXjXsDi9ty 2bw+mBKYCECeFi6ndyohqGVcZohRKjdh+waMBZO7gJlGo9IzuaJ87yR6y+CJ8B8WlSCG N7BsQUAFSEruTLN0PWissa/pd0tmch6Ds+2LhH4EhEprhIW2wrXNh/pTaOYjJfOAfhDb d6ZFbI/JdII9SyZteY0IxMojoIIQo2t/2azn4I7y5w07slhsVOw0UY36qVlR4p+zDGuU l/RA== X-Gm-Message-State: AOAM532sc2emibV9HQRmSLMKEwBj/AcY8fDe6dUYS7zfrzcSX6PQVxzs uS9A4zjQuokpjM+DHpCAvkWZy43horA+ X-Google-Smtp-Source: ABdhPJwpulpudlfIiB7CO8SfhZeZ9mfxxExEhDLOhAm5IzLeR7emCgSi+C7ROeGvaAWlJ6EMz8iciBV4Xt6V X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:90b:396:: with SMTP id ga22mr92005pjb.0.1629312198788; Wed, 18 Aug 2021 11:43:18 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:02 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-2-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 01/10] KVM: arm64: selftests: Add MMIO readl/writel support From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Define the readl() and writel() functions for the guests to access (4-byte) the MMIO region. The routines, and their dependents, are inspired from the kernel's arch/arm64/include/asm/io.h and arch/arm64/include/asm/barrier.h. Signed-off-by: Raghavendra Rao Ananta --- .../selftests/kvm/include/aarch64/processor.h | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h index 27dc5c2e56b9..14f68bf55036 100644 --- a/tools/testing/selftests/kvm/include/aarch64/processor.h +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h @@ -127,6 +127,49 @@ void vm_install_sync_handler(struct kvm_vm *vm, val; \ }) -#define isb() asm volatile("isb" : : : "memory") +#define isb() asm volatile("isb" : : : "memory") +#define dsb(opt) asm volatile("dsb " #opt : : : "memory") +#define dmb(opt) asm volatile("dmb " #opt : : : "memory") + +#define dma_wmb() dmb(oshst) +#define __iowmb() dma_wmb() + +#define dma_rmb() dmb(oshld) + +#define __iormb(v) \ +({ \ + unsigned long tmp; \ + \ + dma_rmb(); \ + \ + /* \ + * Courtesy of arch/arm64/include/asm/io.h: \ + * Create a dummy control dependency from the IO read to any \ + * later instructions. This ensures that a subsequent call \ + * to udelay() will be ordered due to the ISB in __delay(). \ + */ \ + asm volatile("eor %0, %1, %1\n" \ + "cbnz %0, ." \ + : "=r" (tmp) : "r" ((unsigned long)(v)) \ + : "memory"); \ +}) + +static __always_inline void __raw_writel(u32 val, volatile void *addr) +{ + asm volatile("str %w0, [%1]" : : "rZ" (val), "r" (addr)); +} + +static __always_inline u32 __raw_readl(const volatile void *addr) +{ + u32 val; + asm volatile("ldr %w0, [%1]" : "=r" (val) : "r" (addr)); + return val; +} + +#define writel_relaxed(v,c) ((void)__raw_writel((__force u32)cpu_to_le32(v),(c))) +#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; }) + +#define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c));}) +#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(__v); __v; }) #endif /* SELFTEST_KVM_PROCESSOR_H */ From patchwork Wed Aug 18 18:43:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12444991 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CFFA2C432BE for ; Wed, 18 Aug 2021 18:43:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AA62B61103 for ; Wed, 18 Aug 2021 18:43:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232785AbhHRSoD (ORCPT ); Wed, 18 Aug 2021 14:44:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53282 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232713AbhHRSn4 (ORCPT ); Wed, 18 Aug 2021 14:43:56 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C881FC061764 for ; Wed, 18 Aug 2021 11:43:21 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id 134-20020a63008c0000b029023286313a3cso1951665pga.4 for ; Wed, 18 Aug 2021 11:43:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=xPoIZjuWep0XnVjE3RZ+lF+QPEA9z7qXvcODMX5rYnc=; b=i9ROhHHLC7+9XVDXCedC9jm56keI2vlEBmvdJN8VFYKW+DoVJfmSia7ZbiPQwaV13S m//FjRqZlmB/Q0f4AgFaoRaX/xkqgrcfzh/dhrvnHOiri2x2oUE9qLfITAOgxBFD8N1E zWJR3aoeJ3Iq1mFLBeDwgc9cD5oRixUA5X8I/zM/bpb4/NNLJIHYswIuAXFLy4yBf23X aPGFRZ+8oe74OomG/nGQt6VI031c3kuPNtvJUqpXAwYjFgJ9sRUDijE39mW4TJNA1O9H WB5ZV2iG5E5YREdy1Pt98gbJ8L5AQpYTJNd1flPj/DpVGCfmvdZo/707zZfa+nkMezBs Lc6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=xPoIZjuWep0XnVjE3RZ+lF+QPEA9z7qXvcODMX5rYnc=; b=HsQsYDSiTFvIt+zJcxpt7GCvdhlVJ/Ix0WrN/XFYm3wg8m/g4GueM+8CSRRS68fWOg fZdAJgpqUVR3Hx39Zfvfo1SZfcfBEGqgck9+SmJ5sSDGKxEWgs7u+Qs+u2VEU07bXnnt 8SjG1+8XS0Y77fp3+wEtJQO7isI7f2NjnVLc1WKpbzXFB37gBVKTrJ+xbh/q5x8CKkHr LF2Mi0MiC2JkLkus+eGkYlOhaH3kHrgPdF94MKMj35SNt4NY7dGle6sL4K2DGnbZG6vA JgMzu9y9mon63gWoydTMWoAfesODl8er/prifviOvkNpJ/msmFQgeLxhM1fXqKzWh4B+ QbRQ== X-Gm-Message-State: AOAM532BNrQUqwF0cZKCMufGWlWhbdatn4OWv2RRi23Vh1DHRs+Ho62y NtErDS1G6RwDZSiLifzEeEhFllmzYZ6x X-Google-Smtp-Source: ABdhPJzx7O78WEN4MoFWpeiB6hWgg45bljg5ENDsoLX3FLeJ/Yl4YexADXJn8SvFup4tTD/118WwthhmvMgL X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:902:a503:b029:12b:2429:385e with SMTP id s3-20020a170902a503b029012b2429385emr8393704plq.64.1629312201293; Wed, 18 Aug 2021 11:43:21 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:03 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-3-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 02/10] KVM: arm64: selftests: Add write_sysreg_s and read_sysreg_s From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org For register names that are unsupported by the assembler or the ones without architectural names, add the macros write_sysreg_s and read_sysreg_s to support them. The functionality is derived from kvm-unit-tests and kernel's arch/arm64/include/asm/sysreg.h. Signed-off-by: Raghavendra Rao Ananta --- .../selftests/kvm/include/aarch64/processor.h | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h index 14f68bf55036..b4bbce837288 100644 --- a/tools/testing/selftests/kvm/include/aarch64/processor.h +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h @@ -115,6 +115,67 @@ void vm_install_exception_handler(struct kvm_vm *vm, void vm_install_sync_handler(struct kvm_vm *vm, int vector, int ec, handler_fn handler); +/* + * ARMv8 ARM reserves the following encoding for system registers: + * (Ref: ARMv8 ARM, Section: "System instruction class encoding overview", + * C5.2, version:ARM DDI 0487A.f) + * [20-19] : Op0 + * [18-16] : Op1 + * [15-12] : CRn + * [11-8] : CRm + * [7-5] : Op2 + */ +#define Op0_shift 19 +#define Op0_mask 0x3 +#define Op1_shift 16 +#define Op1_mask 0x7 +#define CRn_shift 12 +#define CRn_mask 0xf +#define CRm_shift 8 +#define CRm_mask 0xf +#define Op2_shift 5 +#define Op2_mask 0x7 + +/* + * When accessed from guests, the ARM64_SYS_REG() doesn't work since it + * generates a different encoding for additional KVM processing, and is + * only suitable for userspace to access the register via ioctls. + * Hence, define a 'pure' sys_reg() here to generate the encodings as per spec. + */ +#define sys_reg(op0, op1, crn, crm, op2) \ + (((op0) << Op0_shift) | ((op1) << Op1_shift) | \ + ((crn) << CRn_shift) | ((crm) << CRm_shift) | \ + ((op2) << Op2_shift)) + +asm( +" .irp num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30\n" +" .equ .L__reg_num_x\\num, \\num\n" +" .endr\n" +" .equ .L__reg_num_xzr, 31\n" +"\n" +" .macro mrs_s, rt, sreg\n" +" .inst 0xd5200000|(\\sreg)|(.L__reg_num_\\rt)\n" +" .endm\n" +"\n" +" .macro msr_s, sreg, rt\n" +" .inst 0xd5000000|(\\sreg)|(.L__reg_num_\\rt)\n" +" .endm\n" +); + +/* + * read_sysreg_s() and write_sysreg_s()'s 'reg' has to be encoded via sys_reg() + */ +#define read_sysreg_s(reg) ({ \ + u64 __val; \ + asm volatile("mrs_s %0, "__stringify(reg) : "=r" (__val)); \ + __val; \ +}) + +#define write_sysreg_s(reg, val) do { \ + u64 __val = (u64)val; \ + asm volatile("msr_s "__stringify(reg) ", %x0" : : "rZ" (__val));\ +} while (0) + #define write_sysreg(reg, val) \ ({ \ u64 __val = (u64)(val); \ From patchwork Wed Aug 18 18:43:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12444995 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5AAC7C432BE for ; Wed, 18 Aug 2021 18:43:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3A19C61103 for ; Wed, 18 Aug 2021 18:43:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232902AbhHRSoG (ORCPT ); Wed, 18 Aug 2021 14:44:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232808AbhHRSoC (ORCPT ); Wed, 18 Aug 2021 14:44:02 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 409CEC0613D9 for ; Wed, 18 Aug 2021 11:43:27 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id v130-20020a25c5880000b0290593c8c353ffso3858782ybe.7 for ; Wed, 18 Aug 2021 11:43:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=i0gC3YpOlYGFveSBqO/xZNra4rgAWDR79DWIZ6oDj6o=; b=c8xHVk4s6hSd+6Y9GryOeLTGVMmzfkiq1hv7+jFyRnpW6EH3IA6vmLaWc7VfrEEA9H BC5PDnWCLJQYD9/0Xt+U8dv1Hz1sD/0zc/41uJi38os0mU+Gy01KpPSwhnyRj/Gr1yBA GO0AuLPq9dgBbgik2aFUjbnvbKt/xem2y4uC8HTF6LEJ0/1IX9Us5a3LLtfBjdVOiMU+ YosbEo5C7+oG7IxmbUBFFHTDPskrCRAsnrhO2XGtZsFSmNugOGf3h4yFHVuLFyX+B8Vg THIDBL5JM6sHOxo6jAk1l1wrkOmBjDxa2oo74PYYstjOagpBtrnx3g4Gi7UHSKp9/9xe 4t4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=i0gC3YpOlYGFveSBqO/xZNra4rgAWDR79DWIZ6oDj6o=; b=JaJQBoDM68u3mGCn3YHKtAM2AcTcrMG9m3HjIY1dD5G/dFPN6gDow32ba/48e6VPbO B2z1PPoy0ML4G2FHI0yS/baW5hvUPfnjj0HLv+qAYu0xBUz487mgRElo5fUUSyHWlZJp qcAQvv3yphVuCAyXM/3Q4SjbtUk50qQuNN0f5MH8ZMshn8fQwVPs10tRycrHFe9qOrR/ d5pLT5DFgWpFox0i3tDpWfcMnErF5PvCiJACtOODPhLRZTXQX57MkTEwBaCRsCbUq7N6 qtfYvZlBcaVClnd+MAVSnOJ+Gsqa9K+39hIMoSpUkboaOsyLsgk8WAZawlBjbtnugJSs 81dQ== X-Gm-Message-State: AOAM533nPhayVCQwS97hSOTEPPbZJLQJKUJoSCjvz8TbwJyejogLajn5 PQML6w1CP1bgvKX0U8WbCfOWqJIlOlUs X-Google-Smtp-Source: ABdhPJwB6PS63y9NDjqeatAE1xaf+AJcpA2bji3PMSZ/4YD/r9FU49atLPRhaO9PZI8UBkHhanFmIb7u3Kje X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a25:f803:: with SMTP id u3mr12689796ybd.515.1629312203430; Wed, 18 Aug 2021 11:43:23 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:04 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-4-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 03/10] KVM: arm64: selftests: Add support for cpu_relax From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Implement the guest helper routine, cpu_relax(), to yield the processor to other tasks. The function was derived from arch/arm64/include/asm/vdso/processor.h. Signed-off-by: Raghavendra Rao Ananta --- tools/testing/selftests/kvm/include/aarch64/processor.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h index b4bbce837288..c83ff99282ed 100644 --- a/tools/testing/selftests/kvm/include/aarch64/processor.h +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h @@ -188,6 +188,11 @@ asm( val; \ }) +static inline void cpu_relax(void) +{ + asm volatile("yield" ::: "memory"); +} + #define isb() asm volatile("isb" : : : "memory") #define dsb(opt) asm volatile("dsb " #opt : : : "memory") #define dmb(opt) asm volatile("dmb " #opt : : : "memory") From patchwork Wed Aug 18 18:43:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12444993 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 498C2C4338F for ; Wed, 18 Aug 2021 18:43:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2A9BA61103 for ; Wed, 18 Aug 2021 18:43:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232834AbhHRSoF (ORCPT ); Wed, 18 Aug 2021 14:44:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232823AbhHRSoC (ORCPT ); Wed, 18 Aug 2021 14:44:02 -0400 Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 83C94C0613CF for ; Wed, 18 Aug 2021 11:43:26 -0700 (PDT) Received: by mail-qk1-x74a.google.com with SMTP id w2-20020a3794020000b02903b54f40b442so2462452qkd.0 for ; Wed, 18 Aug 2021 11:43:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=0Y0O8/jMTi8+MKBw8+SC9CkFDxQTH0x1K+F2lorBjNw=; b=U4fCLEUOOczPm8ogE1eilqE2IX/q5dZYpTUaPZ7In9Xogc9Is2YYJ4PdA5z5akOnRb zbnCmhl/HcZiIWVFvBIxyxxxWDZwfM/6rVRUQbVjmR0xu4pEvT0dEiDNpHqpVKRUlGSg PrFH48Vl3R6SocBK9oc3ILkAflN3crptqFzwjm4iUdBsl8VZ7NgJfjxxzHZLEhZ1oZIb jCtqNb38XKIM7qCfGQh1ZXTf+UqyRJY/NYgCWUu8I9lHeBt8/9iAkp5OIkPk6FaOfAwk cvm2eEiSk3GiQf/6uwc3lmoxtOIXSFNluzN0FdPD8706siUbSTwTmZb8Ww1BYCvnptzP pLzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=0Y0O8/jMTi8+MKBw8+SC9CkFDxQTH0x1K+F2lorBjNw=; b=lgFAJVXyOPCv1sjQaOy2SEtgrWb6T2Ve7T07MYjYBa/XcNQrI0ovbwRlXhSehiH8OS vhuiHGuvX6PORv1tDpdKueBd+RP72XPMpHUK2CXWQDEma/r4VXEoQRT818yDGxEnHN8P ITIaCl0h61oamGTZj6YjZwxUCPYLEbAtVVTG2FaIZDufdeUhcCoBK0TEZknDNFGeMD3l y4J2gT/YWL2mCGrofvabSG2f/FxbJBDVm7wV+32DepGe9ex34opMrPgy9PLZ5FiCBuYG 3rPAHvoodhhHHso6wOhOMWBMjU8scu/un1uuS7C3m8hJPCrpalwqq5c543itqBq/+OLe Sj/w== X-Gm-Message-State: AOAM532ep0Gulg/dBKKOo/HyKwfDqo2gq0zBpGyv9tbBXpQWJFts3rI6 5FOvj9WWDBMmpWK99SMJT5G1jl9lb/kg X-Google-Smtp-Source: ABdhPJzQWgpNp1Calgoj+b5RrQwbZcpvRpTehG5RJ6gjpdwYc8hrymlLG30VoJ0I1EDe0HQTY+K2VPCWx3ze X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a05:6214:d8a:: with SMTP id e10mr10482331qve.22.1629312205652; Wed, 18 Aug 2021 11:43:25 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:05 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-5-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 04/10] KVM: arm64: selftests: Add basic support for arch_timers From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a minimalistic library support to access the virtual timers, that can be used for simple timing functionalities, such as introducing delays in the guest. Signed-off-by: Raghavendra Rao Ananta --- .../kvm/include/aarch64/arch_timer.h | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 tools/testing/selftests/kvm/include/aarch64/arch_timer.h diff --git a/tools/testing/selftests/kvm/include/aarch64/arch_timer.h b/tools/testing/selftests/kvm/include/aarch64/arch_timer.h new file mode 100644 index 000000000000..9df5b63abc47 --- /dev/null +++ b/tools/testing/selftests/kvm/include/aarch64/arch_timer.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ARM Generic Timer specific interface + */ + +#ifndef SELFTEST_KVM_ARCH_TIMER_H +#define SELFTEST_KVM_ARCH_TIMER_H + +#include "processor.h" + +enum arch_timer { + VIRTUAL, + PHYSICAL, +}; + +#define CTL_ENABLE (1 << 0) +#define CTL_IMASK (1 << 1) +#define CTL_ISTATUS (1 << 2) + +#define msec_to_cycles(msec) \ + (timer_get_cntfrq() * (uint64_t)(msec) / 1000) + +#define usec_to_cycles(usec) \ + (timer_get_cntfrq() * (uint64_t)(usec) / 1000000) + +#define cycles_to_usec(cycles) \ + ((uint64_t)(cycles) * 1000000 / timer_get_cntfrq()) + +static inline uint32_t timer_get_cntfrq(void) +{ + return read_sysreg(cntfrq_el0); +} + +static inline uint64_t timer_get_cntct(enum arch_timer timer) +{ + isb(); + + switch (timer) { + case VIRTUAL: + return read_sysreg(cntvct_el0); + case PHYSICAL: + return read_sysreg(cntpct_el0); + default: + GUEST_ASSERT_1(0, timer); + } + + /* We should not reach here */ + return 0; +} + +static inline void timer_set_cval(enum arch_timer timer, uint64_t cval) +{ + switch (timer) { + case VIRTUAL: + write_sysreg(cntv_cval_el0, cval); + break; + case PHYSICAL: + write_sysreg(cntp_cval_el0, cval); + break; + default: + GUEST_ASSERT_1(0, timer); + } + + isb(); +} + +static inline uint64_t timer_get_cval(enum arch_timer timer) +{ + switch (timer) { + case VIRTUAL: + return read_sysreg(cntv_cval_el0); + case PHYSICAL: + return read_sysreg(cntp_cval_el0); + default: + GUEST_ASSERT_1(0, timer); + } + + /* We should not reach here */ + return 0; +} + +static inline void timer_set_tval(enum arch_timer timer, uint32_t tval) +{ + switch (timer) { + case VIRTUAL: + write_sysreg(cntv_tval_el0, tval); + break; + case PHYSICAL: + write_sysreg(cntp_tval_el0, tval); + break; + default: + GUEST_ASSERT_1(0, timer); + } + + isb(); +} + +static inline void timer_set_ctl(enum arch_timer timer, uint32_t ctl) +{ + switch (timer) { + case VIRTUAL: + write_sysreg(cntv_ctl_el0, ctl); + break; + case PHYSICAL: + write_sysreg(cntp_ctl_el0, ctl); + break; + default: + GUEST_ASSERT_1(0, timer); + } + + isb(); +} + +static inline uint32_t timer_get_ctl(enum arch_timer timer) +{ + switch (timer) { + case VIRTUAL: + return read_sysreg(cntv_ctl_el0); + case PHYSICAL: + return read_sysreg(cntp_ctl_el0); + default: + GUEST_ASSERT_1(0, timer); + } + + /* We should not reach here */ + return 0; +} + +static inline void timer_set_next_cval_ms(enum arch_timer timer, uint32_t msec) +{ + uint64_t now_ct = timer_get_cntct(timer); + uint64_t next_ct = now_ct + msec_to_cycles(msec); + + timer_set_cval(timer, next_ct); +} + +static inline void timer_set_next_tval_ms(enum arch_timer timer, uint32_t msec) +{ + timer_set_tval(timer, msec_to_cycles(msec)); +} + +#endif /* SELFTEST_KVM_ARCH_TIMER_H */ From patchwork Wed Aug 18 18:43:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12444997 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B095C4338F for ; Wed, 18 Aug 2021 18:43:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 03DD4610A5 for ; Wed, 18 Aug 2021 18:43:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232979AbhHRSoH (ORCPT ); Wed, 18 Aug 2021 14:44:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232584AbhHRSoD (ORCPT ); Wed, 18 Aug 2021 14:44:03 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 32297C061764 for ; Wed, 18 Aug 2021 11:43:28 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id 5-20020a170902ee45b029012d3a69c6c5so781543plo.7 for ; Wed, 18 Aug 2021 11:43:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=JcHymXf2ERbzAFxFFXQtQ/oPOCBg0VdgmGHaGoYCh8I=; b=XclqRPUA0/dOnnUxZ6e5xfFEGz1bzMNLZDMWFZSNFvSFo8M+XkqAR82qhWjdPE04Gd aXBogWWruyzy9kxHz03pmBGH/UtNF0W3hCs5Aaq4tpFylnvpbS77o1qVZhE6gSQuUQw4 mJkGlM8sPbtWCf+da7Jh+QMhfXB3oiO3IwX+9fwS1X7zzd6PquEQPLAul6Z6D2FsdeuH O1YzzLW8k2PHAi3uM/cXlCc5b8E7dTrTBvjTkL5DH6rkSScy+NHjgpTDduDeCEmNH+mF K/Okj9Ec+GiUjBFew8hgsuz9H4bIcWhcekTwVtjgiLg39+UVOacGwheMLt6SoqfOWwiK SluA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=JcHymXf2ERbzAFxFFXQtQ/oPOCBg0VdgmGHaGoYCh8I=; b=nkmdYRT/z2FzGgC1NpvaEff+Sz9QzLgR8/KyArEPodANV6cJo64ayZBWDMsX3yQDQJ dLlt+RbDNtZ7Udc/wg74DvxFn/eM5ISkz+OoAEpHorplJ+GShydOj/sQEEYYI2Y4+9iQ 1wtTR7GWKSDUo4SJ0ynsM+CqlJthkFeXThKJz98Yt7erogVOj+r2KA/DB4vKKW8EIYVU 8L++KPCcUnD3B9sgQgq9qAcqqDZomdUQuw6HZfDlqbTORPpz1L+U03upbRljTWrDeBG3 z7Kv9aGGPWeTDQ4Vt86TrdjcdonytHZ2pWcHhbBCrXiTKZH50oyMgXpwBCkp0l6D0+A2 lDRA== X-Gm-Message-State: AOAM533ZhWqxU/Pp6+2bHH/p40BDrdnWAbRkRN5iE71xY7gyKOKhnsws slosoe9kFgLGb3wt4J6rglQcDezpPDHW X-Google-Smtp-Source: ABdhPJxc2j/d30LFbliRbem66L7CuOMyzlZyrRGCesZ+JnC9QmoojdAvcyujHgWDyq8CQJl8cLQINmB345v+ X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:903:4055:b0:12e:ce88:e896 with SMTP id n21-20020a170903405500b0012ece88e896mr4978961pla.21.1629312207724; Wed, 18 Aug 2021 11:43:27 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:06 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-6-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 05/10] KVM: arm64: selftests: Add basic support to generate delays From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add udelay() support to generate a delay in the guest. The routines are derived and simplified from kernel's arch/arm64/lib/delay.c. Signed-off-by: Raghavendra Rao Ananta --- .../selftests/kvm/include/aarch64/delay.h | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tools/testing/selftests/kvm/include/aarch64/delay.h diff --git a/tools/testing/selftests/kvm/include/aarch64/delay.h b/tools/testing/selftests/kvm/include/aarch64/delay.h new file mode 100644 index 000000000000..329e4f5079ea --- /dev/null +++ b/tools/testing/selftests/kvm/include/aarch64/delay.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ARM simple delay routines + */ + +#ifndef SELFTEST_KVM_ARM_DELAY_H +#define SELFTEST_KVM_ARM_DELAY_H + +#include "arch_timer.h" + +static inline void __delay(uint64_t cycles) +{ + enum arch_timer timer = VIRTUAL; + uint64_t start = timer_get_cntct(timer); + + while ((timer_get_cntct(timer) - start) < cycles) + cpu_relax(); +} + +static inline void udelay(unsigned long usec) +{ + __delay(usec_to_cycles(usec)); +} + +#endif /* SELFTEST_KVM_ARM_DELAY_H */ From patchwork Wed Aug 18 18:43:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12445007 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1D7EC4338F for ; Wed, 18 Aug 2021 18:45:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9E8B2610FF for ; Wed, 18 Aug 2021 18:45:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233134AbhHRSoK (ORCPT ); Wed, 18 Aug 2021 14:44:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53322 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232854AbhHRSoF (ORCPT ); Wed, 18 Aug 2021 14:44:05 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 964E9C0613CF for ; Wed, 18 Aug 2021 11:43:30 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id t62-20020a625f410000b029032bc3dda599so1779001pfb.17 for ; Wed, 18 Aug 2021 11:43:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=hVS0vPea/E7ymOuCPsOem1y67EWYYT9eWBeHAHepsoY=; b=M4v7edVYyKBY+V84oWDNulNY+yx4Uze2wbZlUXRS2Aln9eqOffhXiBXP5DqvkJiSS6 ixVqUwuDxfj3hQwR3DyYk3Rg1Es+zp4/+Bndw5JEEMqIa2SqRk9ViwSiUkA2wFuFM5xB EDVY79ZV26X/y44fJVpZSzHM0O24OQkHsMiGP5NVaAgMOxCNwyzeNlaj98UnYeNLSiVV 3NPTU3nkl3+FXba1M7nb9zipmihuU6BPali7X4+fro6+nVTtq7oJkwx3jU0X53Bb+xsz zfnz4UOTYUCfp5iGx6vwnuOZu6kevvHSd+WSbDX4FYIDV6ERrruszwVx7V3PRnFU8XAO Dyug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=hVS0vPea/E7ymOuCPsOem1y67EWYYT9eWBeHAHepsoY=; b=l+OYHYrRGQKkKzjxlexyMfIsydsomCi+ot6mQf5Q1u/wDHBODE8KylXyLG+Qq1XOIm J1M2UfGYUApycFVoJ/AEhhcQBqHpSBdgJF7NCZc0eGpseiIBDoD0jjXjmBzzoo2RZrkh YLIAqjzwO8MxA1pmMeQfwZVUOToGEKmPu27GRY/bh6FWr9ZNwKxKVHxzjEH9G2qAlb/m myD2DbT8xKg8rPMqpjpYugEvTJ84BIEgWoDXO71jzi09OPl9wfJuRQwycAYfgeuvV8UK P99MykOAIoRV1JAwnBBw6PRfNBcVF11Ktt9wsn0USR7TcRnjPJlVqqD5wxrDimHklWkC SQIA== X-Gm-Message-State: AOAM530cUtOaj63mwfNLLKhx1DWeByfY0Ml5wemCYpyIOyh5mFUTj87E 8SI5hcAd4lzyzLA6InmK8eFoh2LUmRRu X-Google-Smtp-Source: ABdhPJwYcXARLYf9x4AaQrRYJ8sgbNkV+MLILfJmXoYMtcvFdw4v4vbdtvvWUMKaPFR8/UlVv8HOd2W4xggq X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:902:e850:b0:12d:91c6:1cd with SMTP id t16-20020a170902e85000b0012d91c601cdmr8429954plg.16.1629312210095; Wed, 18 Aug 2021 11:43:30 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:07 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-7-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 06/10] KVM: arm64: selftests: Add support to disable and enable local IRQs From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add functions local_irq_enable() and local_irq_disable() to enable and disable the IRQs from the guest, respectively. Signed-off-by: Raghavendra Rao Ananta --- .../testing/selftests/kvm/include/aarch64/processor.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h index c83ff99282ed..ae7a079ae180 100644 --- a/tools/testing/selftests/kvm/include/aarch64/processor.h +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h @@ -238,4 +238,14 @@ static __always_inline u32 __raw_readl(const volatile void *addr) #define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c));}) #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(__v); __v; }) +static inline void local_irq_enable(void) +{ + asm volatile("msr daifclr, #3" : : : "memory"); +} + +static inline void local_irq_disable(void) +{ + asm volatile("msr daifset, #3" : : : "memory"); +} + #endif /* SELFTEST_KVM_PROCESSOR_H */ From patchwork Wed Aug 18 18:43:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12444999 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3640BC4338F for ; Wed, 18 Aug 2021 18:43:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 18B8861101 for ; Wed, 18 Aug 2021 18:43:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232808AbhHRSoR (ORCPT ); Wed, 18 Aug 2021 14:44:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232823AbhHRSoI (ORCPT ); Wed, 18 Aug 2021 14:44:08 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E875C0613CF for ; Wed, 18 Aug 2021 11:43:33 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id e10-20020a17090301ca00b0012dd6a04c04so775410plh.10 for ; Wed, 18 Aug 2021 11:43:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=X215a34XlYY9pGUGC8FkhsQTh0Gsxzcj/XXjeeVpyoQ=; b=D8RHHn21WpX7lOwcIGclpa5kQE9RPrULMWoIr/pvS4NpZo0Om1eqeAlu1PRP1P1eUF IdyNGXYQlZoDhrnT3JirR7kCp1sfABUN3wP8ISx+/rHQNa/uaYACjvTkMJcse4rGqVlz XBnxDwirlSF4VOhIF/5nBLRWCCTw+r4O15fySStZfB+TkB7wprD5I4OlSun+ipBQweza scQJh4Nv3ll/qCJW/B2bso3VW59XorbpEscb4i/A0aKU5v/j81XzbvdWK1xd2FNCXBNU Hf5rPzbe/jNV39F4/ok6ZZoZoEzVv1ekZWY/46D5H2j638X6BySeNRbZJFoT54/mOoUr +TGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=X215a34XlYY9pGUGC8FkhsQTh0Gsxzcj/XXjeeVpyoQ=; b=O3KEHLasVozbaDx1CFSoVjPJD6iBBH+Fy+n4lbsCD5LNLy7eAyNZ+2nS8WA7mwI+Uw k0x8/NYT1DCtCrCvdh9Vm26fkBKGTpH2AR0+Rv4I03PvMz+SvaP512kjF8W0hanrcRSs WerJLd8rTlz1MCaAnsaiaxNGXNJOQ1Ag2t5F7eAfq7hoJXeUE6nI61Xc389p091SJ1Yj BnEC58ZGBL9Bz1YloR5JSm7piI0FszO4F1+p4am1H58pKTRfd2tz7dN8rcIRrvaYpAJN DFyUMpU1X5a/H6E0E/RFP3XCRweTte0G22BXfqNlA6awk+7GIzo77eUVk78nofxi4OSQ 5lRw== X-Gm-Message-State: AOAM530DERm1XBo2K/n5wMdqAaAHc2pWn+GhejCpUcpkteQkG1T6PAag AYhVdCYVOr+DXX4ZUYcD211lZRcns+q+ X-Google-Smtp-Source: ABdhPJxNdjQSpOttv8J6ZV+X+0iEAxdfgHwp5u0JVDm7jCBLggrHgvVi0/5rLv6kFjQEQdwhUcVWtBV59Aca X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:90a:43a7:: with SMTP id r36mr91749pjg.1.1629312212315; Wed, 18 Aug 2021 11:43:32 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:08 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-8-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 07/10] KVM: arm64: selftests: Add support to get the vcpuid from MPIDR_EL1 From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org At times, such as when in the interrupt handler, the guest wants to get the vCPU-id that it's running on. As a result, introduce get_vcpuid() that parses the MPIDR_EL1 and returns the vcpuid to the requested caller. Signed-off-by: Raghavendra Rao Ananta --- .../selftests/kvm/include/aarch64/processor.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h index ae7a079ae180..e9342e63d05d 100644 --- a/tools/testing/selftests/kvm/include/aarch64/processor.h +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h @@ -248,4 +248,23 @@ static inline void local_irq_disable(void) asm volatile("msr daifset, #3" : : : "memory"); } +#define MPIDR_LEVEL_BITS 8 +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level) +#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) +#define MPIDR_AFFINITY_LEVEL(mpidr, level) \ + ((mpidr >> MPIDR_LEVEL_SHIFT(level)) & MPIDR_LEVEL_MASK) + +static inline uint32_t get_vcpuid(void) +{ + uint32_t vcpuid = 0; + uint64_t mpidr = read_sysreg(mpidr_el1); + + /* KVM limits only 16 vCPUs at level 0 */ + vcpuid = mpidr & 0x0f; + vcpuid |= MPIDR_AFFINITY_LEVEL(mpidr, 1) << 4; + vcpuid |= MPIDR_AFFINITY_LEVEL(mpidr, 2) << 12; + + return vcpuid; +} + #endif /* SELFTEST_KVM_PROCESSOR_H */ From patchwork Wed Aug 18 18:43:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12445001 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B3EAC4338F for ; Wed, 18 Aug 2021 18:43:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4CF4861100 for ; Wed, 18 Aug 2021 18:43:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232932AbhHRSoS (ORCPT ); Wed, 18 Aug 2021 14:44:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233143AbhHRSoL (ORCPT ); Wed, 18 Aug 2021 14:44:11 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9155CC061764 for ; Wed, 18 Aug 2021 11:43:35 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id j21-20020a25d2150000b029057ac4b4e78fso3846283ybg.4 for ; Wed, 18 Aug 2021 11:43:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=wYh8smn48aXYYcSZU2IfL26LMTAImxlTzaqpMoQB+vI=; b=kzUtgAJSv2qNhZclEaU8FzKPyTqyxNgL+/U6RRB7b/NCQvhO63nxSBfOCqe12j8twA V8F00bR+TZr69FrMgpIK4CoQ8ff3s8YPi1NA8tAGh3pWBM06lyx8YqVDHz2q92fvYh5N y6wv2XfKViL8d/TWDzK/8sFitI87sqi/58D1pYUD28q6+DTljmvediyoPFKtwWW8RKjm 3pzeW/ksT/t5d7qHd4TPWHzFcTbuM7GglokZagJpfoL31QtWyWrNWJjaVzbJkJvr1bYZ +HxHwmee1VbX2GCtDvvr/xClS/kuLfWemGLXjahHSybYUj//STJlfyTym+shoKWSdV6G jsxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=wYh8smn48aXYYcSZU2IfL26LMTAImxlTzaqpMoQB+vI=; b=URKFglaCwWfmeEs+CdUGQb4GH1QoT5aJtfhT18ahVQ2CfILXunv+2tDDFjevIHVEVd VP4R+xnc8IDQjBpB3SimSjwUDHKsPWyo97OmcX8TOAenPod3SBgCeY5IKW8TCZo+NOz6 P0iSCe0NlWw/NfyWvpKy/m//r8FMvrcfUz/KPQmeJD0HoT5ooq/GwHZ2I4hrXWYr0wFW Axq+KRZptijc+taLsUaXkfrfuRtc2kond9hBEXxUkboQMPwk83WnQDvQIgl7FZi3gxMm 7AlksJVnX4lNEB9ISbFlcwcQNtD8WqjHcFNZvaTfPtyh980fDqtyZeh+SWMGefUKF1L8 Z8SA== X-Gm-Message-State: AOAM532ctaBDgEs9rIO73FVG8BRVBvG5gD53H7wiROzX+s5hIO06ldWt 0KMwGM0PBAL/ffpbA5htCv/p856BF+3k X-Google-Smtp-Source: ABdhPJxOmEaD7HVk4G/6lY+hgeTQktgQhg/NyAhOupYESQ8XGpcFBIq2fwUiPCq1kOf6U13VsKLCyVSfEXxd X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a25:4216:: with SMTP id p22mr12570656yba.397.1629312214825; Wed, 18 Aug 2021 11:43:34 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:09 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-9-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 08/10] KVM: arm64: selftests: Add light-weight spinlock support From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a simpler version of spinlock support for ARM64 for the guests to use. The implementation is loosely based on the spinlock implementation in kvm-unit-tests. Signed-off-by: Raghavendra Rao Ananta --- tools/testing/selftests/kvm/Makefile | 2 +- .../selftests/kvm/include/aarch64/spinlock.h | 13 +++++++++ .../selftests/kvm/lib/aarch64/spinlock.c | 27 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/kvm/include/aarch64/spinlock.h create mode 100644 tools/testing/selftests/kvm/lib/aarch64/spinlock.c diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 5832f510a16c..8f6d82b570bd 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -35,7 +35,7 @@ endif LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/rbtree.c lib/sparsebit.c lib/test_util.c lib/guest_modes.c lib/perf_test_util.c LIBKVM_x86_64 = lib/x86_64/apic.c lib/x86_64/processor.c lib/x86_64/vmx.c lib/x86_64/svm.c lib/x86_64/ucall.c lib/x86_64/handlers.S -LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c lib/aarch64/handlers.S +LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c lib/aarch64/handlers.S lib/aarch64/spinlock.c LIBKVM_s390x = lib/s390x/processor.c lib/s390x/ucall.c lib/s390x/diag318_test_handler.c TEST_GEN_PROGS_x86_64 = x86_64/cr4_cpuid_sync_test diff --git a/tools/testing/selftests/kvm/include/aarch64/spinlock.h b/tools/testing/selftests/kvm/include/aarch64/spinlock.h new file mode 100644 index 000000000000..cf0984106d14 --- /dev/null +++ b/tools/testing/selftests/kvm/include/aarch64/spinlock.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef SELFTEST_KVM_ARM64_SPINLOCK_H +#define SELFTEST_KVM_ARM64_SPINLOCK_H + +struct spinlock { + int v; +}; + +extern void spin_lock(struct spinlock *lock); +extern void spin_unlock(struct spinlock *lock); + +#endif /* SELFTEST_KVM_ARM64_SPINLOCK_H */ diff --git a/tools/testing/selftests/kvm/lib/aarch64/spinlock.c b/tools/testing/selftests/kvm/lib/aarch64/spinlock.c new file mode 100644 index 000000000000..6d66a3dac237 --- /dev/null +++ b/tools/testing/selftests/kvm/lib/aarch64/spinlock.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ARM64 Spinlock support + */ +#include + +#include "spinlock.h" + +void spin_lock(struct spinlock *lock) +{ + uint32_t val, res; + + asm volatile( + "1: ldaxr %w0, [%2]\n" + " cbnz %w0, 1b\n" + " mov %w0, #1\n" + " stxr %w1, %w0, [%2]\n" + " cbnz %w1, 1b\n" + : "=&r" (val), "=&r" (res) + : "r" (&lock->v) + : "memory"); +} + +void spin_unlock(struct spinlock *lock) +{ + asm volatile("stlr wzr, [%0]\n" : : "r" (&lock->v) : "memory"); +} From patchwork Wed Aug 18 18:43:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12445003 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10D4BC432BE for ; Wed, 18 Aug 2021 18:43:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EE15161101 for ; Wed, 18 Aug 2021 18:43:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233042AbhHRSoU (ORCPT ); Wed, 18 Aug 2021 14:44:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233480AbhHRSoO (ORCPT ); Wed, 18 Aug 2021 14:44:14 -0400 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 34C35C0617AD for ; Wed, 18 Aug 2021 11:43:38 -0700 (PDT) Received: by mail-qt1-x84a.google.com with SMTP id t35-20020a05622a1823b02902647b518455so1397421qtc.3 for ; Wed, 18 Aug 2021 11:43:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=20nnTTofiyqiR0MYfZASFsaMi6XXnagQj9CoOJhUpDE=; b=ot2STW0sudtcs8PUHCkEJsxh0cITVPIgey+K7au4a3itjWKzocULiccv+dEpc5F3uq E8+j+MtCeKvfk5fUU/2nnKeK6rINx3Rc0ViIQAxc61FxeFLZkgkxDxPKJX9xdk81+RrW dQb9lJE5JiYthxslxIybXqved0Y/lr1b+VKwFHc/MTt1w4UNyXk18ofL7Ad5kCYHhJak 56cM90xV7R1RREqfzzTJBPpkDjm39uSMtKoaSBUsbh8jVZwetmEnaYBQ6TIMujxzKbHt 5M+ItI8i85N/SU9JAzaJ5MCWNtN+PEFvH+dIU5CkKBkgmmosjzP9QBTiFBPt7JqfOvH1 DjrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=20nnTTofiyqiR0MYfZASFsaMi6XXnagQj9CoOJhUpDE=; b=twjgGSrdIRTtYknKSnP1scsUINRb4z9zOvxHMxttS8oUv/5awikvx5Em5tlr7k3b+H XUDidua+iHpo3KEgNYyIyXPKz6cx+iRL+Bh+1SsfARTlnANAdWhdwAPoNh1DblqYFgoB o6h/RMkwIGEKRaaYKYAzlVhYmv6RJgp9OsVEt08FDBupFzlTH6iOGeKr4EhoMdzGR9YB lLdACArkfOkK3pZAHCAPLg6qL83PZgejYPrwCXjJBsedDlXxqJL5bmRhCVXphHn4HiiN 1sI/CsORkezezlpKKIqobRP3oS3tOhysn9g/rvR72d27V6EC+JxW0eI9tNs7QINYIhCf GAPw== X-Gm-Message-State: AOAM531Kklzaw2DYFR7cAn7VVWhfp/Vy6YcNIJRPfYsKNje9weWl87ug jNvQSaTxVeu+AaimsN56dZTSZp6lXZV8 X-Google-Smtp-Source: ABdhPJzINnAuQbwAjq+jpcsZYiF2S8hB/WDNgLVZwsHIuE00vHxFz5sVWHtqeWdkt+Nir/z3GC+2yk2USZFD X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a05:6214:144e:: with SMTP id b14mr10579282qvy.8.1629312217293; Wed, 18 Aug 2021 11:43:37 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:10 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-10-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 09/10] KVM: arm64: selftests: Add basic GICv3 support From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add basic support for ARM Generic Interrupt Controller v3. The support provides guests to setup interrupts. The work is inspired from kvm-unit-tests and the kernel's GIC driver (drivers/irqchip/irq-gic-v3.c). Signed-off-by: Raghavendra Rao Ananta --- tools/testing/selftests/kvm/Makefile | 2 +- .../selftests/kvm/include/aarch64/gic.h | 21 ++ tools/testing/selftests/kvm/lib/aarch64/gic.c | 93 +++++++ .../selftests/kvm/lib/aarch64/gic_private.h | 21 ++ .../selftests/kvm/lib/aarch64/gic_v3.c | 240 ++++++++++++++++++ .../selftests/kvm/lib/aarch64/gic_v3.h | 70 +++++ 6 files changed, 446 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/kvm/include/aarch64/gic.h create mode 100644 tools/testing/selftests/kvm/lib/aarch64/gic.c create mode 100644 tools/testing/selftests/kvm/lib/aarch64/gic_private.h create mode 100644 tools/testing/selftests/kvm/lib/aarch64/gic_v3.c create mode 100644 tools/testing/selftests/kvm/lib/aarch64/gic_v3.h diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 8f6d82b570bd..a170166334a3 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -35,7 +35,7 @@ endif LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/rbtree.c lib/sparsebit.c lib/test_util.c lib/guest_modes.c lib/perf_test_util.c LIBKVM_x86_64 = lib/x86_64/apic.c lib/x86_64/processor.c lib/x86_64/vmx.c lib/x86_64/svm.c lib/x86_64/ucall.c lib/x86_64/handlers.S -LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c lib/aarch64/handlers.S lib/aarch64/spinlock.c +LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c lib/aarch64/handlers.S lib/aarch64/spinlock.c lib/aarch64/gic.c lib/aarch64/gic_v3.c LIBKVM_s390x = lib/s390x/processor.c lib/s390x/ucall.c lib/s390x/diag318_test_handler.c TEST_GEN_PROGS_x86_64 = x86_64/cr4_cpuid_sync_test diff --git a/tools/testing/selftests/kvm/include/aarch64/gic.h b/tools/testing/selftests/kvm/include/aarch64/gic.h new file mode 100644 index 000000000000..85dd1e53048e --- /dev/null +++ b/tools/testing/selftests/kvm/include/aarch64/gic.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ARM Generic Interrupt Controller (GIC) specific defines + */ + +#ifndef SELFTEST_KVM_GIC_H +#define SELFTEST_KVM_GIC_H + +enum gic_type { + GIC_V3, + GIC_TYPE_MAX, +}; + +void gic_init(enum gic_type type, unsigned int nr_cpus, + void *dist_base, void *redist_base); +void gic_irq_enable(unsigned int intid); +void gic_irq_disable(unsigned int intid); +unsigned int gic_get_and_ack_irq(void); +void gic_set_eoi(unsigned int intid); + +#endif /* SELFTEST_KVM_GIC_H */ diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic.c b/tools/testing/selftests/kvm/lib/aarch64/gic.c new file mode 100644 index 000000000000..b0b67f5aeaa6 --- /dev/null +++ b/tools/testing/selftests/kvm/lib/aarch64/gic.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ARM Generic Interrupt Controller (GIC) support + */ + +#include +#include +#include + +#include "kvm_util.h" + +#include +#include "gic_private.h" +#include "processor.h" +#include "spinlock.h" + +static const struct gic_common_ops *gic_common_ops; +static struct spinlock gic_lock; + +static void gic_cpu_init(unsigned int cpu, void *redist_base) +{ + gic_common_ops->gic_cpu_init(cpu, redist_base); +} + +static void +gic_dist_init(enum gic_type type, unsigned int nr_cpus, void *dist_base) +{ + const struct gic_common_ops *gic_ops; + + spin_lock(&gic_lock); + + /* Distributor initialization is needed only once per VM */ + if (gic_common_ops) { + spin_unlock(&gic_lock); + return; + } + + if (type == GIC_V3) + gic_ops = &gicv3_ops; + + gic_ops->gic_init(nr_cpus, dist_base); + gic_common_ops = gic_ops; + + /* Make sure that the initialized data is visible to all the vCPUs */ + dsb(sy); + + spin_unlock(&gic_lock); +} + +void gic_init(enum gic_type type, unsigned int nr_cpus, + void *dist_base, void *redist_base) +{ + uint32_t cpu = get_vcpuid(); + + GUEST_ASSERT(type < GIC_TYPE_MAX); + GUEST_ASSERT(dist_base); + GUEST_ASSERT(redist_base); + GUEST_ASSERT(nr_cpus); + + gic_dist_init(type, nr_cpus, dist_base); + gic_cpu_init(cpu, redist_base); +} + +void gic_irq_enable(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_irq_enable(intid); +} + +void gic_irq_disable(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_irq_disable(intid); +} + +unsigned int gic_get_and_ack_irq(void) +{ + uint64_t irqstat; + unsigned int intid; + + GUEST_ASSERT(gic_common_ops); + + irqstat = gic_common_ops->gic_read_iar(); + intid = irqstat & GENMASK(23, 0); + + return intid; +} + +void gic_set_eoi(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_write_eoir(intid); +} diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_private.h b/tools/testing/selftests/kvm/lib/aarch64/gic_private.h new file mode 100644 index 000000000000..d81d739433dc --- /dev/null +++ b/tools/testing/selftests/kvm/lib/aarch64/gic_private.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ARM Generic Interrupt Controller (GIC) private defines that's only + * shared among the GIC library code. + */ + +#ifndef SELFTEST_KVM_GIC_PRIVATE_H +#define SELFTEST_KVM_GIC_PRIVATE_H + +struct gic_common_ops { + void (*gic_init)(unsigned int nr_cpus, void *dist_base); + void (*gic_cpu_init)(unsigned int cpu, void *redist_base); + void (*gic_irq_enable)(unsigned int intid); + void (*gic_irq_disable)(unsigned int intid); + uint64_t (*gic_read_iar)(void); + void (*gic_write_eoir)(uint32_t irq); +}; + +extern const struct gic_common_ops gicv3_ops; + +#endif /* SELFTEST_KVM_GIC_PRIVATE_H */ diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c new file mode 100644 index 000000000000..4b635ca6a8cb --- /dev/null +++ b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ARM Generic Interrupt Controller (GIC) v3 support + */ + +#include + +#include "kvm_util.h" +#include "processor.h" +#include "delay.h" + +#include "gic_v3.h" +#include "gic_private.h" + +struct gicv3_data { + void *dist_base; + void *redist_base[GICV3_MAX_CPUS]; + unsigned int nr_cpus; + unsigned int nr_spis; +}; + +#define sgi_base_from_redist(redist_base) (redist_base + SZ_64K) + +enum gicv3_intid_range { + SGI_RANGE, + PPI_RANGE, + SPI_RANGE, + INVALID_RANGE, +}; + +static struct gicv3_data gicv3_data; + +static void gicv3_gicd_wait_for_rwp(void) +{ + unsigned int count = 100000; /* 1s */ + + while (readl(gicv3_data.dist_base + GICD_CTLR) & GICD_CTLR_RWP) { + GUEST_ASSERT(count--); + udelay(10); + } +} + +static void gicv3_gicr_wait_for_rwp(void *redist_base) +{ + unsigned int count = 100000; /* 1s */ + + while (readl(redist_base + GICR_CTLR) & GICR_CTLR_RWP) { + GUEST_ASSERT(count--); + udelay(10); + } +} + +static enum gicv3_intid_range get_intid_range(unsigned int intid) +{ + switch (intid) { + case 0 ... 15: + return SGI_RANGE; + case 16 ... 31: + return PPI_RANGE; + case 32 ... 1019: + return SPI_RANGE; + } + + /* We should not be reaching here */ + GUEST_ASSERT(0); + + return INVALID_RANGE; +} + +static uint64_t gicv3_read_iar(void) +{ + uint64_t irqstat = read_sysreg_s(SYS_ICC_IAR1_EL1); + + dsb(sy); + return irqstat; +} + +static void gicv3_write_eoir(uint32_t irq) +{ + write_sysreg_s(SYS_ICC_EOIR1_EL1, irq); + isb(); +} + +static void +gicv3_config_irq(unsigned int intid, unsigned int offset) +{ + uint32_t cpu = get_vcpuid(); + uint32_t mask = 1 << (intid % 32); + enum gicv3_intid_range intid_range = get_intid_range(intid); + void *reg; + + /* We care about 'cpu' only for SGIs or PPIs */ + if (intid_range == SGI_RANGE || intid_range == PPI_RANGE) { + GUEST_ASSERT(cpu < gicv3_data.nr_cpus); + + reg = sgi_base_from_redist(gicv3_data.redist_base[cpu]) + + offset; + writel(mask, reg); + gicv3_gicr_wait_for_rwp(gicv3_data.redist_base[cpu]); + } else if (intid_range == SPI_RANGE) { + reg = gicv3_data.dist_base + offset + (intid / 32) * 4; + writel(mask, reg); + gicv3_gicd_wait_for_rwp(); + } else { + GUEST_ASSERT(0); + } +} + +static void gicv3_irq_enable(unsigned int intid) +{ + gicv3_config_irq(intid, GICD_ISENABLER); +} + +static void gicv3_irq_disable(unsigned int intid) +{ + gicv3_config_irq(intid, GICD_ICENABLER); +} + +static void gicv3_enable_redist(void *redist_base) +{ + uint32_t val = readl(redist_base + GICR_WAKER); + unsigned int count = 100000; /* 1s */ + + val &= ~GICR_WAKER_ProcessorSleep; + writel(val, redist_base + GICR_WAKER); + + /* Wait until the processor is 'active' */ + while (readl(redist_base + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) { + GUEST_ASSERT(count--); + udelay(10); + } +} + +static inline void *gicr_base_gpa_cpu(void *redist_base, uint32_t cpu) +{ + /* Align all the redistributors sequentially */ + return redist_base + cpu * SZ_64K * 2; +} + +static void gicv3_cpu_init(unsigned int cpu, void *redist_base) +{ + void *sgi_base; + unsigned int i; + void *redist_base_cpu; + + GUEST_ASSERT(cpu < gicv3_data.nr_cpus); + + redist_base_cpu = gicr_base_gpa_cpu(redist_base, cpu); + sgi_base = sgi_base_from_redist(redist_base_cpu); + + gicv3_enable_redist(redist_base_cpu); + + /* + * Mark all the SGI and PPI interrupts as non-secure Group-1. + * Also, deactivate and disable them. + */ + writel(~0, sgi_base + GICR_IGROUPR0); + writel(~0, sgi_base + GICR_ICACTIVER0); + writel(~0, sgi_base + GICR_ICENABLER0); + + /* Set a default priority for all the SGIs and PPIs */ + for (i = 0; i < 32; i += 4) + writel(GICD_INT_DEF_PRI_X4, + sgi_base + GICR_IPRIORITYR0 + i); + + gicv3_gicr_wait_for_rwp(redist_base_cpu); + + /* Enable the GIC system register (ICC_*) access */ + write_sysreg_s(SYS_ICC_SRE_EL1, + read_sysreg_s(SYS_ICC_SRE_EL1) | ICC_SRE_EL1_SRE); + + /* Set a default priority threshold */ + write_sysreg_s(SYS_ICC_PMR_EL1, ICC_PMR_DEF_PRIO); + + /* Enable non-secure Group-1 interrupts */ + write_sysreg_s(SYS_ICC_GRPEN1_EL1, ICC_IGRPEN1_EL1_ENABLE); + + gicv3_data.redist_base[cpu] = redist_base_cpu; +} + +static void gicv3_dist_init(void) +{ + void *dist_base = gicv3_data.dist_base; + unsigned int i; + + /* Disable the distributor until we set things up */ + writel(0, dist_base + GICD_CTLR); + gicv3_gicd_wait_for_rwp(); + + /* + * Mark all the SPI interrupts as non-secure Group-1. + * Also, deactivate and disable them. + */ + for (i = 32; i < gicv3_data.nr_spis; i += 32) { + writel(~0, dist_base + GICD_IGROUPR + i / 8); + writel(~0, dist_base + GICD_ICACTIVER + i / 8); + writel(~0, dist_base + GICD_ICENABLER + i / 8); + } + + /* Set a default priority for all the SPIs */ + for (i = 32; i < gicv3_data.nr_spis; i += 4) + writel(GICD_INT_DEF_PRI_X4, + dist_base + GICD_IPRIORITYR + i); + + /* Wait for the settings to sync-in */ + gicv3_gicd_wait_for_rwp(); + + /* Finally, enable the distributor globally with ARE */ + writel(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | + GICD_CTLR_ENABLE_G1, dist_base + GICD_CTLR); + gicv3_gicd_wait_for_rwp(); +} + +static void gicv3_init(unsigned int nr_cpus, void *dist_base) +{ + GUEST_ASSERT(nr_cpus <= GICV3_MAX_CPUS); + + gicv3_data.nr_cpus = nr_cpus; + gicv3_data.dist_base = dist_base; + gicv3_data.nr_spis = GICD_TYPER_SPIS( + readl(gicv3_data.dist_base + GICD_TYPER)); + if (gicv3_data.nr_spis > 1020) + gicv3_data.nr_spis = 1020; + + /* + * Initialize only the distributor for now. + * The redistributor and CPU interfaces are initialized + * later for every PE. + */ + gicv3_dist_init(); +} + +const struct gic_common_ops gicv3_ops = { + .gic_init = gicv3_init, + .gic_cpu_init = gicv3_cpu_init, + .gic_irq_enable = gicv3_irq_enable, + .gic_irq_disable = gicv3_irq_disable, + .gic_read_iar = gicv3_read_iar, + .gic_write_eoir = gicv3_write_eoir, +}; diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.h b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.h new file mode 100644 index 000000000000..d41195e347b3 --- /dev/null +++ b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ARM Generic Interrupt Controller (GIC) v3 specific defines + */ + +#ifndef SELFTEST_KVM_GICV3_H +#define SELFTEST_KVM_GICV3_H + +#include "processor.h" + +/* + * Distributor registers + */ +#define GICD_CTLR 0x0000 +#define GICD_TYPER 0x0004 +#define GICD_IGROUPR 0x0080 +#define GICD_ISENABLER 0x0100 +#define GICD_ICENABLER 0x0180 +#define GICD_ICACTIVER 0x0380 +#define GICD_IPRIORITYR 0x0400 + +/* + * The assumption is that the guest runs in a non-secure mode. + * The following bits of GICD_CTLR are defined accordingly. + */ +#define GICD_CTLR_RWP (1U << 31) +#define GICD_CTLR_nASSGIreq (1U << 8) +#define GICD_CTLR_ARE_NS (1U << 4) +#define GICD_CTLR_ENABLE_G1A (1U << 1) +#define GICD_CTLR_ENABLE_G1 (1U << 0) + +#define GICD_TYPER_SPIS(typer) ((((typer) & 0x1f) + 1) * 32) +#define GICD_INT_DEF_PRI_X4 0xa0a0a0a0 + +/* + * Redistributor registers + */ +#define GICR_CTLR 0x000 +#define GICR_WAKER 0x014 + +#define GICR_CTLR_RWP (1U << 3) + +#define GICR_WAKER_ProcessorSleep (1U << 1) +#define GICR_WAKER_ChildrenAsleep (1U << 2) + +/* + * Redistributor registers, offsets from SGI base + */ +#define GICR_IGROUPR0 GICD_IGROUPR +#define GICR_ISENABLER0 GICD_ISENABLER +#define GICR_ICENABLER0 GICD_ICENABLER +#define GICR_ICACTIVER0 GICD_ICACTIVER +#define GICR_IPRIORITYR0 GICD_IPRIORITYR + +/* CPU interface registers */ +#define SYS_ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0) +#define SYS_ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0) +#define SYS_ICC_EOIR1_EL1 sys_reg(3, 0, 12, 12, 1) +#define SYS_ICC_SRE_EL1 sys_reg(3, 0, 12, 12, 5) +#define SYS_ICC_GRPEN1_EL1 sys_reg(3, 0, 12, 12, 7) + +#define ICC_PMR_DEF_PRIO 0xf0 + +#define ICC_SRE_EL1_SRE (1U << 0) + +#define ICC_IGRPEN1_EL1_ENABLE (1U << 0) + +#define GICV3_MAX_CPUS 512 + +#endif /* SELFTEST_KVM_GICV3_H */ From patchwork Wed Aug 18 18:43:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12445005 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50D5AC4320E for ; Wed, 18 Aug 2021 18:43:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 38B67610FD for ; Wed, 18 Aug 2021 18:43:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232995AbhHRSoV (ORCPT ); Wed, 18 Aug 2021 14:44:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233634AbhHRSoQ (ORCPT ); Wed, 18 Aug 2021 14:44:16 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 192C8C0613D9 for ; Wed, 18 Aug 2021 11:43:41 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id w201-20020a25dfd2000000b00594695384d1so3858696ybg.20 for ; Wed, 18 Aug 2021 11:43:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=G8SpNklEDZWajysk0gZLosfORko9hc4kc79cXySk3Ng=; b=DOdPQ+arjkg0yL/BVTPhU92JuBmGp8sQlMbYnDn3EYlUGWX9y06YzbkJ42UydtcVUe SVCnO1qu+yvdQuPYmfMuPusBAERjhsCDkyhOrLLSxrgLGz7fMeIVrSq2rfw/9H08VcI9 JeWc+jePCoHb6N2wGXgeK/NsejW4L9EVNFi+ZHcthvah0/rMWqo70mxTqZegwwaR1P0G 1netz8VEvSx+5RlOJBKmHj4AypGsZ1AtYPRudGsQZauv4F/kgevSxnVx0BOIOTU3HnyZ 8w9amOv5zrFArfD8KLGFeU8qxnV0Tx0cIGrOSAgsjhQzVk2mtKk5DVpDPVAmLd2eQsO5 PdCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=G8SpNklEDZWajysk0gZLosfORko9hc4kc79cXySk3Ng=; b=Ljjpfpgm0oQMKxlVhx5tzN9jtVfdnNp9eZswsvqzvf6qmEv1gH3Zp3bw+E4FcXkqRh U8sTU+QTqN43PN3yg2oJX6Xw0JGf7L8XE5QiWHDhLAuf2QHho5PO44Cfd1NE3J2hB1gO 85RTEEK9+nCedOHqeJqhS0k/hgC6+zJWaptkE42aQkyEmZUrukoqGMefYVTyMfdflJtj eHZR9rDJRcODAPhbxNCWpHID5fJRk+KnT6bbYU3t4Fwq7VX/rfgC04LdVP53qdUruSlH eg46QD7IGyK2Yp6sHMP8/bVnLCA70H4uV4aTnPGF/vUmzTXBCgbqAduhgJFVGCAKc6+Q VCFw== X-Gm-Message-State: AOAM532FN/ZThumgYQTKIIh8sCS1YeJtg+1FZBcFUdTJ5GuXwPsvSBWe WBi2wvF/qkzeyDubQpTbmpxvRI3t9eJ/ X-Google-Smtp-Source: ABdhPJwZV+LwEfOaAWwFg94Of0SNVcHgMFmTDMtQOu1IeXOkWChi5BnQ8ElP/B61qxPyVKjr8AwfhPB7JQwN X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a25:e747:: with SMTP id e68mr12849876ybh.364.1629312220248; Wed, 18 Aug 2021 11:43:40 -0700 (PDT) Date: Wed, 18 Aug 2021 18:43:11 +0000 In-Reply-To: <20210818184311.517295-1-rananta@google.com> Message-Id: <20210818184311.517295-11-rananta@google.com> Mime-Version: 1.0 References: <20210818184311.517295-1-rananta@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v2 10/10] KVM: arm64: selftests: Add arch_timer test From: Raghavendra Rao Ananta To: Paolo Bonzini , Marc Zyngier Cc: Alexandru Elisei , Suzuki K Poulose , James Morse , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a KVM selftest to validate the arch_timer functionality. Primarily, the test sets up periodic timer interrupts and validates the basic architectural expectations upon its receipt. The test provides command-line options to configure the period of the timer, number of iterations, and number of vCPUs. Signed-off-by: Raghavendra Rao Ananta --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/aarch64/arch_timer.c | 382 ++++++++++++++++++ 3 files changed, 384 insertions(+) create mode 100644 tools/testing/selftests/kvm/aarch64/arch_timer.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index 0709af0144c8..5f6cf0c76cf8 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +/aarch64/arch_timer /aarch64/debug-exceptions /aarch64/get-reg-list /aarch64/vgic_init diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index a170166334a3..62a2c3e4b50c 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -84,6 +84,7 @@ TEST_GEN_PROGS_x86_64 += set_memory_region_test TEST_GEN_PROGS_x86_64 += steal_time TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test +TEST_GEN_PROGS_aarch64 += aarch64/arch_timer TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list TEST_GEN_PROGS_aarch64 += aarch64/vgic_init diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c new file mode 100644 index 000000000000..88333fe1e567 --- /dev/null +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * arch_timer.c - Tests the aarch64 timer IRQ functionality + * + * The test validates both the virtual and physical timer IRQs using + * CVAL and TVAL registers. This consitutes the four stages in the test. + * The guest's main thread configures the timer interrupt for a stage + * and waits for it to fire, with a timeout equal to the timer period. + * It asserts that the timeout doesn't exceed the timer period. + * + * On the other hand, upon receipt of an interrupt, the guest's interrupt + * handler validates the interrupt by checking if the architectural state + * is in compliance with the specifications. + * + * The test provides command-line options to configure the timer's + * period (-p), number of vCPUs (-n), and iterations per stage (-i). + * + * Copyright (c) 2021, Google LLC. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include + +#include "kvm_util.h" +#include "processor.h" +#include "delay.h" +#include "arch_timer.h" +#include "gic.h" + +#define NR_VCPUS_DEF 4 +#define NR_TEST_ITERS_DEF 5 +#define TIMER_TEST_PERIOD_MS_DEF 10 +#define TIMER_TEST_ERR_MARGIN_US 100 + +struct test_args { + int nr_vcpus; + int nr_iter; + int timer_period_ms; +}; + +static struct test_args test_args = { + .nr_vcpus = NR_VCPUS_DEF, + .nr_iter = NR_TEST_ITERS_DEF, + .timer_period_ms = TIMER_TEST_PERIOD_MS_DEF, +}; + +#define msecs_to_usecs(msec) ((msec) * 1000LL) + +#define VTIMER_IRQ 27 +#define PTIMER_IRQ 30 + +#define REDIST_REGION_ATTR_ADDR(count, base, flags, index) \ + (((uint64_t)(count) << 52) | \ + ((uint64_t)((base) >> 16) << 16) | \ + ((uint64_t)(flags) << 12) | \ + index) + +#define GICD_BASE_GPA 0x8000000ULL +#define GICR_BASE_GPA 0x80A0000ULL + +enum guest_stage { + GUEST_STAGE_VTIMER_CVAL = 1, + GUEST_STAGE_VTIMER_TVAL, + GUEST_STAGE_PTIMER_CVAL, + GUEST_STAGE_PTIMER_TVAL, + GUEST_STAGE_MAX, +}; + +/* Sahred variables between host and guest */ +struct test_vcpu_shared_data { + int nr_iter; + enum guest_stage guest_stage; + uint64_t xcnt; +}; + +struct test_vcpu { + uint32_t vcpuid; + pthread_t pt_vcpu_run; + struct kvm_vm *vm; +}; + +static struct test_vcpu test_vcpu[KVM_MAX_VCPUS]; +static struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS]; + +static void +guest_configure_timer_action(struct test_vcpu_shared_data *shared_data) +{ + switch (shared_data->guest_stage) { + case GUEST_STAGE_VTIMER_CVAL: + timer_set_next_cval_ms(VIRTUAL, test_args.timer_period_ms); + shared_data->xcnt = timer_get_cntct(VIRTUAL); + timer_set_ctl(VIRTUAL, CTL_ENABLE); + break; + case GUEST_STAGE_VTIMER_TVAL: + timer_set_next_tval_ms(VIRTUAL, test_args.timer_period_ms); + shared_data->xcnt = timer_get_cntct(VIRTUAL); + timer_set_ctl(VIRTUAL, CTL_ENABLE); + break; + case GUEST_STAGE_PTIMER_CVAL: + timer_set_next_cval_ms(PHYSICAL, test_args.timer_period_ms); + shared_data->xcnt = timer_get_cntct(PHYSICAL); + timer_set_ctl(PHYSICAL, CTL_ENABLE); + break; + case GUEST_STAGE_PTIMER_TVAL: + timer_set_next_tval_ms(PHYSICAL, test_args.timer_period_ms); + shared_data->xcnt = timer_get_cntct(PHYSICAL); + timer_set_ctl(PHYSICAL, CTL_ENABLE); + break; + default: + GUEST_ASSERT(0); + } +} + +static void guest_validate_irq(unsigned int intid, + struct test_vcpu_shared_data *shared_data) +{ + enum guest_stage stage = shared_data->guest_stage; + uint64_t xcnt = 0, xcnt_diff_us, cval = 0; + unsigned long xctl = 0; + unsigned int timer_irq = 0; + + if (stage == GUEST_STAGE_VTIMER_CVAL || + stage == GUEST_STAGE_VTIMER_TVAL) { + xctl = timer_get_ctl(VIRTUAL); + timer_set_ctl(VIRTUAL, CTL_IMASK); + xcnt = timer_get_cntct(VIRTUAL); + cval = timer_get_cval(VIRTUAL); + timer_irq = VTIMER_IRQ; + } else if (stage == GUEST_STAGE_PTIMER_CVAL || + stage == GUEST_STAGE_PTIMER_TVAL) { + xctl = timer_get_ctl(PHYSICAL); + timer_set_ctl(PHYSICAL, CTL_IMASK); + xcnt = timer_get_cntct(PHYSICAL); + cval = timer_get_cval(PHYSICAL); + timer_irq = PTIMER_IRQ; + } else { + GUEST_ASSERT(0); + } + + xcnt_diff_us = cycles_to_usec(xcnt - shared_data->xcnt); + + /* Make sure we are dealing with the correct timer IRQ */ + GUEST_ASSERT_2(intid == timer_irq, intid, timer_irq); + + /* Basic 'timer codition met' check */ + GUEST_ASSERT_3(xcnt >= cval, xcnt, cval, xcnt_diff_us); + GUEST_ASSERT_1(xctl & CTL_ISTATUS, xctl); +} + +static void guest_irq_handler(struct ex_regs *regs) +{ + unsigned int intid = gic_get_and_ack_irq(); + uint32_t cpu = get_vcpuid(); + struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu]; + + guest_validate_irq(intid, shared_data); + + WRITE_ONCE(shared_data->nr_iter, shared_data->nr_iter + 1); + + gic_set_eoi(intid); +} + +static void guest_run_stage(struct test_vcpu_shared_data *shared_data, + enum guest_stage stage) +{ + uint32_t irq_iter, config_iter; + + shared_data->guest_stage = stage; + shared_data->nr_iter = 0; + + for (config_iter = 0; config_iter < test_args.nr_iter; config_iter++) { + /* Setup the next interrupt */ + guest_configure_timer_action(shared_data); + + /* Setup a timeout for the interrupt to arrive */ + udelay(msecs_to_usecs(test_args.timer_period_ms) + + TIMER_TEST_ERR_MARGIN_US); + + irq_iter = READ_ONCE(shared_data->nr_iter); + GUEST_ASSERT_2(config_iter + 1 == irq_iter, + config_iter + 1, irq_iter); + }; +} + +static void guest_code(void) +{ + uint32_t cpu = get_vcpuid(); + struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu]; + + local_irq_disable(); + + gic_init(GIC_V3, test_args.nr_vcpus, + (void *)GICD_BASE_GPA, (void *)GICR_BASE_GPA); + + timer_set_ctl(VIRTUAL, CTL_IMASK); + timer_set_ctl(PHYSICAL, CTL_IMASK); + + gic_irq_enable(VTIMER_IRQ); + gic_irq_enable(PTIMER_IRQ); + local_irq_enable(); + + guest_run_stage(shared_data, GUEST_STAGE_VTIMER_CVAL); + guest_run_stage(shared_data, GUEST_STAGE_VTIMER_TVAL); + guest_run_stage(shared_data, GUEST_STAGE_PTIMER_CVAL); + guest_run_stage(shared_data, GUEST_STAGE_PTIMER_TVAL); + + GUEST_DONE(); +} + +static void *test_vcpu_run(void *arg) +{ + struct ucall uc; + struct test_vcpu *vcpu = arg; + struct kvm_vm *vm = vcpu->vm; + uint32_t vcpuid = vcpu->vcpuid; + struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[vcpuid]; + + vcpu_run(vm, vcpuid); + + switch (get_ucall(vm, vcpuid, &uc)) { + case UCALL_SYNC: + case UCALL_DONE: + break; + case UCALL_ABORT: + sync_global_from_guest(vm, *shared_data); + TEST_ASSERT(false, + "%s at %s:%ld\n\tvalues: %lu, %lu; %lu, vcpu: %u; stage: %u; iter: %u", + (const char *)uc.args[0], __FILE__, uc.args[1], + uc.args[2], uc.args[3], uc.args[4], vcpuid, + shared_data->guest_stage, shared_data->nr_iter); + break; + default: + TEST_FAIL("Unexpected guest exit\n"); + } + + return NULL; +} + +static void test_run(struct kvm_vm *vm) +{ + int i, ret; + + for (i = 0; i < test_args.nr_vcpus; i++) { + ret = pthread_create(&test_vcpu[i].pt_vcpu_run, NULL, + test_vcpu_run, &test_vcpu[i]); + TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i); + } + + for (i = 0; i < test_args.nr_vcpus; i++) + pthread_join(test_vcpu[i].pt_vcpu_run, NULL); +} + +static void test_vm_setup_gic(struct kvm_vm *vm, unsigned int n_gicr_pages) +{ + uint64_t addr; + int gic_fd; + + gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false); + + addr = GICD_BASE_GPA; + kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, + KVM_VGIC_V3_ADDR_TYPE_DIST, &addr, true); + virt_pg_map(vm, GICD_BASE_GPA, GICD_BASE_GPA); + + addr = REDIST_REGION_ATTR_ADDR(test_args.nr_vcpus, GICR_BASE_GPA, 0, 0); + kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, + KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true); + virt_map(vm, GICR_BASE_GPA, GICR_BASE_GPA, n_gicr_pages); + + kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL, + KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true); +} + +static struct kvm_vm *test_vm_create(void) +{ + struct kvm_vm *vm; + unsigned int i, n_gicr_pages; + int nr_vcpus = test_args.nr_vcpus; + + /* Reserve additional pages for GICR MMIO based on nr_vcpus */ + n_gicr_pages = vm_calc_num_guest_pages(VM_MODE_DEFAULT, + 2 * SZ_64K * nr_vcpus); + + vm = vm_create_default_with_vcpus(nr_vcpus, n_gicr_pages, 0, + guest_code, NULL); + + vm_init_descriptor_tables(vm); + vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT, guest_irq_handler); + + for (i = 0; i < nr_vcpus; i++) { + vcpu_init_descriptor_tables(vm, i); + + test_vcpu[i].vcpuid = i; + test_vcpu[i].vm = vm; + } + + ucall_init(vm, NULL); + test_vm_setup_gic(vm, n_gicr_pages); + + /* Make all the test's cmdline args visible to the guest */ + sync_global_to_guest(vm, test_args); + + return vm; +} + +static void test_print_help(char *name) +{ + pr_info("Usage: %s [-h] [-n nr_vcpus] [-i iterations] [-p timer_period_ms]\n", + name); + pr_info("\t-n: Number of vCPUs to configure (default: %u; max: %u)\n", + NR_VCPUS_DEF, KVM_MAX_VCPUS); + pr_info("\t-i: Number of iterations per stage (default: %u)\n", + NR_TEST_ITERS_DEF); + pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n", + TIMER_TEST_PERIOD_MS_DEF); + pr_info("\t-h: print this help screen\n"); +} + +static bool parse_args(int argc, char *argv[]) +{ + int opt; + + while ((opt = getopt(argc, argv, "hn:i:p:")) != -1) { + switch (opt) { + case 'n': + test_args.nr_vcpus = atoi(optarg); + if (test_args.nr_vcpus <= 0) { + pr_info("Positive value needed for -n\n"); + goto err; + } else if (test_args.nr_vcpus > KVM_MAX_VCPUS) { + pr_info("Max allowed vCPUs: %u\n", + KVM_MAX_VCPUS); + goto err; + } + break; + case 'i': + test_args.nr_iter = atoi(optarg); + if (test_args.nr_iter <= 0) { + pr_info("Positive value needed for -i\n"); + goto err; + } + break; + case 'p': + test_args.timer_period_ms = atoi(optarg); + if (test_args.timer_period_ms <= 0) { + pr_info("Positive value needed for -p\n"); + goto err; + } + break; + case 'h': + default: + goto err; + } + } + + return true; + +err: + test_print_help(argv[0]); + return false; +} + +int main(int argc, char *argv[]) +{ + struct kvm_vm *vm; + + /* Tell stdout not to buffer its content */ + setbuf(stdout, NULL); + + if (!parse_args(argc, argv)) + exit(KSFT_SKIP); + + vm = test_vm_create(); + test_run(vm); + kvm_vm_free(vm); + + return 0; +}