From patchwork Wed Aug 4 08:57:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418163 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 98877C4338F for ; Wed, 4 Aug 2021 09:01:22 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6892160E52 for ; Wed, 4 Aug 2021 09:01:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6892160E52 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=v2qpb3gVna8+WkH6NL5hYaBg9rpBzUn8gT9EP/br/yE=; b=v+AtGPSaTbrYw+S25ZGsIKQ+mJ fiU0o5jR+rllK7PlsnhK/oZdzVvqPP4Kgo5FdlfOpy43kcWvWbLcLQqQ2yOsjRxEpWlPTD12K/i1S /BDyWperHU7k6AhR5pqO53Yz/hqU0fP/8XUGWoQauL4k7K8p5Y4kSJFhefbBZPJUJz2efP+/udW+V eux+8ZSN1jheNywlUN0M9+f6GA8Cybv/i6NewI6uGVPipf4s4TWpz3/3ilBhqNzpFh6GucKmMM0/s pfJwwJ3G+FlarRB4lRZ9D2gAA3GUxpTz6V8uOm2lW/w8uVvkZisHEZbkH3tn8b0+L0W4AnxB/FZUn QuhPLrXQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjZ-005FYu-Mx; Wed, 04 Aug 2021 08:58:41 +0000 Received: from mail-qk1-x74a.google.com ([2607:f8b0:4864:20::74a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjW-005FXY-7P for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:39 +0000 Received: by mail-qk1-x74a.google.com with SMTP id p14-20020a05620a22eeb02903b94aaa0909so1662789qki.15 for ; Wed, 04 Aug 2021 01:58:36 -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=9z0ILel/nmHkGUMptTPmpCG4j9f031MAvczP47Mkt78=; b=AGG526CClu6IqHFTOxS7+h3HvPWXLqKYwyxWDqhy8O1Cl7kRhpnrrXFTY0kzLPlJzo NTLuHbzcLYaYfAWrM32xY1DL6EHrQH4/2lErBCn8/ZGON8Be4/Pp9eWnRrHfI5ABkk+e cUAX5/1tP6hG7xgE0KZ69uOsXKCWECXSJndhcqwqutNTyGslSd/lvGhdMfdY1YZV67+W DWELveZd0WTMUmICxJLUctfDxryaN/y9+D66dBcuvb4CitoE5kvYTWemb+5QNRxgHI0j rWPx8EeySutkqhAJYHR/vC6ZOVzwZ3vF7onQk6tkqzA+Opb0I7MhtY7K0lwaz97Zb10g jtsQ== 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=9z0ILel/nmHkGUMptTPmpCG4j9f031MAvczP47Mkt78=; b=QwgridhX6jD+0BqCZOCDeiJuKbUnlQ6DPavTmJmdT0EVByZ5z1mt9sczJH0eYIJ/AS XpE0c/f9gbBw4LQJ1z72Z1BDEvmnp31SJHRaXOS+fM4rBGwMIvetHxtYMTBP/ruD8Qxo Ml+PVHCjp02Nfffc1E1gdRTC3pXIQ26QkArcBES864F3r/gnF6UohHQCHOesqXtYOpl1 /dQlzLX47tJq72sL5xpX21YJdQ6znrDhbUR1Ryp1dPv8Ozgm22DhE/zJPdZpi1ep1YLN aEKJcIcLS1ojfWWfXDlKlvijXa5bDWVeOdFGrUizj35FcDu0Q4Yd2mGZvYIEXMHfZFxj cX6Q== X-Gm-Message-State: AOAM532kX0mmFkRIsn+06fVQuBwI8CvUF2f+bcr8MZCDTB71+Q0sLMcP Egh8oqAHkWRQPGia/rsU9E2dg+a50jU= X-Google-Smtp-Source: ABdhPJzxzqd5PN7eP88ZrBpXcJ5Qw54s+lcbwp2wfv6KXhmpgwkZOP22ITfr7gZ3p1xKgG6E9IZ8pxMUSks= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a05:6214:332:: with SMTP id j18mr25863430qvu.21.1628067515916; Wed, 04 Aug 2021 01:58:35 -0700 (PDT) Date: Wed, 4 Aug 2021 08:57:59 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-2-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 01/21] KVM: x86: Fix potential race in KVM_GET_CLOCK From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015838_312275_C8078F57 X-CRM114-Status: GOOD ( 15.92 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Sean noticed that KVM_GET_CLOCK was checking kvm_arch.use_master_clock outside of the pvclock sync lock. This is problematic, as the clock value written to the user may or may not actually correspond to a stable TSC. Fix the race by populating the entire kvm_clock_data structure behind the pvclock_gtod_sync_lock. Suggested-by: Sean Christopherson Signed-off-by: Oliver Upton Signed-off-by: Paolo Bonzini Reviewed-by: Oliver Upton --- arch/x86/kvm/x86.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8cdf4ac6990b..34287c522f4e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2782,19 +2782,20 @@ static void kvm_gen_update_masterclock(struct kvm *kvm) #endif } -u64 get_kvmclock_ns(struct kvm *kvm) +static void get_kvmclock(struct kvm *kvm, struct kvm_clock_data *data) { struct kvm_arch *ka = &kvm->arch; struct pvclock_vcpu_time_info hv_clock; unsigned long flags; - u64 ret; spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags); if (!ka->use_master_clock) { spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags); - return get_kvmclock_base_ns() + ka->kvmclock_offset; + data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset; + return; } + data->flags |= KVM_CLOCK_TSC_STABLE; hv_clock.tsc_timestamp = ka->master_cycle_now; hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset; spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags); @@ -2806,13 +2807,26 @@ u64 get_kvmclock_ns(struct kvm *kvm) kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL, &hv_clock.tsc_shift, &hv_clock.tsc_to_system_mul); - ret = __pvclock_read_cycles(&hv_clock, rdtsc()); - } else - ret = get_kvmclock_base_ns() + ka->kvmclock_offset; + data->clock = __pvclock_read_cycles(&hv_clock, rdtsc()); + } else { + data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset; + } put_cpu(); +} - return ret; +u64 get_kvmclock_ns(struct kvm *kvm) +{ + struct kvm_clock_data data; + + /* + * Zero flags as it's accessed RMW, leave everything else uninitialized + * as clock is always written and no other fields are consumed. + */ + data.flags = 0; + + get_kvmclock(kvm, &data); + return data.clock; } static void kvm_setup_pvclock_page(struct kvm_vcpu *v, @@ -6104,11 +6118,14 @@ long kvm_arch_vm_ioctl(struct file *filp, } case KVM_GET_CLOCK: { struct kvm_clock_data user_ns; - u64 now_ns; - now_ns = get_kvmclock_ns(kvm); - user_ns.clock = now_ns; - user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0; + /* + * Zero flags as it is accessed RMW, leave everything else + * uninitialized as clock is always written and no other fields + * are consumed. + */ + user_ns.flags = 0; + get_kvmclock(kvm, &user_ns); memset(&user_ns.pad, 0, sizeof(user_ns.pad)); r = -EFAULT; From patchwork Wed Aug 4 08:58:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418159 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 D0571C4338F for ; Wed, 4 Aug 2021 09:01:01 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9554360E52 for ; Wed, 4 Aug 2021 09:01:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 9554360E52 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=jasS9M8ko8dq/GIpgRyP8MAwH0uCYg1IiYb6Nao5E50=; b=fON0HFUAQqH+yKjbZLFP9z9hiG LDaxCX+iq11b3IcU83yIRLsqs33824yvsxRIyhl78DEIUoZEztdzeLsZLrCRKQ2sSs2QLaUcx+qyP 5x0YuXVxlNXy+PbEXVUxp7I2y/vKnfmi+9e5LcIBpt4qVQJberMSeCeTvF9ggUxbNcIl5Z+29EhRc WSE29Pa0u+3BpLAd3Ivq3iZ4KpxcAxpVw5gkL/nYNEdkf9kH9N2yc7pbne7W4WAaZH8io2q7xSFk3 IbjMxIcXXbRb/mp8pJfuu5flyY4p4P7BL9iWzHjoRUp+NRV2bujVreBw8CdAY0tFvLmaoJBYthZLQ cTEn4Tdw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCk6-005FiA-O0; Wed, 04 Aug 2021 08:59:14 +0000 Received: from mail-il1-x14a.google.com ([2607:f8b0:4864:20::14a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjY-005FXd-10 for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:41 +0000 Received: by mail-il1-x14a.google.com with SMTP id v18-20020a056e020f92b02901ff388acf98so627211ilo.2 for ; Wed, 04 Aug 2021 01:58:37 -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=K7pLZDgIPuV12HPJ9thky4TOXLt6Z7al5u7GtuvUBZA=; b=by4LiJhYPpMwogtLXJ7fjEm8BONAI58MOYgbyTmmvv9mv9oTtLGatcNERorAuv0dmW UC3XjcBEb+sx3noaVxjS+QVNRj+biM3Lo1eV/RlruKJ50GC+iadfF6aaHguozUNiI3b8 YVhEsnwcNXmmJJqaEt39Vf/k1B6m654tV9mllpPUiOfRIYnAY37fY/gsmCSkNxueDDY4 CHN0wKT96CZGFhb8xqQkHDHbLL8+lrMg5+vDb+3rcZNwb2534M5p+W2BHQjONV2mDibP t5YC7m8i/+Un2HWG0r/tiICiXyhzpxJRCRei0WxRWZFxrCaI8v+wY5+1CvTYu5q7gqWn QVGw== 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=K7pLZDgIPuV12HPJ9thky4TOXLt6Z7al5u7GtuvUBZA=; b=DQxwvocJU71AAA78BVis6gBLmYT60Fj56hqk6n5EiANcj8GkT7s6sDl1zzEklvT0HQ sM4c99Y8dttN/zKGQwS9dIpz2h6iYfqzYAFSfzrWW4hVJGqbAkCNwqIbK1N8o9mliJHb sXBL3m4b8NgFZ42RV2wP8HBC3PwnhqwUrW7Cfd3VTOG2WE6224boVwIcdw/HTSyMrBtP OP640cxGUxn/I3ypxI6bVfvM6uOFVzF+SVRst+vnKwk98lmeCEe8LgNGF8quiYgp5wDG GJwuIHwqHDVU5fQ0Iptj6SdF/hT4mie14hKqyUSks8o/Xe/w/7/6CJ58zoFFO2vHLQ2q HDWg== X-Gm-Message-State: AOAM5320bSxfb+NUz5Pii+t8DEwG99iGH6OzC1F9Yt5gLnAmADgpp8DS SZUz+VD9wylyaBjIHPAmFkS8Snpx8og= X-Google-Smtp-Source: ABdhPJz2W1LC0u615gdgeVlOBMaE1ErBs2fgBK7IpnYekTHQRjIlezwcsg27qu68TXmnKqnX9nsOS4p49MQ= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a5d:824e:: with SMTP id n14mr394806ioo.134.1628067517220; Wed, 04 Aug 2021 01:58:37 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:00 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-3-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 02/21] KVM: x86: Report host tsc and realtime values in KVM_GET_CLOCK From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015840_156898_A7B556DA X-CRM114-Status: GOOD ( 26.60 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Handling the migration of TSCs correctly is difficult, in part because Linux does not provide userspace with the ability to retrieve a (TSC, realtime) clock pair for a single instant in time. In lieu of a more convenient facility, KVM can report similar information in the kvm_clock structure. Provide userspace with a host TSC & realtime pair iff the realtime clock is based on the TSC. If userspace provides KVM_SET_CLOCK with a valid realtime value, advance the KVM clock by the amount of elapsed time. Do not step the KVM clock backwards, though, as it is a monotonic oscillator. Suggested-by: Paolo Bonzini Signed-off-by: Oliver Upton --- Documentation/virt/kvm/api.rst | 42 ++++++++--- arch/x86/include/asm/kvm_host.h | 3 + arch/x86/kvm/x86.c | 127 ++++++++++++++++++-------------- include/uapi/linux/kvm.h | 7 +- 4 files changed, 112 insertions(+), 67 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index dae68e68ca23..8d4a3471ad9e 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -993,20 +993,34 @@ such as migration. When KVM_CAP_ADJUST_CLOCK is passed to KVM_CHECK_EXTENSION, it returns the set of bits that KVM can return in struct kvm_clock_data's flag member. -The only flag defined now is KVM_CLOCK_TSC_STABLE. If set, the returned -value is the exact kvmclock value seen by all VCPUs at the instant -when KVM_GET_CLOCK was called. If clear, the returned value is simply -CLOCK_MONOTONIC plus a constant offset; the offset can be modified -with KVM_SET_CLOCK. KVM will try to make all VCPUs follow this clock, -but the exact value read by each VCPU could differ, because the host -TSC is not stable. +FLAGS: + +KVM_CLOCK_TSC_STABLE. If set, the returned value is the exact kvmclock +value seen by all VCPUs at the instant when KVM_GET_CLOCK was called. +If clear, the returned value is simply CLOCK_MONOTONIC plus a constant +offset; the offset can be modified with KVM_SET_CLOCK. KVM will try +to make all VCPUs follow this clock, but the exact value read by each +VCPU could differ, because the host TSC is not stable. + +KVM_CLOCK_REALTIME. If set, the `realtime` field in the kvm_clock_data +structure is populated with the value of the host's real time +clocksource at the instant when KVM_GET_CLOCK was called. If clear, +the `realtime` field does not contain a value. + +KVM_CLOCK_HOST_TSC. If set, the `host_tsc` field in the kvm_clock_data +structure is populated with the value of the host's timestamp counter (TSC) +at the instant when KVM_GET_CLOCK was called. If clear, the `host_tsc` field +does not contain a value. :: struct kvm_clock_data { __u64 clock; /* kvmclock current value */ __u32 flags; - __u32 pad[9]; + __u32 pad0; + __u64 realtime; + __u64 host_tsc; + __u32 pad[4]; }; @@ -1023,12 +1037,22 @@ Sets the current timestamp of kvmclock to the value specified in its parameter. In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios such as migration. +FLAGS: + +KVM_CLOCK_REALTIME. If set, KVM will compare the value of the `realtime` field +with the value of the host's real time clocksource at the instant when +KVM_SET_CLOCK was called. The difference in elapsed time is added to the final +kvmclock value that will be provided to guests. + :: struct kvm_clock_data { __u64 clock; /* kvmclock current value */ __u32 flags; - __u32 pad[9]; + __u32 pad0; + __u64 realtime; + __u64 host_tsc; + __u32 pad[4]; }; diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 6818095dd157..d6376ca8efce 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1926,4 +1926,7 @@ int kvm_cpu_dirty_log_size(void); int alloc_all_memslots_rmaps(struct kvm *kvm); +#define KVM_CLOCK_VALID_FLAGS \ + (KVM_CLOCK_TSC_STABLE | KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC) + #endif /* _ASM_X86_KVM_HOST_H */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 34287c522f4e..26f1fa263192 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2804,10 +2804,20 @@ static void get_kvmclock(struct kvm *kvm, struct kvm_clock_data *data) get_cpu(); if (__this_cpu_read(cpu_tsc_khz)) { +#ifdef CONFIG_X86_64 + struct timespec64 ts; + + if (kvm_get_walltime_and_clockread(&ts, &data->host_tsc)) { + data->realtime = ts.tv_nsec + NSEC_PER_SEC * ts.tv_sec; + data->flags |= KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC; + } else +#endif + data->host_tsc = rdtsc(); + kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL, &hv_clock.tsc_shift, &hv_clock.tsc_to_system_mul); - data->clock = __pvclock_read_cycles(&hv_clock, rdtsc()); + data->clock = __pvclock_read_cycles(&hv_clock, data->host_tsc); } else { data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset; } @@ -4047,7 +4057,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) r = KVM_SYNC_X86_VALID_FIELDS; break; case KVM_CAP_ADJUST_CLOCK: - r = KVM_CLOCK_TSC_STABLE; + r = KVM_CLOCK_VALID_FLAGS; break; case KVM_CAP_X86_DISABLE_EXITS: r |= KVM_X86_DISABLE_EXITS_HLT | KVM_X86_DISABLE_EXITS_PAUSE | @@ -5834,6 +5844,60 @@ int kvm_arch_pm_notifier(struct kvm *kvm, unsigned long state) } #endif /* CONFIG_HAVE_KVM_PM_NOTIFIER */ +static int kvm_vm_ioctl_get_clock(struct kvm *kvm, void __user *argp) +{ + struct kvm_clock_data data; + + memset(&data, 0, sizeof(data)); + get_kvmclock(kvm, &data); + + if (copy_to_user(argp, &data, sizeof(data))) + return -EFAULT; + + return 0; +} + +static int kvm_vm_ioctl_set_clock(struct kvm *kvm, void __user *argp) +{ + struct kvm_arch *ka = &kvm->arch; + struct kvm_clock_data data; + u64 now_raw_ns; + + if (copy_from_user(&data, argp, sizeof(data))) + return -EFAULT; + + if (data.flags & ~KVM_CLOCK_REALTIME) + return -EINVAL; + + /* + * TODO: userspace has to take care of races with VCPU_RUN, so + * kvm_gen_update_masterclock() can be cut down to locked + * pvclock_update_vm_gtod_copy(). + */ + kvm_gen_update_masterclock(kvm); + + spin_lock_irq(&ka->pvclock_gtod_sync_lock); + if (data.flags & KVM_CLOCK_REALTIME) { + u64 now_real_ns = ktime_get_real_ns(); + + /* + * Avoid stepping the kvmclock backwards. + */ + if (now_real_ns > data.realtime) + data.clock += now_real_ns - data.realtime; + } + + if (ka->use_master_clock) + now_raw_ns = ka->master_kernel_ns; + else + now_raw_ns = get_kvmclock_base_ns(); + ka->kvmclock_offset = data.clock - now_raw_ns; + spin_unlock_irq(&ka->pvclock_gtod_sync_lock); + + kvm_make_all_cpus_request(kvm, KVM_REQ_CLOCK_UPDATE); + return 0; +} + long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -6077,63 +6141,12 @@ long kvm_arch_vm_ioctl(struct file *filp, break; } #endif - case KVM_SET_CLOCK: { - struct kvm_arch *ka = &kvm->arch; - struct kvm_clock_data user_ns; - u64 now_ns; - - r = -EFAULT; - if (copy_from_user(&user_ns, argp, sizeof(user_ns))) - goto out; - - r = -EINVAL; - if (user_ns.flags) - goto out; - - r = 0; - /* - * TODO: userspace has to take care of races with VCPU_RUN, so - * kvm_gen_update_masterclock() can be cut down to locked - * pvclock_update_vm_gtod_copy(). - */ - kvm_gen_update_masterclock(kvm); - - /* - * This pairs with kvm_guest_time_update(): when masterclock is - * in use, we use master_kernel_ns + kvmclock_offset to set - * unsigned 'system_time' so if we use get_kvmclock_ns() (which - * is slightly ahead) here we risk going negative on unsigned - * 'system_time' when 'user_ns.clock' is very small. - */ - spin_lock_irq(&ka->pvclock_gtod_sync_lock); - if (kvm->arch.use_master_clock) - now_ns = ka->master_kernel_ns; - else - now_ns = get_kvmclock_base_ns(); - ka->kvmclock_offset = user_ns.clock - now_ns; - spin_unlock_irq(&ka->pvclock_gtod_sync_lock); - - kvm_make_all_cpus_request(kvm, KVM_REQ_CLOCK_UPDATE); + case KVM_SET_CLOCK: + r = kvm_vm_ioctl_set_clock(kvm, argp); break; - } - case KVM_GET_CLOCK: { - struct kvm_clock_data user_ns; - - /* - * Zero flags as it is accessed RMW, leave everything else - * uninitialized as clock is always written and no other fields - * are consumed. - */ - user_ns.flags = 0; - get_kvmclock(kvm, &user_ns); - memset(&user_ns.pad, 0, sizeof(user_ns.pad)); - - r = -EFAULT; - if (copy_to_user(argp, &user_ns, sizeof(user_ns))) - goto out; - r = 0; + case KVM_GET_CLOCK: + r = kvm_vm_ioctl_get_clock(kvm, argp); break; - } case KVM_MEMORY_ENCRYPT_OP: { r = -ENOTTY; if (kvm_x86_ops.mem_enc_op) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index d9e4aabcb31a..53a49cb8616a 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1223,11 +1223,16 @@ struct kvm_irqfd { /* Do not use 1, KVM_CHECK_EXTENSION returned it before we had flags. */ #define KVM_CLOCK_TSC_STABLE 2 +#define KVM_CLOCK_REALTIME (1 << 2) +#define KVM_CLOCK_HOST_TSC (1 << 3) struct kvm_clock_data { __u64 clock; __u32 flags; - __u32 pad[9]; + __u32 pad0; + __u64 realtime; + __u64 host_tsc; + __u32 pad[4]; }; /* For KVM_CAP_SW_TLB */ From patchwork Wed Aug 4 08:58:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418169 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 B269DC4338F for ; Wed, 4 Aug 2021 09:01:34 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7C58B60E52 for ; Wed, 4 Aug 2021 09:01:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7C58B60E52 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=zLGwwIXypuzaIStf5w6p0bJT2BXuc+D9oxlAyxwKcgc=; b=ZG1ZUZafzHz7P6SvpAnnsNVJFg FN3eLJXBy8J3SQlS8InjEGlNyisCl81rpkqiqAtjFpQXoznaopLSviL8U/tKQ07uF1leZ+vxQ9YT9 QPwbwiaU7yMoIxUNWRIrA0/ZvVge29emLQZnVvUF1QP/gnFYHvQmJvPh400VFcGothjBwQvgrgZTO i074ZQHwG4EpHiARxrJE+fQWYSiin2vtpw8FAIDwsEf7xgCKjn3ZKWePP6N85QXAGIM2MFlyodAXi bjGhW+hyzaYBRz0dhWUUmkmpCFInSsZ4nuo/tYVvU+6eI299/R5jUedLXRFcwjRMg8d+ZJbk65MYa wcLv4EEg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjw-005Fgn-6M; Wed, 04 Aug 2021 08:59:04 +0000 Received: from mail-io1-xd4a.google.com ([2607:f8b0:4864:20::d4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjX-005FY8-JA for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:40 +0000 Received: by mail-io1-xd4a.google.com with SMTP id e7-20020a0566020447b029050017e563a6so1076377iov.4 for ; Wed, 04 Aug 2021 01:58: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=yT+nCrFmg471JgKctqrSQtIm1tfSoSdZEimBbuaP3hM=; b=I75O/UznjRurZ12yqjeSXM1uRHLtkMyqOHMPWxjHv7EqFHpdUtNM/q2lhH3rSJRXMi hmtx2v5DfPRntVTXd1HEnfhKFNm++uRppRctqQ9/tBN3y/qLQO6G3I2+zHRVMWwO1Qei zrOEuyl5E91LBxGmWuvw3x7WRXMvdLPIXIO7e3es+i3ueOVQhqmLhiWEr19ExFdGTomd tzU7TnghJPoMZ486oD2ZRvoEOyvto0wtqL/JmqdjzcDUWMzObugg/StxuiD9e42u0kek tBdoapOnjPK+cQ9upIllnUwqm+zBJQdTCWl7xwGMM/2Q+sZLNygYgEiJoxOxk2TjKJ7l qk2Q== 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=yT+nCrFmg471JgKctqrSQtIm1tfSoSdZEimBbuaP3hM=; b=LIZlgEvqTvUFUsgCRXt6I0VCZWtIEdQmLbVtBEaWHdr6sK1Bo97wjGta4YdtYVKwKt mkQRF5ry4no6mv/+mGRb8Vou7dMbjXUZQVL6pwcV/WdW92xgPYuOaA/5phchvgBDcYSr hnICKQF6Oqwf2lRy1JZUoI1N1V/hDmDHhI0II8i+GnrukwSVo2mcJiTcAe1I8Y8qCAE4 ZCaIIYE9RtxGqH2k734M896GX3wrlpynPWI86PoinovwGk9K2Hu+89M3UNygHHJpOvza /ovMQTkYeTc2puSRQZ5QX7kHx38sMYhJtyvod/h0V47hnVbZlTf2mQOxXVsfh6GYd48a teHA== X-Gm-Message-State: AOAM530hvvgCzthxxqEpoC+qiiwPJW4GRtAsIc4UMqfJNfVyy4g0AENe d32gZLf2l18sHdwbUPn3I4uMmsEQjO8= X-Google-Smtp-Source: ABdhPJxSOYTpnXMnEgvD536Lr//pppHFulfycmnTBjxZ233HWebGAqoEW5FBilAhV/Yot+rrAUs5jGbPkWM= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a92:cf44:: with SMTP id c4mr262704ilr.11.1628067518129; Wed, 04 Aug 2021 01:58:38 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:01 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-4-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 03/21] KVM: x86: Take the pvclock sync lock behind the tsc_write_lock From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015839_679333_425AEA69 X-CRM114-Status: GOOD ( 12.84 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org A later change requires that the pvclock sync lock be taken while holding the tsc_write_lock. Change the locking in kvm_synchronize_tsc() to align with the requirement to isolate the locking change to its own commit. Cc: Sean Christopherson Signed-off-by: Oliver Upton --- Documentation/virt/kvm/locking.rst | 11 +++++++++++ arch/x86/kvm/x86.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/virt/kvm/locking.rst b/Documentation/virt/kvm/locking.rst index 8138201efb09..0bf346adac2a 100644 --- a/Documentation/virt/kvm/locking.rst +++ b/Documentation/virt/kvm/locking.rst @@ -36,6 +36,9 @@ On x86: holding kvm->arch.mmu_lock (typically with ``read_lock``, otherwise there's no need to take kvm->arch.tdp_mmu_pages_lock at all). +- kvm->arch.tsc_write_lock is taken outside + kvm->arch.pvclock_gtod_sync_lock + Everything else is a leaf: no other lock is taken inside the critical sections. @@ -222,6 +225,14 @@ time it will be set using the Dirty tracking mechanism described above. :Comment: 'raw' because hardware enabling/disabling must be atomic /wrt migration. +:Name: kvm_arch::pvclock_gtod_sync_lock +:Type: raw_spinlock_t +:Arch: x86 +:Protects: kvm_arch::{cur_tsc_generation,cur_tsc_nsec,cur_tsc_write, + cur_tsc_offset,nr_vcpus_matched_tsc} +:Comment: 'raw' because updating the kvm master clock must not be + preempted. + :Name: kvm_arch::tsc_write_lock :Type: raw_spinlock :Arch: x86 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 26f1fa263192..93b449761fbe 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2529,7 +2529,6 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write; kvm_vcpu_write_tsc_offset(vcpu, offset); - raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags); spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags); if (!matched) { @@ -2540,6 +2539,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) kvm_track_tsc_matching(vcpu); spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags); + raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags); } static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu, From patchwork Wed Aug 4 08:58:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418161 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 C8691C4338F for ; Wed, 4 Aug 2021 09:01:17 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8D13B60E52 for ; Wed, 4 Aug 2021 09:01:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 8D13B60E52 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=a0KtqnpRRqnybgGWWTo6fN7xbHonDKC47FdpJ8RoIP0=; b=a745m1jMc6DV+gx6+3WnCg9DkO 0GW7omHrwm8YBCu6+xG+oQD5YO2G/9mOjTwkQJzrBDqkvRqn6jBm15Po72oK/BshgZFoQPwkOadiK 8wv590i6vcendaeSdMgw879jXTwKCllxiXcOfn7UAxU5R8oZaNfVmOFLbMeFAxewR4xrWayvpfrb3 KMNlakwLBvwdr4Y6gGRUEIronD+BvkBNf6ZV78W3TdqGNohfgW2YT/embEvtmxMm+Dhn2Y4Amb90G wRNUt1CtnOik0+Ws36ca5o4yzvbOQ+whYpRuz/oWqis765nkD5eGRu9+Q6uKtPvSzdHrDD39tzuxM wM4goseg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCkH-005FkS-KK; Wed, 04 Aug 2021 08:59:25 +0000 Received: from mail-il1-x149.google.com ([2607:f8b0:4864:20::149]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjZ-005FYE-1p for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:42 +0000 Received: by mail-il1-x149.google.com with SMTP id o11-20020a92d38b0000b0290222c57c8ca8so609544ilo.16 for ; Wed, 04 Aug 2021 01:58:39 -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=uloEpvDC1x4KyjcHtp66tRD4W6eFcIbVLp7KXwjdRug=; b=wWYNfr0/AgyWtA0xf6ApJcYYykZozz9WwRpQ2OdZvKK6Nt5sdWxU7SXTd0G4pRobA3 +iF6vlIXzYig3jrnte3drl3CENUMZinaVvksioh27z6Ierrhvj2stjn6tx5duzEGuwuS yprkj51j3QUNbZF2ZFzngnBUD1Gr6Ph5TxERYyOUfzqWsNTutgKpCpPgdX28ctqVcJk7 LJjiO42DBcrzWRLU4GB2GWmPqKgL7AYzmO5hk54ey9J6OoFr96x/KSAF1JHTyQtOZSJh mPHrSOeRaBFaCWmL1z7NLA5uURwVEfaz5ccXJRo10iLCVu+DzEqBDvrjAnY1N68Fsyui /wEw== 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=uloEpvDC1x4KyjcHtp66tRD4W6eFcIbVLp7KXwjdRug=; b=TtisbcfIG5sGzkydap13h4n+a901JhEf/84dK9tljKlh+7D6Pf9Jw7Jznw5BCvR8Sx HV/4kSmlmtciqbBiD1bvK7UypJhfXw57DLB5akOBZQKC+qFfdehdMYZZ5QILoinRMMAe 88rQ7cgQvR6V+EQbwicWweK4+HqXmvOlAA1x83D6uFP8+cMfloHMIfE1CC60w4aJko94 sZu4kj/3s6E3HJpTPoaXKZWADJw8Vp99D6iaomvPWMGqaA3RJG99VTu++qTuj7liFdJB iGz65E3DWnSOkhsu7+WSKEgylICJS/OVRloZEf3n/MRiuLZXVQlO7pxUFqN6vvXs1Cde qvXg== X-Gm-Message-State: AOAM531btota7FafSjvNwde922BeixBkfuNyGPxQfHDT6+zj3xFuM/oC j5LGkbMM7Tt+f/28+pHpYanCbz8clAA= X-Google-Smtp-Source: ABdhPJwtVZyUWoHKFbiNQ2h2t9X7r0uhYjdaRL+9QGByuYY9K8DV9KrSpRwCNZjrwBRQxEPOiczXInUogDA= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a05:6638:381e:: with SMTP id i30mr23084938jav.17.1628067519135; Wed, 04 Aug 2021 01:58:39 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:02 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-5-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 04/21] KVM: x86: Refactor tsc synchronization code From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015841_155155_0469B5C5 X-CRM114-Status: GOOD ( 15.22 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Refactor kvm_synchronize_tsc to make a new function that allows callers to specify TSC parameters (offset, value, nanoseconds, etc.) explicitly for the sake of participating in TSC synchronization. Signed-off-by: Oliver Upton --- arch/x86/kvm/x86.c | 105 ++++++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 44 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 93b449761fbe..91aea751d621 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2443,13 +2443,71 @@ static inline bool kvm_check_tsc_unstable(void) return check_tsc_unstable(); } +/* + * Infers attempts to synchronize the guest's tsc from host writes. Sets the + * offset for the vcpu and tracks the TSC matching generation that the vcpu + * participates in. + */ +static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc, + u64 ns, bool matched) +{ + struct kvm *kvm = vcpu->kvm; + bool already_matched; + + lockdep_assert_held(&kvm->arch.tsc_write_lock); + + already_matched = + (vcpu->arch.this_tsc_generation == kvm->arch.cur_tsc_generation); + + /* + * We track the most recent recorded KHZ, write and time to + * allow the matching interval to be extended at each write. + */ + kvm->arch.last_tsc_nsec = ns; + kvm->arch.last_tsc_write = tsc; + kvm->arch.last_tsc_khz = vcpu->arch.virtual_tsc_khz; + + vcpu->arch.last_guest_tsc = tsc; + + /* Keep track of which generation this VCPU has synchronized to */ + vcpu->arch.this_tsc_generation = kvm->arch.cur_tsc_generation; + vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec; + vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write; + + kvm_vcpu_write_tsc_offset(vcpu, offset); + + if (!matched) { + /* + * We split periods of matched TSC writes into generations. + * For each generation, we track the original measured + * nanosecond time, offset, and write, so if TSCs are in + * sync, we can match exact offset, and if not, we can match + * exact software computation in compute_guest_tsc() + * + * These values are tracked in kvm->arch.cur_xxx variables. + */ + kvm->arch.cur_tsc_generation++; + kvm->arch.cur_tsc_nsec = ns; + kvm->arch.cur_tsc_write = tsc; + kvm->arch.cur_tsc_offset = offset; + + spin_lock(&kvm->arch.pvclock_gtod_sync_lock); + kvm->arch.nr_vcpus_matched_tsc = 0; + } else if (!already_matched) { + spin_lock(&kvm->arch.pvclock_gtod_sync_lock); + kvm->arch.nr_vcpus_matched_tsc++; + } + + kvm_track_tsc_matching(vcpu); + spin_unlock(&kvm->arch.pvclock_gtod_sync_lock); +} + static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) { struct kvm *kvm = vcpu->kvm; u64 offset, ns, elapsed; unsigned long flags; - bool matched; - bool already_matched; + bool matched = false; bool synchronizing = false; raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags); @@ -2495,50 +2553,9 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) offset = kvm_compute_l1_tsc_offset(vcpu, data); } matched = true; - already_matched = (vcpu->arch.this_tsc_generation == kvm->arch.cur_tsc_generation); - } else { - /* - * We split periods of matched TSC writes into generations. - * For each generation, we track the original measured - * nanosecond time, offset, and write, so if TSCs are in - * sync, we can match exact offset, and if not, we can match - * exact software computation in compute_guest_tsc() - * - * These values are tracked in kvm->arch.cur_xxx variables. - */ - kvm->arch.cur_tsc_generation++; - kvm->arch.cur_tsc_nsec = ns; - kvm->arch.cur_tsc_write = data; - kvm->arch.cur_tsc_offset = offset; - matched = false; } - /* - * We also track th most recent recorded KHZ, write and time to - * allow the matching interval to be extended at each write. - */ - kvm->arch.last_tsc_nsec = ns; - kvm->arch.last_tsc_write = data; - kvm->arch.last_tsc_khz = vcpu->arch.virtual_tsc_khz; - - vcpu->arch.last_guest_tsc = data; - - /* Keep track of which generation this VCPU has synchronized to */ - vcpu->arch.this_tsc_generation = kvm->arch.cur_tsc_generation; - vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec; - vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write; - - kvm_vcpu_write_tsc_offset(vcpu, offset); - - spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags); - if (!matched) { - kvm->arch.nr_vcpus_matched_tsc = 0; - } else if (!already_matched) { - kvm->arch.nr_vcpus_matched_tsc++; - } - - kvm_track_tsc_matching(vcpu); - spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags); + __kvm_synchronize_tsc(vcpu, offset, data, ns, matched); raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags); } From patchwork Wed Aug 4 08:58:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418167 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 8CF03C432BE for ; Wed, 4 Aug 2021 09:01:28 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5F7CA60E52 for ; Wed, 4 Aug 2021 09:01:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 5F7CA60E52 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=ul3eyDdLYsLICT6J0a+xGfHaMArrtbBhBA2mEjP6sF4=; b=zp3Y+HPoFLF5etY4Us7qDRJQod +/RDPR6JnWEiYs24jM2N2zIznsNxbYllU9No0HyQ+Xuusm3Y4bEp581t92ecEviPqJSc50ZwvtSYF uCar/WrUMby+dEm9x2OUU+ohiia85nfJO5H/fV5FOUc6HH0Em+8Qkq2Mwd2cvG4dWml6s6vE1KxoM O4mIqA+5TZm0gJTOdGhTIlh3AR3UpkGuJQ+B6RinlSO8NU7ADm9ZoU7emVaONsUZIpConagpxIPfq RBj7+LIYC7dWHPcCbrhWHZVEHDTtC4OUt2W7HYWZ03zjd5Lf1/fN/X4uco5efj/vwBscgNgjQ9hkJ L035X3AA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCkW-005Foq-FC; Wed, 04 Aug 2021 08:59:40 +0000 Received: from mail-io1-xd4a.google.com ([2607:f8b0:4864:20::d4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjZ-005FYw-P1 for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:43 +0000 Received: by mail-io1-xd4a.google.com with SMTP id k6-20020a6b3c060000b0290568c2302268so1048342iob.16 for ; Wed, 04 Aug 2021 01:58:40 -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=x8LPWtdOqJCGz9ZSpM5JrXHjuEyQMoplDMq1Km+kgH0=; b=Au6D/Rvztr8x+Su+/oHB1zmQdKPKKOPs60i1D7hXkjYp9l6h0j9DWswHbfoi6cMVx/ cjoothQhTFpqD3jSDCQ24VbgRhP1N00BTGfvSVXqc4pdGyfiOUF8th/2oUMCVzTjs/E8 WPDPC+v5GLCMg0rbTM5na3j7fyRd/GR0XorrJHmYMLeYrhtyAlVC+ghXc+An64/+5N5Z fVLCeWG7KQ9TzW6MjKrc2hASzDgjGZcA9GK0/shvksegM3ZLWPdVozZazOshAoEZ9GbX WDlgqr8qPRDdjK/ffvbsn+J+q78H7XPdFth0NkJZaioxy4IovF4YAdBGOXh+JbNq/Bz+ PnLw== 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=x8LPWtdOqJCGz9ZSpM5JrXHjuEyQMoplDMq1Km+kgH0=; b=r+JCr8z0c+eumnT3ofo9aHqSo3ck7UqkBRJF2TUCB790lezJdzuaLWDKsdM0vzvHsY Mo//tZoFdWt5qATw2Gfi6fzR02hLeSSE5geiFiDZdOjOrgtjYvvqwdhJ6so9ALUUpKO5 cFV2hrldlCRQc/h93OOyKBe8QQENRXpFmZz8qDnbbqxQJkZYtPTxHcoIusjdaVkX5VVw XT8qewjjqp6UJJUzcHLyc5+2N0xZ1QuJMI36gU7pEHrKLwfxX0J/qzUdNm2bn0xy34d4 BAMhMt7auKX5uhEZgoOk4TWc6OA70Ox6GPvicVLXpPKyaRVlY1SIVRfAEdjdd5qmahP/ G2tA== X-Gm-Message-State: AOAM533WdjUgbHKGcaNGudd3/vts+Erh3x+EXAVhXC1AkEF4Xur9padW 0d3m6Jnmj49Hf5oOeY6y5ySQeRyY3us= X-Google-Smtp-Source: ABdhPJwJZUENE+FwWb/7dNEy0PuIQl8TXpDew9XDjDz/fQ4geLk3Q3U6VoPSJg0+mNpCuFaUZohuvLgh4W8= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a5e:c803:: with SMTP id y3mr762616iol.107.1628067520327; Wed, 04 Aug 2021 01:58:40 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:03 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-6-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 05/21] KVM: x86: Expose TSC offset controls to userspace From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015841_866501_7CC3B789 X-CRM114-Status: GOOD ( 24.13 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org To date, VMM-directed TSC synchronization and migration has been a bit messy. KVM has some baked-in heuristics around TSC writes to infer if the VMM is attempting to synchronize. This is problematic, as it depends on host userspace writing to the guest's TSC within 1 second of the last write. A much cleaner approach to configuring the guest's views of the TSC is to simply migrate the TSC offset for every vCPU. Offsets are idempotent, and thus not subject to change depending on when the VMM actually reads/writes values from/to KVM. The VMM can then read the TSC once with KVM_GET_CLOCK to capture a (realtime, host_tsc) pair at the instant when the guest is paused. Cc: David Matlack Cc: Sean Christopherson Signed-off-by: Oliver Upton --- Documentation/virt/kvm/devices/vcpu.rst | 57 +++++++++++++ arch/x86/include/asm/kvm_host.h | 1 + arch/x86/include/uapi/asm/kvm.h | 4 + arch/x86/kvm/x86.c | 109 ++++++++++++++++++++++++ 4 files changed, 171 insertions(+) diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst index 2acec3b9ef65..3b399d727c11 100644 --- a/Documentation/virt/kvm/devices/vcpu.rst +++ b/Documentation/virt/kvm/devices/vcpu.rst @@ -161,3 +161,60 @@ Specifies the base address of the stolen time structure for this VCPU. The base address must be 64 byte aligned and exist within a valid guest memory region. See Documentation/virt/kvm/arm/pvtime.rst for more information including the layout of the stolen time structure. + +4. GROUP: KVM_VCPU_TSC_CTRL +=========================== + +:Architectures: x86 + +4.1 ATTRIBUTE: KVM_VCPU_TSC_OFFSET + +:Parameters: 64-bit unsigned TSC offset + +Returns: + + ======= ====================================== + -EFAULT Error reading/writing the provided + parameter address. + -ENXIO Attribute not supported + ======= ====================================== + +Specifies the guest's TSC offset relative to the host's TSC. The guest's +TSC is then derived by the following equation: + + guest_tsc = host_tsc + KVM_VCPU_TSC_OFFSET + +This attribute is useful for the precise migration of a guest's TSC. The +following describes a possible algorithm to use for the migration of a +guest's TSC: + +From the source VMM process: + +1. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (t_0), + kvmclock nanoseconds (k_0), and realtime nanoseconds (r_0). + +2. Read the KVM_VCPU_TSC_OFFSET attribute for every vCPU to record the + guest TSC offset (off_n). + +3. Invoke the KVM_GET_TSC_KHZ ioctl to record the frequency of the + guest's TSC (freq). + +From the destination VMM process: + +4. Invoke the KVM_SET_CLOCK ioctl, providing the kvmclock nanoseconds + (k_0) and realtime nanoseconds (r_0) in their respective fields. + Ensure that the KVM_CLOCK_REALTIME flag is set in the provided + structure. KVM will advance the VM's kvmclock to account for elapsed + time since recording the clock values. + +5. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (t_1) and + kvmclock nanoseconds (k_1). + +6. Adjust the guest TSC offsets for every vCPU to account for (1) time + elapsed since recording state and (2) difference in TSCs between the + source and destination machine: + + new_off_n = t_0 + off_n + (k_1 - k_0) * freq - t_1 + +7. Write the KVM_VCPU_TSC_OFFSET attribute for every vCPU with the + respective value derived in the previous step. diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d6376ca8efce..e9bfc00692fb 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1064,6 +1064,7 @@ struct kvm_arch { u64 last_tsc_nsec; u64 last_tsc_write; u32 last_tsc_khz; + u64 last_tsc_offset; u64 cur_tsc_nsec; u64 cur_tsc_write; u64 cur_tsc_offset; diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index a6c327f8ad9e..0b22e1e84e78 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -503,4 +503,8 @@ struct kvm_pmu_event_filter { #define KVM_PMU_EVENT_ALLOW 0 #define KVM_PMU_EVENT_DENY 1 +/* for KVM_{GET,SET,HAS}_DEVICE_ATTR */ +#define KVM_VCPU_TSC_CTRL 0 /* control group for the timestamp counter (TSC) */ +#define KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */ + #endif /* _ASM_X86_KVM_H */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 91aea751d621..3fdad71e5a36 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2466,6 +2466,7 @@ static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc, kvm->arch.last_tsc_nsec = ns; kvm->arch.last_tsc_write = tsc; kvm->arch.last_tsc_khz = vcpu->arch.virtual_tsc_khz; + kvm->arch.last_tsc_offset = offset; vcpu->arch.last_guest_tsc = tsc; @@ -4924,6 +4925,109 @@ static int kvm_set_guest_paused(struct kvm_vcpu *vcpu) return 0; } +static int kvm_arch_tsc_has_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + int r; + + switch (attr->attr) { + case KVM_VCPU_TSC_OFFSET: + r = 0; + break; + default: + r = -ENXIO; + } + + return r; +} + +static int kvm_arch_tsc_get_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + u64 __user *uaddr = (u64 __user *)attr->addr; + int r; + + switch (attr->attr) { + case KVM_VCPU_TSC_OFFSET: + r = -EFAULT; + if (put_user(vcpu->arch.l1_tsc_offset, uaddr)) + break; + r = 0; + break; + default: + r = -ENXIO; + } + + return r; +} + +static int kvm_arch_tsc_set_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + u64 __user *uaddr = (u64 __user *)attr->addr; + struct kvm *kvm = vcpu->kvm; + int r; + + switch (attr->attr) { + case KVM_VCPU_TSC_OFFSET: { + u64 offset, tsc, ns; + unsigned long flags; + bool matched; + + r = -EFAULT; + if (get_user(offset, uaddr)) + break; + + raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags); + + matched = (vcpu->arch.virtual_tsc_khz && + kvm->arch.last_tsc_khz == vcpu->arch.virtual_tsc_khz && + kvm->arch.last_tsc_offset == offset); + + tsc = kvm_scale_tsc(vcpu, rdtsc(), vcpu->arch.l1_tsc_scaling_ratio) + offset; + ns = get_kvmclock_base_ns(); + + __kvm_synchronize_tsc(vcpu, offset, tsc, ns, matched); + raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags); + + r = 0; + break; + } + default: + r = -ENXIO; + } + + return r; +} + +static int kvm_vcpu_ioctl_device_attr(struct kvm_vcpu *vcpu, + unsigned int ioctl, + void __user *argp) +{ + struct kvm_device_attr attr; + int r; + + if (copy_from_user(&attr, argp, sizeof(attr))) + return -EFAULT; + + if (attr.group != KVM_VCPU_TSC_CTRL) + return -ENXIO; + + switch (ioctl) { + case KVM_HAS_DEVICE_ATTR: + r = kvm_arch_tsc_has_attr(vcpu, &attr); + break; + case KVM_GET_DEVICE_ATTR: + r = kvm_arch_tsc_get_attr(vcpu, &attr); + break; + case KVM_SET_DEVICE_ATTR: + r = kvm_arch_tsc_set_attr(vcpu, &attr); + break; + } + + return r; +} + static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, struct kvm_enable_cap *cap) { @@ -5378,6 +5482,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = __set_sregs2(vcpu, u.sregs2); break; } + case KVM_HAS_DEVICE_ATTR: + case KVM_GET_DEVICE_ATTR: + case KVM_SET_DEVICE_ATTR: + r = kvm_vcpu_ioctl_device_attr(vcpu, ioctl, argp); + break; default: r = -EINVAL; } From patchwork Wed Aug 4 08:58:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418171 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 ACC43C4338F for ; Wed, 4 Aug 2021 09:01:45 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7C02B60E52 for ; Wed, 4 Aug 2021 09:01:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7C02B60E52 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=w3mK2Rr1E1TCjd/LOUsOugfIo06kF+WM5BMQ+J77Xao=; b=jiLatM46BUNtQZ7bv/ifp+zyIc Xdq/qKY7+X9a4II9K791wlgNwuoYWKRd10eAe/lKEJtCI7mf7sFscpODehWy5Uq3GS5oWRNIpJqYq bkIwRZh3ncwDP85MNlnV0wzssktPw2nFipxZ0h9OUCNQq7HCq31gBBrjJa6kMxzEm0DG8sNzjfTvE 5lWFL8qsmCgyacx98vez6xMh7YBwlMPvMUvLm5Mtq8g8BKuMATTlyzO9bnlxURoJT40qjBqrmQhZ9 G+h+0PcZVnro5qmYlB3THi08/Pgx/a0rguy9MxwMlacbmSAMShvt0CcTZRI0VxQhcyj2pounac1qS gbRZT/2g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCkr-005Fys-LM; Wed, 04 Aug 2021 09:00:02 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjb-005FZN-A3 for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:44 +0000 Received: by mail-yb1-xb49.google.com with SMTP id x5-20020a0569020505b0290592c25b8c59so2200549ybs.18 for ; Wed, 04 Aug 2021 01:58: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=QZYUzbcXutG2B1XPKYDDaowrOTkrdRCYpxjQmfgRBqw=; b=fg8ZdJyTO1IzZwQnyFmtQzBLyvzLg3oWs5Mwrvzrq7RU1rdysfWLN2A/CA6201R02a 9x/yYSHRuUETBU088OpH41tdmTezHXghlym7jalL4hNQj9khOjSNah3nmR20olJYlpGM NL9UDv3ftB1FzNYvmaswYPXp0iJ0GOb9T8RcGftr9OzVhNA3piITvnnmbrvRoEKYaUs3 TAbiN9VHBzEih5yBmaD0TSgq4w33jIlobvj6FE10tdMiUbNXovPf3cPu5j0dQjIYAP24 xcRWGMUyhFLsg7YJPN15v+gKZLMR1hpOHVLDuC1OOWN4vglBYkL+5BSD3FbMNsMZGkwn KpMw== 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=QZYUzbcXutG2B1XPKYDDaowrOTkrdRCYpxjQmfgRBqw=; b=pJLEopkQXmt4gkIT897CWs482l1hA8mhevZmkIGOTau7k6RCUu++zfFp3iQ9j2e0Dd wLrFQOfJ4UvbNXbRcIMEU5oFyW0uZOFKX4hwlwodcV2qfkiFqtLdHnu5a4rSxgZ8vCJN cQBniA8V3lwHezE3kkx3TCYNZcxroQnXLvb3dQkRvkVNJ7BJZHrWBUm+E6+hDNzBoQwq N7MOwpS8bOTz49w8EEyLzi2Mlwlp/+ZsdbRYMVVd6ibhnnBDr17cLJkDryoW2xDXqmUL 5zXVaMPd70eAbro3wHDdZtofiYOBOwNWf1CKm/T3HE5mSmS0Ux0p3ElhZQnjYiRYlPPI MuFg== X-Gm-Message-State: AOAM532BPg1UyFyNjlsjD4T1quNvSySYn2YnzZKCO982A16qe5hPwUEo rEhlA6/94dtbNHVhFBqTXTmSdLLUi1A= X-Google-Smtp-Source: ABdhPJxV6+3gLGbTheDt4LD8pHoTTfHfR6GcLwPPsqBvh7B9FGBWOPkR9xVf9DHE0p02LBy+6d+tyicSFeI= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a25:4283:: with SMTP id p125mr35878914yba.184.1628067521137; Wed, 04 Aug 2021 01:58:41 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:04 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-7-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 06/21] tools: arch: x86: pull in pvclock headers From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015843_405145_FD42997E X-CRM114-Status: GOOD ( 21.55 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Copy over approximately clean versions of the pvclock headers into tools. Reconcile headers/symbols missing in tools that are unneeded. Signed-off-by: Oliver Upton --- tools/arch/x86/include/asm/pvclock-abi.h | 48 +++++++++++ tools/arch/x86/include/asm/pvclock.h | 103 +++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 tools/arch/x86/include/asm/pvclock-abi.h create mode 100644 tools/arch/x86/include/asm/pvclock.h diff --git a/tools/arch/x86/include/asm/pvclock-abi.h b/tools/arch/x86/include/asm/pvclock-abi.h new file mode 100644 index 000000000000..1436226efe3e --- /dev/null +++ b/tools/arch/x86/include/asm/pvclock-abi.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_PVCLOCK_ABI_H +#define _ASM_X86_PVCLOCK_ABI_H +#ifndef __ASSEMBLY__ + +/* + * These structs MUST NOT be changed. + * They are the ABI between hypervisor and guest OS. + * Both Xen and KVM are using this. + * + * pvclock_vcpu_time_info holds the system time and the tsc timestamp + * of the last update. So the guest can use the tsc delta to get a + * more precise system time. There is one per virtual cpu. + * + * pvclock_wall_clock references the point in time when the system + * time was zero (usually boot time), thus the guest calculates the + * current wall clock by adding the system time. + * + * Protocol for the "version" fields is: hypervisor raises it (making + * it uneven) before it starts updating the fields and raises it again + * (making it even) when it is done. Thus the guest can make sure the + * time values it got are consistent by checking the version before + * and after reading them. + */ + +struct pvclock_vcpu_time_info { + u32 version; + u32 pad0; + u64 tsc_timestamp; + u64 system_time; + u32 tsc_to_system_mul; + s8 tsc_shift; + u8 flags; + u8 pad[2]; +} __attribute__((__packed__)); /* 32 bytes */ + +struct pvclock_wall_clock { + u32 version; + u32 sec; + u32 nsec; +} __attribute__((__packed__)); + +#define PVCLOCK_TSC_STABLE_BIT (1 << 0) +#define PVCLOCK_GUEST_STOPPED (1 << 1) +/* PVCLOCK_COUNTS_FROM_ZERO broke ABI and can't be used anymore. */ +#define PVCLOCK_COUNTS_FROM_ZERO (1 << 2) +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_X86_PVCLOCK_ABI_H */ diff --git a/tools/arch/x86/include/asm/pvclock.h b/tools/arch/x86/include/asm/pvclock.h new file mode 100644 index 000000000000..2628f9a6330b --- /dev/null +++ b/tools/arch/x86/include/asm/pvclock.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_PVCLOCK_H +#define _ASM_X86_PVCLOCK_H + +#include +#include + +/* some helper functions for xen and kvm pv clock sources */ +u64 pvclock_clocksource_read(struct pvclock_vcpu_time_info *src); +u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src); +void pvclock_set_flags(u8 flags); +unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src); +void pvclock_resume(void); + +void pvclock_touch_watchdogs(void); + +static __always_inline +unsigned pvclock_read_begin(const struct pvclock_vcpu_time_info *src) +{ + unsigned version = src->version & ~1; + /* Make sure that the version is read before the data. */ + rmb(); + return version; +} + +static __always_inline +bool pvclock_read_retry(const struct pvclock_vcpu_time_info *src, + unsigned version) +{ + /* Make sure that the version is re-read after the data. */ + rmb(); + return version != src->version; +} + +/* + * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, + * yielding a 64-bit result. + */ +static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift) +{ + u64 product; +#ifdef __i386__ + u32 tmp1, tmp2; +#else + unsigned long tmp; +#endif + + if (shift < 0) + delta >>= -shift; + else + delta <<= shift; + +#ifdef __i386__ + __asm__ ( + "mul %5 ; " + "mov %4,%%eax ; " + "mov %%edx,%4 ; " + "mul %5 ; " + "xor %5,%5 ; " + "add %4,%%eax ; " + "adc %5,%%edx ; " + : "=A" (product), "=r" (tmp1), "=r" (tmp2) + : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); +#elif defined(__x86_64__) + __asm__ ( + "mulq %[mul_frac] ; shrd $32, %[hi], %[lo]" + : [lo]"=a"(product), + [hi]"=d"(tmp) + : "0"(delta), + [mul_frac]"rm"((u64)mul_frac)); +#else +#error implement me! +#endif + + return product; +} + +static __always_inline +u64 __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src, u64 tsc) +{ + u64 delta = tsc - src->tsc_timestamp; + u64 offset = pvclock_scale_delta(delta, src->tsc_to_system_mul, + src->tsc_shift); + return src->system_time + offset; +} + +struct pvclock_vsyscall_time_info { + struct pvclock_vcpu_time_info pvti; +} __attribute__((__aligned__(64))); + +#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info) + +#ifdef CONFIG_PARAVIRT_CLOCK +void pvclock_set_pvti_cpu0_va(struct pvclock_vsyscall_time_info *pvti); +struct pvclock_vsyscall_time_info *pvclock_get_pvti_cpu0_va(void); +#else +static inline struct pvclock_vsyscall_time_info *pvclock_get_pvti_cpu0_va(void) +{ + return NULL; +} +#endif + +#endif /* _ASM_X86_PVCLOCK_H */ From patchwork Wed Aug 4 08:58:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418173 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=-14.6 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 790C8C4338F for ; Wed, 4 Aug 2021 09:02:08 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 48D8360E52 for ; Wed, 4 Aug 2021 09:02:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 48D8360E52 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=G75kTzLfN2n9NsAJQkuRZbT5ADX9bPhZ4UDwFDIPVho=; b=wPB3o07NZWnL2+Ps7Ptfjw/2Lk CNYooq6eXTLI2w9kF3f6aj3nSX8lPvXEc/8FTlEt86uE71MTBlBWj+6k62eE03V6BWsTetEeBS6+5 JOXX3oCQrC0Y9MELLN5Ro2wSgHfy1ZrEAgks7VsIMgs7mq758sfAMRZcSxHK2ZrjQAjVswVI0EZH/ igyNel1XRe+3QbwmitmIDXPn97TJfZr2yP9p92MtbtUNJk4vmhCHjCyF7Be7LdfrmohTz2S8po52t M2MMWChWMwp54t6Fqi1ziDOtH8/xKdR+Z+cS8bpJZ7djMRgXyimiB4eL5m6MKKennOcxL1Pl0XzZu qApFHrMg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCl9-005G7N-GT; Wed, 04 Aug 2021 09:00:20 +0000 Received: from mail-il1-x14a.google.com ([2607:f8b0:4864:20::14a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjb-005FZk-Ir for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:45 +0000 Received: by mail-il1-x14a.google.com with SMTP id l14-20020a056e0205ceb02901f2f7ba704aso601368ils.20 for ; Wed, 04 Aug 2021 01:58:42 -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=fWcniuNXCUCuPv57yCdSEdrKkifvC8A89oeC6WgOzN8=; b=a9oOAkp4mvbQXissCbYue355AXwUJT0HyqVBhuZt9Uq2Oyi8tVlNMo/c/bZSF5LyrW mHB4/6yIVqensNawvm9tyvWFjoT+YkB0Tvb7Mic09FxwsneEGvLKtmQWfbfkfGC0NN00 +WBONgVMZ7jhm2uwJuAkeDE9h/2mo/bjkfi9kt5ci3bceCDwhMnxiujgpDx34DfOPk8z +H6PUQQa+YSiUjG18yfhsQw3IWbzPPu4m4POcWBtJFo9mgA6yxSEgZpi3jhcqfRxVb9y B6z69N+o/U5y7TGF/p0TcAP9yTuhdp69m0eQKJbQ91Ap69SkvekfHzoR6FVEoxXf0+LF Ov8w== 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=fWcniuNXCUCuPv57yCdSEdrKkifvC8A89oeC6WgOzN8=; b=S7aKdxIlfjoAj9TaMzTBx4L4bYEW9MM1DP09AxpKogLj70rYkLg7DSJ7aG0XzYYbUf piwm9U815hTpbap0KZviqbNitj8acfy9FWRuDZFixM2k45nOBGaEfVANjqPUvhqQD6o1 kzqw7CHMvaO+TqHKE8iehqHWJcMiFggIFxPlOCsbpbo5ltj4PvV16oL+wuwjpOFyfZJP sKbDGRpBuwdJODkSiZb5Mvqu51T1lf6yPgdC/FT7+NA52uKZo/W0IGRKPLa8eujyCkcX GivfCzP8Wd6pdUGjUDQ9uxpFmcdefM7dKk/0dLzHMcqpAxdbTGjbyTVVdVvAUZH835ND TA6g== X-Gm-Message-State: AOAM532EXH2j+WZ2aE6pl55WHt55TfaE2WnYpR933o+qD9MHyw02+Bcq QXTVAtb4nqZaZul2CniIIf+iAd3E9WQ= X-Google-Smtp-Source: ABdhPJyAyc/dU3nSEvjNvxPG8j4g40KIoOuCzRMMt1RHb+qZXYIlBxONKqT8lMuEOfBkT/Z+tisIzU18bGY= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a5d:9808:: with SMTP id a8mr135685iol.1.1628067522287; Wed, 04 Aug 2021 01:58:42 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:05 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-8-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 07/21] selftests: KVM: Add test for KVM_{GET,SET}_CLOCK From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015843_675604_59CD4261 X-CRM114-Status: GOOD ( 23.10 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a selftest for the new KVM clock UAPI that was introduced. Ensure that the KVM clock is consistent between userspace and the guest, and that the difference in realtime will only ever cause the KVM clock to advance forward. Cc: Andrew Jones Signed-off-by: Oliver Upton --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../testing/selftests/kvm/include/kvm_util.h | 2 + .../selftests/kvm/x86_64/kvm_clock_test.c | 204 ++++++++++++++++++ 4 files changed, 208 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_clock_test.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index 36896d251977..958a809c8de4 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -11,6 +11,7 @@ /x86_64/emulator_error_test /x86_64/get_cpuid_test /x86_64/get_msr_index_features +/x86_64/kvm_clock_test /x86_64/kvm_pv_test /x86_64/hyperv_clock /x86_64/hyperv_cpuid diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index c103873531e0..0f94b18b33ce 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -46,6 +46,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/get_cpuid_test TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features +TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test TEST_GEN_PROGS_x86_64 += x86_64/mmio_warning_test TEST_GEN_PROGS_x86_64 += x86_64/mmu_role_test diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 010b59b13917..a8ac5d52e17b 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -19,6 +19,8 @@ #define KVM_DEV_PATH "/dev/kvm" #define KVM_MAX_VCPUS 512 +#define NSEC_PER_SEC 1000000000L + /* * Callers of kvm_util only have an incomplete/opaque description of the * structure kvm_util is using to maintain the state of a VM. diff --git a/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c b/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c new file mode 100644 index 000000000000..e0dcc27ae9f1 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021, Google LLC. + * + * Tests for adjusting the KVM clock from userspace + */ +#include +#include +#include +#include +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" + +#define VCPU_ID 0 + +struct test_case { + uint64_t kvmclock_base; + int64_t realtime_offset; +}; + +static struct test_case test_cases[] = { + { .kvmclock_base = 0 }, + { .kvmclock_base = 180 * NSEC_PER_SEC }, + { .kvmclock_base = 0, .realtime_offset = -180 * NSEC_PER_SEC }, + { .kvmclock_base = 0, .realtime_offset = 180 * NSEC_PER_SEC }, +}; + +#define GUEST_SYNC_CLOCK(__stage, __val) \ + GUEST_SYNC_ARGS(__stage, __val, 0, 0, 0) + +static void guest_main(vm_paddr_t pvti_pa, struct pvclock_vcpu_time_info *pvti) +{ + int i; + + wrmsr(MSR_KVM_SYSTEM_TIME_NEW, pvti_pa | KVM_MSR_ENABLED); + for (i = 0; i < ARRAY_SIZE(test_cases); i++) + GUEST_SYNC_CLOCK(i, __pvclock_read_cycles(pvti, rdtsc())); +} + +#define EXPECTED_FLAGS (KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC) + +static inline void assert_flags(struct kvm_clock_data *data) +{ + TEST_ASSERT((data->flags & EXPECTED_FLAGS) == EXPECTED_FLAGS, + "unexpected clock data flags: %x (want set: %x)", + data->flags, EXPECTED_FLAGS); +} + +static void handle_sync(struct ucall *uc, struct kvm_clock_data *start, + struct kvm_clock_data *end) +{ + uint64_t obs, exp_lo, exp_hi; + + obs = uc->args[2]; + exp_lo = start->clock; + exp_hi = end->clock; + + assert_flags(start); + assert_flags(end); + + TEST_ASSERT(exp_lo <= obs && obs <= exp_hi, + "unexpected kvm-clock value: %"PRIu64" expected range: [%"PRIu64", %"PRIu64"]", + obs, exp_lo, exp_hi); + + pr_info("kvm-clock value: %"PRIu64" expected range [%"PRIu64", %"PRIu64"]\n", + obs, exp_lo, exp_hi); +} + +static void handle_abort(struct ucall *uc) +{ + TEST_FAIL("%s at %s:%ld", (const char *)uc->args[0], + __FILE__, uc->args[1]); +} + +static void setup_clock(struct kvm_vm *vm, struct test_case *test_case) +{ + struct kvm_clock_data data; + + memset(&data, 0, sizeof(data)); + + data.clock = test_case->kvmclock_base; + if (test_case->realtime_offset) { + struct timespec ts; + int r; + + data.flags |= KVM_CLOCK_REALTIME; + do { + r = clock_gettime(CLOCK_REALTIME, &ts); + if (!r) + break; + } while (errno == EINTR); + + TEST_ASSERT(!r, "clock_gettime() failed: %d\n", r); + + data.realtime = ts.tv_sec * NSEC_PER_SEC; + data.realtime += ts.tv_nsec; + data.realtime += test_case->realtime_offset; + } + + vm_ioctl(vm, KVM_SET_CLOCK, &data); +} + +static void enter_guest(struct kvm_vm *vm) +{ + struct kvm_clock_data start, end; + struct kvm_run *run; + struct ucall uc; + int i, r; + + run = vcpu_state(vm, VCPU_ID); + + for (i = 0; i < ARRAY_SIZE(test_cases); i++) { + setup_clock(vm, &test_cases[i]); + + vm_ioctl(vm, KVM_GET_CLOCK, &start); + + r = _vcpu_run(vm, VCPU_ID); + vm_ioctl(vm, KVM_GET_CLOCK, &end); + + TEST_ASSERT(!r, "vcpu_run failed: %d\n", r); + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, + "unexpected exit reason: %u (%s)", + run->exit_reason, exit_reason_str(run->exit_reason)); + + switch (get_ucall(vm, VCPU_ID, &uc)) { + case UCALL_SYNC: + handle_sync(&uc, &start, &end); + break; + case UCALL_ABORT: + handle_abort(&uc); + return; + default: + TEST_ASSERT(0, "unhandled ucall: %ld\n", + get_ucall(vm, VCPU_ID, &uc)); + } + } +} + +#define CLOCKSOURCE_PATH "/sys/devices/system/clocksource/clocksource0/current_clocksource" + +static void check_clocksource(void) +{ + char *clk_name; + struct stat st; + FILE *fp; + + fp = fopen(CLOCKSOURCE_PATH, "r"); + if (!fp) { + pr_info("failed to open clocksource file: %d; assuming TSC.\n", + errno); + return; + } + + if (fstat(fileno(fp), &st)) { + pr_info("failed to stat clocksource file: %d; assuming TSC.\n", + errno); + goto out; + } + + clk_name = malloc(st.st_size); + TEST_ASSERT(clk_name, "failed to allocate buffer to read file\n"); + + if (!fgets(clk_name, st.st_size, fp)) { + pr_info("failed to read clocksource file: %d; assuming TSC.\n", + ferror(fp)); + goto out; + } + + TEST_ASSERT(!strncmp(clk_name, "tsc\n", st.st_size), + "clocksource not supported: %s", clk_name); +out: + fclose(fp); +} + +int main(void) +{ + vm_vaddr_t pvti_gva; + vm_paddr_t pvti_gpa; + struct kvm_vm *vm; + int flags; + + flags = kvm_check_cap(KVM_CAP_ADJUST_CLOCK); + if (!(flags & KVM_CLOCK_REALTIME)) { + print_skip("KVM_CLOCK_REALTIME not supported; flags: %x", + flags); + exit(KSFT_SKIP); + } + + check_clocksource(); + + vm = vm_create_default(VCPU_ID, 0, guest_main); + + pvti_gva = vm_vaddr_alloc(vm, getpagesize(), 0x10000); + pvti_gpa = addr_gva2gpa(vm, pvti_gva); + vcpu_args_set(vm, VCPU_ID, 2, pvti_gpa, pvti_gva); + + enter_guest(vm); + kvm_vm_free(vm); +} From patchwork Wed Aug 4 08:58:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418175 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT 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 E7596C4338F for ; Wed, 4 Aug 2021 09:02:53 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AC71760EE9 for ; Wed, 4 Aug 2021 09:02:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org AC71760EE9 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=LDF7ILVURAF4IVXc3ntq6sFfet3DMLTjMsVjy0+9zZM=; b=DHYfCy+xtO2qPXMGG6v8JwoBg9 6V4uNcH1oQdd8ddEl4SVTwanS9gWEIN+NiSwB9Lnwj6W8QMWIuv2ZntJh+EmSq0iluClkJAMdz/ha c2+ko/aaWv10IYNVh4grD3F0Riq20XNpzkt1YtPAEbcjdABMtIMZEKoeBBZRL4SF/Uz1WLYU6QYwX Z9KK+UKhnMZhaMo9e61ecboLoZNis3kxhgAZkIo43f+XkYkGsmqBEtbaNtQkTccdYucy9coZGa7/l uZGVChbJsNBDV54OEhVQzYYdyRwTuF3pUUm5zgVEAXEaDEmV6TPmq2GuOdMrlFn7vZKDAy+FFWXkg a9hazRqQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBClo-005GSn-Pn; Wed, 04 Aug 2021 09:01:03 +0000 Received: from mail-ot1-x349.google.com ([2607:f8b0:4864:20::349]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjd-005FaO-Io for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:46 +0000 Received: by mail-ot1-x349.google.com with SMTP id z96-20020a9d24e90000b02902a57e382ca1so514696ota.7 for ; Wed, 04 Aug 2021 01:58:44 -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=gCg0AznWgA4f1SrJgUwp//MIUEfrq8bP1cnOz9mraho=; b=MTCyPCTw0RZ+dPZ2ozrA+5wli9Ay+UMDLegw4vajpPfpUxDPSiKLc0KjPDr4t1VbV+ J5VC+2D7LilUe7K9hJUgzZnIgERsJnXnBOOJYtyh6k6G9qjp7rB8PeWklTOaYdZpRZBf Adib//0K6WdMcr9nPQKZ/DWsF8taEaq+gazsww/VYX1ooxIuECdYs3LHF/RsUdd5IJOD XsBqzD2xkkZt2+J8vZhLXIt8kNwajcSPkONGtG2CEIG2seo6FgP/ztuUH/GpEm5NJjZA C8Buw2XEUbP1aCptyDiqWmQAmJ9h3TUzJU2weTZs6VSF8YzfckKutAH1jJXm2v8olilU PR3A== 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=gCg0AznWgA4f1SrJgUwp//MIUEfrq8bP1cnOz9mraho=; b=nojTnypBpA0c3yvmgVbuAaydngUTj+LnBbKwJgsbb1cogcIz95hC2nZ5/YLjm7weIF 9EN0tEV/gPY25rmzqwObzh9vo8s2ot2bvkkdJfk34qwaJR2GpFlvKtLOsuvz3jJnMZFe m5bRbqTitiTyTFH5q/FxlTEdueaH/njHM6Oi32jV62DrjPb8jbnw36axTttQynhQsIi8 xFf79kRVPvYc+1Bbixvb+TARKfq4zKWUGHLAwBUkGYIIo2yBfpi+yNJ2yw8MOAf5V45T XNl/EfEqLndI1rEN80WowA9nuKx+Zlfb+Sp0bQSXXtmx3RVHBIQSbMj0N0i7NBqsnXWW jG7Q== X-Gm-Message-State: AOAM531BgvDkG7JtzC+6Cm6I/4k4s5/nCkZgJVMTKChTT7xkCKcj7xgc hAW8yW2mv/WZO9q0zeypt1pDCR1MGxs= X-Google-Smtp-Source: ABdhPJyrF6Z/oAvVMCwq6Zwnl1O8bPPs3vKcjVomi62Qv2JKaBWWKXDpL2ITIDF27NgJQLbzg5F4wv4SoZ4= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a05:6808:68d:: with SMTP id k13mr17591632oig.83.1628067523355; Wed, 04 Aug 2021 01:58:43 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:06 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-9-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 08/21] selftests: KVM: Fix kvm device helper ioctl assertions From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015845_692961_A1D7BC16 X-CRM114-Status: GOOD ( 12.13 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The KVM_CREATE_DEVICE and KVM_{GET,SET}_DEVICE_ATTR ioctls are defined to return a value of zero on success. As such, tighten the assertions in the helper functions to only pass if the return code is zero. Suggested-by: Andrew Jones Reviewed-by: Andrew Jones Signed-off-by: Oliver Upton --- tools/testing/selftests/kvm/lib/kvm_util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 10a8ed691c66..0ffc2d39c80d 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1984,7 +1984,7 @@ int kvm_device_check_attr(int dev_fd, uint32_t group, uint64_t attr) { int ret = _kvm_device_check_attr(dev_fd, group, attr); - TEST_ASSERT(ret >= 0, "KVM_HAS_DEVICE_ATTR failed, rc: %i errno: %i", ret, errno); + TEST_ASSERT(!ret, "KVM_HAS_DEVICE_ATTR failed, rc: %i errno: %i", ret, errno); return ret; } @@ -2008,7 +2008,7 @@ int kvm_create_device(struct kvm_vm *vm, uint64_t type, bool test) ret = _kvm_create_device(vm, type, test, &fd); if (!test) { - TEST_ASSERT(ret >= 0, + TEST_ASSERT(!ret, "KVM_CREATE_DEVICE IOCTL failed, rc: %i errno: %i", ret, errno); return fd; } @@ -2036,7 +2036,7 @@ int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr, { int ret = _kvm_device_access(dev_fd, group, attr, val, write); - TEST_ASSERT(ret >= 0, "KVM_SET|GET_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno); + TEST_ASSERT(!ret, "KVM_SET|GET_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno); return ret; } From patchwork Wed Aug 4 08:58:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418177 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 B4E8BC4338F for ; Wed, 4 Aug 2021 09:03:55 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 73AE460E52 for ; Wed, 4 Aug 2021 09:03:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 73AE460E52 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=G7VnMzOg8kXNMlyAZq1mrr/olNttACjRxaPV3nvcSWI=; b=QKyQy67H1YOGEVQgTqtzDcLygK 40Tl3Byl88a1hJR6MEe619alW5jSax/jLeknDHGb1fak2o0Ki2uvIV0IwqiDr0WRip5TCrOYMkKxy qx5izSirDkKyKl4TZypnbNQuMdklc5XAKha8P4jXa53dFo9+KlXgQ2u0ccQhJxMWhAuSgjMLZHta3 jfAFKk3c9+RW1XY8/2IpJGpR3q6Yt7uJ1WMMeXkoXbQD1WCo+iUWpmxc22yxllrUr5lntCHOrxgvg J5smyt4+smg9GPdSTdFKvwdsuuEWGxJk5giL6QnnQw//LZ3Bntk8eu14/7j7qRyN55GhTgFNlzOx1 K7eQUQsg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCmW-005Gqm-It; Wed, 04 Aug 2021 09:01:44 +0000 Received: from mail-il1-x14a.google.com ([2607:f8b0:4864:20::14a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjd-005Fag-R1 for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:47 +0000 Received: by mail-il1-x14a.google.com with SMTP id d6-20020a056e020506b0290208fe58bd16so643471ils.0 for ; Wed, 04 Aug 2021 01:58:45 -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=2gjqXaybcfhGsEx7zzFhczi+7waNRcsT2EekTwdua3g=; b=mV3bavEsQJeFXoUN6afZIex4P+pbiEQskKr9ssIEpwxYxDVbr44+z5lsJsI++Z/9Eq KeBYAqy8laLfZxljKzYQhBLHzT6bqtxYdHktSuVRjDa5Gtqs4iAqWXpfdIpAy1KXSun4 gqNKIV1hLNTLPBmE9EtHKMmmZHP9aWDOkxcA/VE7YzVuVw3idutZtbZD6+c0QLCQN1H/ WTZV0519PCAPuQI5oN6Yhk1r2JrU/cSC6/FfKZYANGe19iGPgRK8igSbV3Do7eoWVteQ gweezT4+LUU7GWjD02ej83+efT++D1RXYMUsW8G2eiB3aMOuJUHJ8KDDFJIHK56sKCZA ShCg== 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=2gjqXaybcfhGsEx7zzFhczi+7waNRcsT2EekTwdua3g=; b=LBISrUyFEMELofUNGQp/ikgPjFI7MkCNg49bJfK3JU8ymICI37SUcSjIiOW8Cj7Lar txIenEb799bxJyGjN09u0YkcQ4VflXTfdUuMPApiEeHQLiM4EM+UHphWbfN6nJGjrp4X m1JOIt/bop/QeHZ8KuImWYfA7vZkOHNRtcgRoAAcWGjL1BmZS+HU1y8VYw2Qu9ZGvNig zQ9BHj2dbxm7ehLT24YLV7rPiXrua7G6jzbgbLpmf+10+JMJWGp5n8VkD3mHGUIlbiyq 4hQucPEj+fShDphRG9zEKZ8+VEcJbH2Y/v05DgGj+ZMlB9xCPboAT2No9Z0M7RWLrwrR N3NA== X-Gm-Message-State: AOAM532LzP+njvaiIHvUeYpIEMnuOqEhI7QFJ+T/rT0+8/BrJX/mECsr YkAx4wbqE/x9TTtK9T1K8Zqr6lTSVnU= X-Google-Smtp-Source: ABdhPJycrlSIwAp+3SfcqVpiRRWeZMq52Xk/yfwClIcOtkMb1s3+t/Zxk/Hhj0Y7XyAdi6gYQ6pBF51nN/o= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a02:9385:: with SMTP id z5mr1643218jah.95.1628067524697; Wed, 04 Aug 2021 01:58:44 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:07 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-10-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 09/21] selftests: KVM: Add helpers for vCPU device attributes From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015845_922422_2A9A645F X-CRM114-Status: GOOD ( 10.15 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org vCPU file descriptors are abstracted away from test code in KVM selftests, meaning that tests cannot directly access a vCPU's device attributes. Add helpers that tests can use to get at vCPU device attributes. Reviewed-by: Andrew Jones Signed-off-by: Oliver Upton --- .../testing/selftests/kvm/include/kvm_util.h | 9 +++++ tools/testing/selftests/kvm/lib/kvm_util.c | 38 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index a8ac5d52e17b..1b3ef5757819 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -240,6 +240,15 @@ int _kvm_device_access(int dev_fd, uint32_t group, uint64_t attr, int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr, void *val, bool write); +int _vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, + uint64_t attr); +int vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, + uint64_t attr); +int _vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, + uint64_t attr, void *val, bool write); +int vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, + uint64_t attr, void *val, bool write); + const char *exit_reason_str(unsigned int exit_reason); void virt_pgd_alloc(struct kvm_vm *vm); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 0ffc2d39c80d..0fe66ca6139a 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2040,6 +2040,44 @@ int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr, return ret; } +int _vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, + uint64_t attr) +{ + struct vcpu *vcpu = vcpu_find(vm, vcpuid); + + TEST_ASSERT(vcpu, "nonexistent vcpu id: %d", vcpuid); + + return _kvm_device_check_attr(vcpu->fd, group, attr); +} + +int vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, + uint64_t attr) +{ + int ret = _vcpu_has_device_attr(vm, vcpuid, group, attr); + + TEST_ASSERT(!ret, "KVM_HAS_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno); + return ret; +} + +int _vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, + uint64_t attr, void *val, bool write) +{ + struct vcpu *vcpu = vcpu_find(vm, vcpuid); + + TEST_ASSERT(vcpu, "nonexistent vcpu id: %d", vcpuid); + + return _kvm_device_access(vcpu->fd, group, attr, val, write); +} + +int vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, + uint64_t attr, void *val, bool write) +{ + int ret = _vcpu_access_device_attr(vm, vcpuid, group, attr, val, write); + + TEST_ASSERT(!ret, "KVM_SET|GET_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno); + return ret; +} + /* * VM Dump * From patchwork Wed Aug 4 08:58:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418179 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=-14.6 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 2C596C4338F for ; Wed, 4 Aug 2021 09:04:48 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EDBA560EE9 for ; Wed, 4 Aug 2021 09:04:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org EDBA560EE9 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=ZcmSxIcdWiizGO3priTsj0GHWRbldjgYGo+f6S+3WfM=; b=4TOrKWedX/Y3pGixLM6GOHwsxe Y2i/CWJTjtb7jbErNtexEcW3TVW27wIZweOubM4GiCk8hfupinepL1Pg4qd+tyQ0rzmqQx07N44Fa GMg51r2HnT/en5dqi1uuFYByROQtBBu/gfi/IeedRGcQljjXHuS0CtaAWufnnTD39w0fuAPCtu/4U XiFWE+3Yx0WXDwmLFseTrV4/GLiyAunel+7PUv/Sen4TfRCqcOSMGEGI0tHbT3BConfkuGaTqXCCO NP3J+gtfoa+xn6XRtsj0pNXqDf2jBB8HDkRR62HQ7Z2zQlIMdohFPAZxWWHgQqSQtw86DHbPOS2dI zshN4e8w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCnP-005HRC-Q3; Wed, 04 Aug 2021 09:02:40 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjf-005FbI-N3 for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:49 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id x5-20020a0569020505b0290592c25b8c59so2200722ybs.18 for ; Wed, 04 Aug 2021 01:58:46 -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=r41+4YYQSiRGA4d6k0mbGoII8JeQ9p3vNbErRM95pUY=; b=i1JP0767Kq2eMPERgaGvHbggJeZJvodxcSvZQy51OakaKa1Cbqy9xm+/eZdOHxqRmC fFh58lUBru2qfvCl38Gfb2VU/pDLhL4ITdf3Chejofn87Q6F7gqmswLQe0W3Vt2hSMrW StDqS5nb+AnvztxtI4rLhPA74xkiiidKtOVGH0ktlG8aZR1A1D+6MTGzGX7hQBqntekf kjPuEi+qTGrrP1iuuWD1IiSGwXiXiasHuZm5SuWHvrSnWVvB3PXsT5RFMcSUlvOuDllF U80KyR1DLEKtQ+pIyHVzZx/Fo3vjH8n1ZPMl4hKmqntonTmhWFeKx1hW1HoxYaHAQ3Fx 4n8Q== 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=r41+4YYQSiRGA4d6k0mbGoII8JeQ9p3vNbErRM95pUY=; b=itvCLUiLoKYP0xjhs3UatcjZbqIifcsN0kI/b1l2ZlnQiXSTxRLhIVswdO+H7t0tOP 4siKgxZIkCo1JYmEgv8IhasXbkKFzaW2o44NTJfryIOgko8jLqstDn5ckdto5cDiA65w GXr34hqR62h3+i9Ob/Y3F0ubG2yUk8YXLYJI+sr6eEBuZwb4cS0UGPNNp8a+gOOvZeto lwhdXvxx73VrxWXcMABqGqZNpVBA4uEw4BrxT09DsxySKbHmxgBL/BC3kyw7+/PEwsWk Wwaf3AFCdfp+PnyLzKxXeSKecLkK+6I/lhWBp0aBNuwYji5RkqQXni6Kt8mEmN3a0RZ1 1Ahw== X-Gm-Message-State: AOAM5328HS26whx2GSTxbaXqfbu0avPegosjshofrCICrpcWVylMy7XU Nm/YJmC5/JAuoDRGZFGKi5FsEZto8AE= X-Google-Smtp-Source: ABdhPJwYShJd9P6lwbF9fYm94Q4Zq6gEEsSqgevPCyNL1eua0sBPsWceQGemLO1QF+7+t0wmw+wsImgjHFE= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a05:6902:114c:: with SMTP id p12mr35133135ybu.282.1628067525755; Wed, 04 Aug 2021 01:58:45 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:08 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-11-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 10/21] selftests: KVM: Introduce system counter offset test From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015847_806108_1FB57A74 X-CRM114-Status: GOOD ( 18.47 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Introduce a KVM selftest to verify that userspace manipulation of the TSC (via the new vCPU attribute) results in the correct behavior within the guest. Reviewed-by: Andrew Jones Signed-off-by: Oliver Upton --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../kvm/system_counter_offset_test.c | 132 ++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 tools/testing/selftests/kvm/system_counter_offset_test.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index 958a809c8de4..3d2585f0bffc 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -52,3 +52,4 @@ /set_memory_region_test /steal_time /kvm_binary_stats_test +/system_counter_offset_test diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 0f94b18b33ce..9f7060c02668 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -85,6 +85,7 @@ TEST_GEN_PROGS_x86_64 += memslot_perf_test 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_x86_64 += system_counter_offset_test TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c new file mode 100644 index 000000000000..b337bbbfa41f --- /dev/null +++ b/tools/testing/selftests/kvm/system_counter_offset_test.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021, Google LLC. + * + * Tests for adjusting the system counter from userspace + */ +#include +#include +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" + +#define VCPU_ID 0 + +#ifdef __x86_64__ + +struct test_case { + uint64_t tsc_offset; +}; + +static struct test_case test_cases[] = { + { 0 }, + { 180 * NSEC_PER_SEC }, + { -180 * NSEC_PER_SEC }, +}; + +static void check_preconditions(struct kvm_vm *vm) +{ + if (!_vcpu_has_device_attr(vm, VCPU_ID, KVM_VCPU_TSC_CTRL, KVM_VCPU_TSC_OFFSET)) + return; + + print_skip("KVM_VCPU_TSC_OFFSET not supported; skipping test"); + exit(KSFT_SKIP); +} + +static void setup_system_counter(struct kvm_vm *vm, struct test_case *test) +{ + vcpu_access_device_attr(vm, VCPU_ID, KVM_VCPU_TSC_CTRL, + KVM_VCPU_TSC_OFFSET, &test->tsc_offset, true); +} + +static uint64_t guest_read_system_counter(struct test_case *test) +{ + return rdtsc(); +} + +static uint64_t host_read_guest_system_counter(struct test_case *test) +{ + return rdtsc() + test->tsc_offset; +} + +#else /* __x86_64__ */ + +#error test not implemented for this architecture! + +#endif + +#define GUEST_SYNC_CLOCK(__stage, __val) \ + GUEST_SYNC_ARGS(__stage, __val, 0, 0, 0) + +static void guest_main(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(test_cases); i++) { + struct test_case *test = &test_cases[i]; + + GUEST_SYNC_CLOCK(i, guest_read_system_counter(test)); + } +} + +static void handle_sync(struct ucall *uc, uint64_t start, uint64_t end) +{ + uint64_t obs = uc->args[2]; + + TEST_ASSERT(start <= obs && obs <= end, + "unexpected system counter value: %"PRIu64" expected range: [%"PRIu64", %"PRIu64"]", + obs, start, end); + + pr_info("system counter value: %"PRIu64" expected range [%"PRIu64", %"PRIu64"]\n", + obs, start, end); +} + +static void handle_abort(struct ucall *uc) +{ + TEST_FAIL("%s at %s:%ld", (const char *)uc->args[0], + __FILE__, uc->args[1]); +} + +static void enter_guest(struct kvm_vm *vm) +{ + uint64_t start, end; + struct ucall uc; + int i; + + for (i = 0; i < ARRAY_SIZE(test_cases); i++) { + struct test_case *test = &test_cases[i]; + + setup_system_counter(vm, test); + start = host_read_guest_system_counter(test); + vcpu_run(vm, VCPU_ID); + end = host_read_guest_system_counter(test); + + switch (get_ucall(vm, VCPU_ID, &uc)) { + case UCALL_SYNC: + handle_sync(&uc, start, end); + break; + case UCALL_ABORT: + handle_abort(&uc); + return; + default: + TEST_ASSERT(0, "unhandled ucall %ld\n", + get_ucall(vm, VCPU_ID, &uc)); + } + } +} + +int main(void) +{ + struct kvm_vm *vm; + + vm = vm_create_default(VCPU_ID, 0, guest_main); + check_preconditions(vm); + ucall_init(vm, NULL); + + enter_guest(vm); + kvm_vm_free(vm); +} From patchwork Wed Aug 4 08:58:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418181 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT 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 2804DC4338F for ; Wed, 4 Aug 2021 09:05:30 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E331C60E52 for ; Wed, 4 Aug 2021 09:05:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E331C60E52 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=i1MbHymrRhH+sEr0qwUSwGpd6EWk57QMidBkDGQLXAg=; b=2zeB7b376lCZE0eqI6GN/xWVi9 oZw8vtFbDgoWMx9o4FzsXD/9vq/FPxS3Vt2eJIFNqm5CorxSpeMJSTvTjFh1zulKmqdzQbQhFe0Mn Cn1DSqpjkrUEHMFKSmU6rKy6NX+wCHqFjvBJ+0AfoRib/IpUSj5hIQvm3jpWrlpP2In4vtl4uCVYa 8dwmYp82JtYLpiBO1wvA3BT8Hq/x8wJ2PneOd9WdjYrdLqkVeP/RZyqVIEPOlz/QlEgQ+miXoHx+x U6Pd/AmhCT1Et2HFTZ/R7xCPEwhjQetpIwmw+BNu6b3mM0IHmtpLA7G7VfN6RePsjFPeTZRYZYhp+ +Evcrmdw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCo5-005Hst-9W; Wed, 04 Aug 2021 09:03:22 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjg-005FbV-Go for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:49 +0000 Received: by mail-yb1-xb49.google.com with SMTP id w200-20020a25c7d10000b02905585436b530so2196888ybe.21 for ; Wed, 04 Aug 2021 01:58:47 -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=35TVCGaSXP1YX+xl0ynmypPjFUwRXJIFcUTUP7y3OEA=; b=uZnF95SUd8tPNPh9UDFmW/BkibQwuIqjWxF/hBpRgMBadermRtPRVOXDB9dmgoECSE FKyGfmtyrLDrsggccC+Bh3D5G2gELbtHa3uN0XfY5JKG0ECY2NshKN8FbWDsmNi36LEb ctSbdLL+8gkNDC+TlCJ0gt0RNoAPIKSkADIlXB6qQ9GqhxXiuP9bYTOxBYCK/0CJbLyX OMo5Qd7rEVm7l+Vl0r9z9VADsMHVwgRinpxvMjgoANM3sIcdXewmA5o0ijE8KaMaarny i6gAvU3WwVGrOeGLvkW/NqGz11SdqskIEqbf4Vm2r99E0OmmNmyy0TLewqXP11d4sUzL O8HA== 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=35TVCGaSXP1YX+xl0ynmypPjFUwRXJIFcUTUP7y3OEA=; b=WI5KY+ZF/K6KpozhqGFb+w45miKU+6pwKkEBv5nDJ3CpzmWA3aKc8YnZZy0i7jpvJl TynYLTPNUf7wJocShNzyFbl6tHem1prl1biLe9JoYLfsrsLGN0Gx9QGFGFjK7yeCqiNN ZgxOfvzFUIbRssJbKCYYELNmIp8Sly3egSQEnxV7kWiNeH1KnIBZSMnFpXraNp94IV+z ZVAzSo0c36EV9f9OLFv31GtdQwAVJUa041dbG7DqAKi2pM7CsCB2UNijog0dumKzVdGy SapTqkvHXcYPwZ5QXE7cKia+DTWQSfsgikIL6DBB3wN9nDESQOBs2bHm7SzngKaUYQnT juCA== X-Gm-Message-State: AOAM532whrG5buJ7bulpxyjcpkjNtLySE+T5oKLj978bzzRpzJbQfdtm gYcNWXmakSSM751P1xn4TIdFmimdil4= X-Google-Smtp-Source: ABdhPJwQw2VG+2wPW9YYVkLKNHJyZLMCee16q7ggjAFKp03Ugn+6tAxy0sKWEOCLAMhlJGHciviyBhrNI/s= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a25:8010:: with SMTP id m16mr34219421ybk.210.1628067526796; Wed, 04 Aug 2021 01:58:46 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:09 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-12-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 11/21] KVM: arm64: Refactor update_vtimer_cntvoff() From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015848_603920_C3E18B6B X-CRM114-Status: GOOD ( 12.78 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Make the implementation of update_vtimer_cntvoff() generic w.r.t. guest timer context and spin off into a new helper method for later use. Require callers of this new helper method to grab the kvm lock beforehand. No functional change intended. Signed-off-by: Oliver Upton Reviewed-by: Andrew Jones --- arch/arm64/kvm/arch_timer.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 3df67c127489..c0101db75ad4 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -747,22 +747,32 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu) return 0; } -/* Make the updates of cntvoff for all vtimer contexts atomic */ -static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff) +/* Make offset updates for all timer contexts atomic */ +static void update_timer_offset(struct kvm_vcpu *vcpu, + enum kvm_arch_timers timer, u64 offset) { int i; struct kvm *kvm = vcpu->kvm; struct kvm_vcpu *tmp; - mutex_lock(&kvm->lock); + lockdep_assert_held(&kvm->lock); + kvm_for_each_vcpu(i, tmp, kvm) - timer_set_offset(vcpu_vtimer(tmp), cntvoff); + timer_set_offset(vcpu_get_timer(tmp, timer), offset); /* * When called from the vcpu create path, the CPU being created is not * included in the loop above, so we just set it here as well. */ - timer_set_offset(vcpu_vtimer(vcpu), cntvoff); + timer_set_offset(vcpu_get_timer(vcpu, timer), offset); +} + +static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff) +{ + struct kvm *kvm = vcpu->kvm; + + mutex_lock(&kvm->lock); + update_timer_offset(vcpu, TIMER_VTIMER, cntvoff); mutex_unlock(&kvm->lock); } From patchwork Wed Aug 4 08:58:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418183 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 3A6ABC432BE for ; Wed, 4 Aug 2021 09:06:37 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0DDF860240 for ; Wed, 4 Aug 2021 09:06:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 0DDF860240 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=x/eHNmoIbUQAGNc4W5z/BFV3g8wRyNva7KcRxMZJGsU=; b=pdiGcNnf0lAt/biDmhwFpBI+Pp ihEWE/UFRAakK+EUH0UCJiiv4Ylz5NGJC5s4yObeaVANdgHe9SHOyROJscbfIKHiz2q8fiMByz9wo pSX/1lfj1pSmxBajsCGU+jjxjkpx31GF33vS3VNf2SVXH4zGgyYSptGDo0lrCgQx7V6g3xmqXExQQ dGQltu8Lybe/HMJKqkL4vGgvmfOVYdmCqdsa4lAwwObv63uzefVDh2pjSQ/LB3V8AMHv3xt2UMn75 UdnvsDTLMkbdisxDhqgdHxXELjEt+4g4oh7GV2KP25EfQU8xEG5LSfN4clhdKk1XZWBqkXYKcUFWo bLIUoH2w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCoj-005I88-0B; Wed, 04 Aug 2021 09:04:01 +0000 Received: from mail-il1-x14a.google.com ([2607:f8b0:4864:20::14a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjh-005Fbr-Dv for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:50 +0000 Received: by mail-il1-x14a.google.com with SMTP id d9-20020a056e021c49b02902095727d18dso608652ilg.17 for ; Wed, 04 Aug 2021 01:58:48 -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=83fDaIfLsY16yic2+Bpl9lC9hOGkPIV4LchssH1j3LE=; b=SN6GL4hBv6p6nMD4A6e58ghkZoNJfYaNi1MH9O1SIy7AoxXS7cRW68enEg2zIivQkk aZholzalc9xdnfdFzpu9eczDYMKU3+21wWy+fHFgrhF1LmBnspbi1VbEK21vIeTc6TgF rxlaa1A0gISSGbu1UB7PaIEPBWtI6gYPJAV/mOAXQctzT1NMqQZJYYnplqQFgzPN9OjD YtOYVGsAkqQIxCqhX5FD0AOTTtVv8WbFRE/CHjmppQjFKKelImAn2YGU+uu7XY+qyKZr CbnHCJveaEuBZkRFO75LP0K3L/M8CD56y8I6K0CXzIBrVp7Y0gEcqjJiNLCF63KqUPgI uDFA== 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=83fDaIfLsY16yic2+Bpl9lC9hOGkPIV4LchssH1j3LE=; b=lxOM0ay8w2VjHuAUZwLyYQvJLnJ65G3QRMWBkOfeK9cYeMI+tKT+euo4xHsrO4IKip tWaXdbeBZEtaA3tvi1eh16N4el6jO70OhvrVpWdof7P8UV4mKOtbutS37tQbly8KtLMW AdVxbNCJaTH/DSCsj2JApvnGq7fKnQg98jFBWPGHEQGjxb0/FUD08ains1dPFcNONZkV trJEzdERdPnxHT9EIrLX0PKTzmszBU00lRkp8lbsJa7zkPh2vXSw+IPr9YiSD2HZ5Ork Z8T4Yanh8Nr4xcZKDgl8rICYzo3uXjBQE8oQVz+FVss4zGH5fzFSAzGqKiLetvPF+yqI DF4Q== X-Gm-Message-State: AOAM532JBCuEkdZfHVZbUOJq7izOLX+RiaNPk5+C9Ip3Ue4Qe8hVLvUg laMHoRnOeUduBNPE3powxxwPo8Plli0= X-Google-Smtp-Source: ABdhPJzi9q8UGwJAYqkti8laANuUPc3nn5R3eDyiiZDnOVn9vGB1o/QfvD8/gVEEbONDuMag3MzbiMyJaWQ= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a92:5205:: with SMTP id g5mr634503ilb.22.1628067527974; Wed, 04 Aug 2021 01:58:47 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:10 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-13-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 12/21] KVM: arm64: Separate guest/host counter offset values From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015849_536133_5E2C1422 X-CRM114-Status: GOOD ( 17.86 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org In some instances, a VMM may want to update the guest's counter-timer offset in a transparent manner, meaning that changes to the hardware value do not affect the synthetic register presented to the guest or the VMM through said guest's architectural state. Lay the groundwork to separate guest offset register writes from the hardware values utilized by KVM. Signed-off-by: Oliver Upton Reviewed-by: Andrew Jones --- arch/arm64/kvm/arch_timer.c | 48 ++++++++++++++++++++++++++++++++---- include/kvm/arm_arch_timer.h | 3 +++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index c0101db75ad4..4c2b763a8849 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -87,6 +87,18 @@ static u64 timer_get_offset(struct arch_timer_context *ctxt) struct kvm_vcpu *vcpu = ctxt->vcpu; switch(arch_timer_ctx_index(ctxt)) { + case TIMER_VTIMER: + return ctxt->host_offset; + default: + return 0; + } +} + +static u64 timer_get_guest_offset(struct arch_timer_context *ctxt) +{ + struct kvm_vcpu *vcpu = ctxt->vcpu; + + switch (arch_timer_ctx_index(ctxt)) { case TIMER_VTIMER: return __vcpu_sys_reg(vcpu, CNTVOFF_EL2); default: @@ -132,13 +144,31 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset) switch(arch_timer_ctx_index(ctxt)) { case TIMER_VTIMER: - __vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset; + ctxt->host_offset = offset; break; default: WARN(offset, "timer %ld\n", arch_timer_ctx_index(ctxt)); } } +static void timer_set_guest_offset(struct arch_timer_context *ctxt, u64 offset) +{ + struct kvm_vcpu *vcpu = ctxt->vcpu; + + switch (arch_timer_ctx_index(ctxt)) { + case TIMER_VTIMER: { + u64 host_offset = timer_get_offset(ctxt); + + host_offset += offset - __vcpu_sys_reg(vcpu, CNTVOFF_EL2); + __vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset; + timer_set_offset(ctxt, host_offset); + break; + } + default: + WARN_ONCE(offset, "timer %ld\n", arch_timer_ctx_index(ctxt)); + } +} + u64 kvm_phys_timer_read(void) { return timecounter->cc->read(timecounter->cc); @@ -749,7 +779,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu) /* Make offset updates for all timer contexts atomic */ static void update_timer_offset(struct kvm_vcpu *vcpu, - enum kvm_arch_timers timer, u64 offset) + enum kvm_arch_timers timer, u64 offset, + bool guest_visible) { int i; struct kvm *kvm = vcpu->kvm; @@ -758,13 +789,20 @@ static void update_timer_offset(struct kvm_vcpu *vcpu, lockdep_assert_held(&kvm->lock); kvm_for_each_vcpu(i, tmp, kvm) - timer_set_offset(vcpu_get_timer(tmp, timer), offset); + if (guest_visible) + timer_set_guest_offset(vcpu_get_timer(tmp, timer), + offset); + else + timer_set_offset(vcpu_get_timer(tmp, timer), offset); /* * When called from the vcpu create path, the CPU being created is not * included in the loop above, so we just set it here as well. */ - timer_set_offset(vcpu_get_timer(vcpu, timer), offset); + if (guest_visible) + timer_set_guest_offset(vcpu_get_timer(vcpu, timer), offset); + else + timer_set_offset(vcpu_get_timer(vcpu, timer), offset); } static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff) @@ -772,7 +810,7 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff) struct kvm *kvm = vcpu->kvm; mutex_lock(&kvm->lock); - update_timer_offset(vcpu, TIMER_VTIMER, cntvoff); + update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, true); mutex_unlock(&kvm->lock); } diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index 51c19381108c..9d65d4a29f81 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -42,6 +42,9 @@ struct arch_timer_context { /* Duplicated state from arch_timer.c for convenience */ u32 host_timer_irq; u32 host_timer_irq_flags; + + /* offset relative to the host's physical counter-timer */ + u64 host_offset; }; struct timer_map { From patchwork Wed Aug 4 08:58:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418185 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 BC4FAC4338F for ; Wed, 4 Aug 2021 09:07:25 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7BBB460F14 for ; Wed, 4 Aug 2021 09:07:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7BBB460F14 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=r+5dD11ySqT9k275aQLd3I51zzGzsDpdgFSa45oN+Lc=; b=FtMcadQo6L0mWJrxhWMkG4B1vA 3wbiCtD4AeFqyJ1o1URzRc67CRjbxyA0Ec7uTaPYOkjKDF15JP6LLVT2+n7HFnfiCLKzJs2w4gl3+ RA4BK9SAScmfug8mowb0p+3Wv6jN/Iwy5ZIPlBuglJTMdoAfapYACBIFFV9W+XkzxYX6qXsDWWBK6 WmR31Mhnd+IFMwcZylPPSgQOf4Ziheq0ZOvxi+DcJ0y0F9Y0tTVqAr/pIBtAcxH6l/Rvo8xLKAn98 HxWZKwtggJ3GmKCoCuG3YeNhB7Lwyxeq0pWYRNSAPrqguMBfHdP8esxVZX4sDFj6NOCuZljRCdo0m MYQBEVWA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCpb-005IWU-Ti; Wed, 04 Aug 2021 09:04:56 +0000 Received: from mail-il1-x149.google.com ([2607:f8b0:4864:20::149]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCji-005FcD-IG for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:52 +0000 Received: by mail-il1-x149.google.com with SMTP id p9-20020a92d2890000b02902221165b777so605029ilp.19 for ; Wed, 04 Aug 2021 01:58:49 -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=pHbBznoto/w1DGPJijTV3nfkHaGebmmnj5HwOTBirkc=; b=dn/0nPYXirFwFfUZ2GEAi/qhuxAMc3UdhDO5zmOyzs4xgPPu1Issk8EocASn5/fyv4 MQAn8vRHgozFqMtyCgZVR6SDS4qKCek2Jf+x2jEEDw5+sz044Vt95ZHgm1fwiYxlm8YX ukQuG2II6iGVwSqrZYFdafAwQC+k5t3CTrkXoJIYdnhEJg5alr2F+tA9OPsKKVDSVi3Y BHefOjNKnYGVSyVxjK2UOSfnx1q9BUaOobpoFWPlmrKVCt998wzyV0/IZhMWS0ApXxWH /hZirW/KtZLzZIrUTN+53iSMqDwzzqQ+cCjWotK5YAmKlkmNPQffOWK+hwL4ocJOa0/s a85Q== 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=pHbBznoto/w1DGPJijTV3nfkHaGebmmnj5HwOTBirkc=; b=TWRHWeLiyETYgtesFqJ4LVRx2ZtMCd/8hKWMB+COGXQTYNMLBqaGlDt2AaYl9yWynQ dsI+5dx21n+3rmScILpVsAAwvdd3IzLPjNYNcxkFjcgu92UnvI+tea5dGWYvBA5I472q Z4yDCrLGGQFiCCblCgzvI2l/6Yj0VlIdZ6B2p0TrzYi+nRFk03Um7wbcku0PA8mjJfF0 BMlsap0AJYwxfkWehmZco0NP0QJHBXDAbrhDAdXeaz3iYZTOraPomE95vkUhkVrROnBg eyLGfkA0BiP2dOd5LYNxFEvNZ9q6InUQt50yZy9qIlW2SuFGTbT6eT3D2DUgR7yQK/Mp psAw== X-Gm-Message-State: AOAM532OwRYkOLiJzJU+/tzbV4jsHvt7E+1JF8o7Rxa7vrvaujJ1ktAq FZMEJeXNZgtVkb5aGEzjMafnrhhcjbA= X-Google-Smtp-Source: ABdhPJx430Og/gl8Ea4doYmCM5gKCd5oDpwqPEalh4SowVARGCh1NYO/9OTpOR3+C6ZHxiOd8eCjQClzb+4= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a05:6e02:54c:: with SMTP id i12mr111057ils.103.1628067529077; Wed, 04 Aug 2021 01:58:49 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:11 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-14-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 13/21] KVM: arm64: Allow userspace to configure a vCPU's virtual offset From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015850_655508_12CD8C4B X-CRM114-Status: GOOD ( 16.59 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Allow userspace to access the guest's virtual counter-timer offset through the ONE_REG interface. The value read or written is defined to be an offset from the guest's physical counter-timer. Add some documentation to clarify how a VMM should use this and the existing CNTVCT_EL0. Signed-off-by: Oliver Upton Reviewed-by: Andrew Jones --- Documentation/virt/kvm/api.rst | 10 ++++++++++ arch/arm64/include/uapi/asm/kvm.h | 1 + arch/arm64/kvm/arch_timer.c | 11 +++++++++++ arch/arm64/kvm/guest.c | 6 +++++- include/kvm/arm_arch_timer.h | 1 + 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 8d4a3471ad9e..28a65dc89985 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -2487,6 +2487,16 @@ arm64 system registers have the following id bit patterns:: derived from the register encoding for CNTV_CVAL_EL0. As this is API, it must remain this way. +.. warning:: + + The value of KVM_REG_ARM_TIMER_OFFSET is defined as an offset from + the guest's view of the physical counter-timer. + + Userspace should use either KVM_REG_ARM_TIMER_OFFSET or + KVM_REG_ARM_TIMER_CVAL to pause and resume a guest's virtual + counter-timer. Mixed use of these registers could result in an + unpredictable guest counter value. + arm64 firmware pseudo-registers have the following bit pattern:: 0x6030 0000 0014 diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index b3edde68bc3e..949a31bc10f0 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -255,6 +255,7 @@ struct kvm_arm_copy_mte_tags { #define KVM_REG_ARM_TIMER_CTL ARM64_SYS_REG(3, 3, 14, 3, 1) #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2) #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) +#define KVM_REG_ARM_TIMER_OFFSET ARM64_SYS_REG(3, 4, 14, 0, 3) /* KVM-as-firmware specific pseudo-registers */ #define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 4c2b763a8849..a8815b09da3e 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -868,6 +868,10 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) timer = vcpu_vtimer(vcpu); kvm_arm_timer_write(vcpu, timer, TIMER_REG_CVAL, value); break; + case KVM_REG_ARM_TIMER_OFFSET: + timer = vcpu_vtimer(vcpu); + update_vtimer_cntvoff(vcpu, value); + break; case KVM_REG_ARM_PTIMER_CTL: timer = vcpu_ptimer(vcpu); kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value); @@ -912,6 +916,9 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid) case KVM_REG_ARM_TIMER_CVAL: return kvm_arm_timer_read(vcpu, vcpu_vtimer(vcpu), TIMER_REG_CVAL); + case KVM_REG_ARM_TIMER_OFFSET: + return kvm_arm_timer_read(vcpu, + vcpu_vtimer(vcpu), TIMER_REG_OFFSET); case KVM_REG_ARM_PTIMER_CTL: return kvm_arm_timer_read(vcpu, vcpu_ptimer(vcpu), TIMER_REG_CTL); @@ -949,6 +956,10 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu, val = kvm_phys_timer_read() - timer_get_offset(timer); break; + case TIMER_REG_OFFSET: + val = timer_get_offset(timer); + break; + default: BUG(); } diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 1dfb83578277..17fc06e2b422 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -591,7 +591,7 @@ static unsigned long num_core_regs(const struct kvm_vcpu *vcpu) * ARM64 versions of the TIMER registers, always available on arm64 */ -#define NUM_TIMER_REGS 3 +#define NUM_TIMER_REGS 4 static bool is_timer_reg(u64 index) { @@ -599,6 +599,7 @@ static bool is_timer_reg(u64 index) case KVM_REG_ARM_TIMER_CTL: case KVM_REG_ARM_TIMER_CNT: case KVM_REG_ARM_TIMER_CVAL: + case KVM_REG_ARM_TIMER_OFFSET: return true; } return false; @@ -614,6 +615,9 @@ static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) uindices++; if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices)) return -EFAULT; + uindices++; + if (put_user(KVM_REG_ARM_TIMER_OFFSET, uindices)) + return -EFAULT; return 0; } diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index 9d65d4a29f81..615f9314f6a5 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -21,6 +21,7 @@ enum kvm_arch_timer_regs { TIMER_REG_CVAL, TIMER_REG_TVAL, TIMER_REG_CTL, + TIMER_REG_OFFSET, }; struct arch_timer_context { From patchwork Wed Aug 4 08:58:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418187 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 BDF7BC4338F for ; Wed, 4 Aug 2021 09:08:28 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8DA6360FC4 for ; Wed, 4 Aug 2021 09:08:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 8DA6360FC4 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=259CacKVtv7R5mEwuH6UP6Xo6rpFSlwabp7OGx7jIPg=; b=k4YTADSkCRhAi+iQg1aLm16anw jYmhtRICdF5hW/hh4n8U+6sXY89EwrN6hRMYCLWs4PDmu6E0eRBFTVsOttKUvy91DS8xSA0fXmFIz JeEvkN+mO7EbT4xKwwxZjiVMZUANg6OPfN2cmZTOPHasULJaDkFOgHLqTLuSWW96qwyKGqlSrqGWl sLSFq4vFiPb2NBVUl0T9vyGOKclOjNi6+G31wrkk43q7FvSeCqEVLfwQAkk6lGtqesSr3rOEWRKNM s3j6eGbKqdOWt39h0XhM5IukECUkKKmi3VQbws4DMPS/Of4VkvUgA4fgBS2Qv5wTS5Gdq8YUftx7H UG5Dj/9A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCqW-005Ivz-C3; Wed, 04 Aug 2021 09:05:54 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjj-005Fcq-UC for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:53 +0000 Received: by mail-yb1-xb49.google.com with SMTP id g11-20020a25ae4b0000b02905792fb55b0bso2246877ybe.9 for ; Wed, 04 Aug 2021 01:58:50 -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=kDlmZ2q+VtsAE3exEj8aYy6Fk3kSky3TCXUK2+oaNSo=; b=lzMCH9i930DInyi3TgFPeE0uphR3Msy4pTrV5RPcS66cl2mtNGs6v5FMcT24ugSCvu 9t2LTl5MeANnamFbgsOAhO26iTUlsALVuwLmAlCcO3GJ9l1hjsOAorK4kMvfpjtwNn0A BzurnpIA6EmR8GyK1/kV3LTsEcDNwzJRnnugFj0EUJxJYPmqNanYRpUqh9Iho74VI27e Za6PQgbIG636DV/zsqE46glgJvckLVfEpvZwIfocJHgnxj1mN/9rtgCngqSXNiD/Gw/d kHmREJP/0WVtk9MY2zVUvznJ0l9KvXjtClvLNoYeMw2fOuBBfPoJ8QZKRd6CAiszFLAJ PK5A== 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=kDlmZ2q+VtsAE3exEj8aYy6Fk3kSky3TCXUK2+oaNSo=; b=JY3POypu40BWa5g0h2UBxB1hv//XiUPMe7fQpBhbiMFCPfTjPx8I3Nx/OtS0+ERDP7 CsYk57MdNTEjTKWqZZ3zSIA4ObPk6rgn1NyJbiKPWMlN8w5qvQy7XY2nTq2QibMw0LDQ hbBMtWpQGT7fg864ECqm5HaIQQx3FXJLHN2ywscmKUxvh8w1AlXMHWYJtWWoJej3FDqq 1MA30OjNuaFjKFj8En4SFBZ78sDDJsDlDd7Vc+kZFnouSOHd2GxM/tektpEjILyueMCj c0eE5klQIqUgLf3uuMDHQHixxN2I1QGTcfamj5goO1vamvM379QFEbKQP9ibjz6HXdTX qK2Q== X-Gm-Message-State: AOAM532FxkW+w6dO2XZZnKT6rqL+oXv+82DtT0z7czeWYVvwZu7UbEFV xGG3x0lRQfhlWejhwPyN8EYpewSqAPg= X-Google-Smtp-Source: ABdhPJwoa+pdRQxhpipLNFgpIp6Y6GN/h2wf96Y41BJ+I1JnXOOC4/K6kyDAjQKCzkOIoOhBQEk5G+hqcxc= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a25:be48:: with SMTP id d8mr33406835ybm.521.1628067530295; Wed, 04 Aug 2021 01:58:50 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:12 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-15-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 14/21] selftests: KVM: Add helper to check for register presence From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015852_020614_70EEAE88 X-CRM114-Status: GOOD ( 12.88 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The KVM_GET_REG_LIST vCPU ioctl returns a list of supported registers for a given vCPU. Add a helper to check if a register exists in the list of supported registers. Signed-off-by: Oliver Upton Reviewed-by: Andrew Jones --- .../testing/selftests/kvm/include/kvm_util.h | 2 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 1b3ef5757819..077082dd2ca7 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -215,6 +215,8 @@ void vcpu_fpu_get(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu); void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu); + +bool vcpu_has_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t reg_id); void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg); void vcpu_set_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg); #ifdef __KVM_HAVE_VCPU_EVENTS diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 0fe66ca6139a..a5801d4ed37d 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1823,6 +1823,25 @@ void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu) ret, errno, strerror(errno)); } +bool vcpu_has_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t reg_id) +{ + struct kvm_reg_list *list; + bool ret = false; + uint64_t i; + + list = vcpu_get_reg_list(vm, vcpuid); + + for (i = 0; i < list->n; i++) { + if (list->reg[i] == reg_id) { + ret = true; + break; + } + } + + free(list); + return ret; +} + void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg) { int ret; From patchwork Wed Aug 4 08:58:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418189 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 80725C432BE for ; Wed, 4 Aug 2021 09:09:40 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 53BF660E78 for ; Wed, 4 Aug 2021 09:09:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 53BF660E78 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=f+PnfnmwTI7ypx0RIKvjOFVtsDBNW78K8h1rA8e4Cds=; b=STGgqMji1r0QjxqKdoTRYi8KcM LFZQCHFM8Ts/BUSrr3inmgyLWU0FHEgHojJINGO6Zr15oAsUrlQQyfvFeibQITld+jinlu1PMNWA2 m/K2WCCVq6wOVZYJ36Spb+2wW01+LaTm8YIyRp/XCNwuOnQByrdYQmPBLohS1JxXh0PLhy5Fb1Vy8 leOwnUYzjiWjB18H7sX4KUEDFt5gAl2ZrnseZGUUEdvywLRZParrzRXqAhqBAxgTntQd2+EvDkeD0 2ueZF5PoQWxZucZN50Lg0qV40BVXYWrmWb0jqFZLwxMdQXE0YFsXMBDfgh29oy6RZvY1l7ynQB26v PEF7Gwrg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCrm-005JKJ-32; Wed, 04 Aug 2021 09:07:11 +0000 Received: from mail-oo1-xc4a.google.com ([2607:f8b0:4864:20::c4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjl-005Fd6-Ao for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:54 +0000 Received: by mail-oo1-xc4a.google.com with SMTP id k18-20020a4a94920000b029026767722880so626272ooi.7 for ; Wed, 04 Aug 2021 01:58:52 -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=Wr2QUWPIrNr02r9ZSQ6a6WvFSF+P+rF7IWMFJFIeT5Q=; b=A2eaQevcuk1kE8kH+hNfVeiJGxQGIsvPPXH7dwJX1I1bqzmceDdLvtt3vtZsSlfHgS 6uk2fnUUV1bWg9ui/diKwA4nuUWGnCfjSPratLEZd7BP/7MO8akAcoc9w+EQ/wtsAXAp ZyNGkKQCPzWCb6fjuunbxbUeHNOvYwMVhCRqWRcU2+VYhha6puKXBjme8zME+4pwl6Bk TcuhrWi5b2xsYj1XFDIS6BErZBNJ2MwSHwcl0Oh6rDaqMeEyEhpsccRugDvMtCKPZdV8 RqjprVlUgFZUxBZHsKv+zbjtLGxLp/H0em+JFSda46mXMaNqevbjZdwKZHvUvVK5VorB lOwg== 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=Wr2QUWPIrNr02r9ZSQ6a6WvFSF+P+rF7IWMFJFIeT5Q=; b=VieCqTf0MuOailj019osiBhVLIDBBwku+tQnFzGYx/fBrq+wtOUStpNPxjv314PuPY ZkQZ121s3HwWZAoZ4OPZux7qcCU/m2/gGUneojT8MBX80xctyLWJUVt4CwMnxYRzAkOY XgTV44hgKMZL8Sp2wMTQMgk+k6JLyE523aYhwY/haPX2GWWIvl/jcW6LkvGPqU2B5CY/ nxkAkORkvhV8ogh7zYtYJoitQNCIGYzB2rfx3E7TEC/OqQpCRuuDCdt4hBfNCsYj54M4 VjHOi3xO5FqEy05gc4Ii6vb8926J/5b9Wn2YPS3yFuhFlWi96Qnmz8Iss5d5IEjJ2Aor zutA== X-Gm-Message-State: AOAM533ElZtgCJiy9sbZspQpxlesbZvdjibEaGdCs6ESHJs1zF6iNPxR YJJtiO/fF67eVJwoTPy7whIt/cu6TWE= X-Google-Smtp-Source: ABdhPJwV6z5/wOQcC6ysoCIBRHVz7QoiKO1NC+BeHz63h1lYVDEtDeBmgg3mO02si6II7kJcePnt4XlEnxs= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a9d:6d16:: with SMTP id o22mr5444656otp.336.1628067531365; Wed, 04 Aug 2021 01:58:51 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:13 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-16-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 15/21] selftests: KVM: Add support for aarch64 to system_counter_offset_test From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015853_425327_1AC1F730 X-CRM114-Status: GOOD ( 16.10 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org KVM/arm64 now allows userspace to adjust the guest virtual counter-timer via a vCPU register. Test that changes to the virtual counter-timer offset result in the correct view being presented to the guest. Reviewed-by: Andrew Jones Signed-off-by: Oliver Upton --- tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/include/aarch64/processor.h | 12 ++++ .../kvm/system_counter_offset_test.c | 56 ++++++++++++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 9f7060c02668..fab42e7c23ee 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -98,6 +98,7 @@ TEST_GEN_PROGS_aarch64 += kvm_page_table_test TEST_GEN_PROGS_aarch64 += set_memory_region_test TEST_GEN_PROGS_aarch64 += steal_time TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test +TEST_GEN_PROGS_aarch64 += system_counter_offset_test TEST_GEN_PROGS_s390x = s390x/memop TEST_GEN_PROGS_s390x += s390x/resets diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h index 27dc5c2e56b9..3168cdbae6ee 100644 --- a/tools/testing/selftests/kvm/include/aarch64/processor.h +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h @@ -129,4 +129,16 @@ void vm_install_sync_handler(struct kvm_vm *vm, #define isb() asm volatile("isb" : : : "memory") +static inline uint64_t read_cntvct_ordered(void) +{ + uint64_t r; + + __asm__ __volatile__("isb\n\t" + "mrs %0, cntvct_el0\n\t" + "isb\n\t" + : "=r"(r)); + + return r; +} + #endif /* SELFTEST_KVM_PROCESSOR_H */ diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c index b337bbbfa41f..ac933db83d03 100644 --- a/tools/testing/selftests/kvm/system_counter_offset_test.c +++ b/tools/testing/selftests/kvm/system_counter_offset_test.c @@ -53,7 +53,61 @@ static uint64_t host_read_guest_system_counter(struct test_case *test) return rdtsc() + test->tsc_offset; } -#else /* __x86_64__ */ +#elif __aarch64__ /* __x86_64__ */ + +enum arch_counter { + VIRTUAL, +}; + +struct test_case { + enum arch_counter counter; + uint64_t offset; +}; + +static struct test_case test_cases[] = { + { .counter = VIRTUAL, .offset = 0 }, + { .counter = VIRTUAL, .offset = 180 * NSEC_PER_SEC }, + { .counter = VIRTUAL, .offset = -180 * NSEC_PER_SEC }, +}; + +static void check_preconditions(struct kvm_vm *vm) +{ + if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET)) + return; + + print_skip("KVM_REG_ARM_TIMER_OFFSET not supported; skipping test"); + exit(KSFT_SKIP); +} + +static void setup_system_counter(struct kvm_vm *vm, struct test_case *test) +{ + struct kvm_one_reg reg = { + .id = KVM_REG_ARM_TIMER_OFFSET, + .addr = (__u64)&test->offset, + }; + + vcpu_set_reg(vm, VCPU_ID, ®); +} + +static uint64_t guest_read_system_counter(struct test_case *test) +{ + switch (test->counter) { + case VIRTUAL: + return read_cntvct_ordered(); + default: + GUEST_ASSERT(0); + } + + /* unreachable */ + return 0; +} + +static uint64_t host_read_guest_system_counter(struct test_case *test) +{ + return read_cntvct_ordered() - test->offset; +} + +#else /* __aarch64__ */ #error test not implemented for this architecture! From patchwork Wed Aug 4 08:58:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418191 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT 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 26652C4338F for ; Wed, 4 Aug 2021 09:10:53 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EB9D360E78 for ; Wed, 4 Aug 2021 09:10:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org EB9D360E78 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=CFl3m2s0GYPLOsEt3rSv0plVmv64yu4P43SYuVRmFpA=; b=OrBC0S08YZBmuCaGYHS5CbclMP E8s3oX5juXc2aNkGGX5kOYr1gXFOqsWsEdI74kjOFI/BRey2/qQdVH/LCwuTSHsQQH0Sqy71nBFOl BLYGmkLmEU5gja5HvXdZ9EEr3EKS9322C8MZabcKqXAJyoPr2Lbl0pxo4LbuSNIEjz+zmphkomxfE qFZ1PiF7UHzFDqYemUCo9EFFsyvfW4SywLahnyML0PasDWDDBkmBwSzf0zeQnIAA0DevLRA5qFH0h cdWAjUG459FUnz7CIfGDKRhQfOFZ2lCIJD2FP4CLRW3QIcdPL+sSwomEvnYY07KMBrQvMtzTDi2SN ODKPY88Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCsn-005Jgr-Qu; Wed, 04 Aug 2021 09:08:16 +0000 Received: from mail-qv1-xf49.google.com ([2607:f8b0:4864:20::f49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjm-005FdW-IN for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:55 +0000 Received: by mail-qv1-xf49.google.com with SMTP id dl20-20020ad44e140000b0290347c39b05c0so1306194qvb.3 for ; Wed, 04 Aug 2021 01:58:53 -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=h8C+AkSSxjD2I6RXdGSsBwEWeDSTzFjVwyFJmn30s0c=; b=vdFpyj+9XNPjdYnHOx6TwDyWXfkwfTUZA5Sw6ri/Z+MfoVjX9B5ei1iIA6qchNTckg Js4/woRxok9rGl937dT5UR6w8jykMhwsS++V75ZeD8wlloCL6wCsYKsehUNaIOE43JeR Z2I0iFTOk5qzEKQKx3u2dbLLBMotmDxqqKCR94OqjLYyygFGecaxna6m9TnnTENZ1dlO BcCV64E3066DzzNmcmkPW3oPneJUjkCGeWxgt3hXPaU/8EVSRFSD6lZNyz1DT33Lkoi7 qZmZBVlnNgK5BwZRYc/LHdxEGICI0QBX432vw8WwyIBzzYfANL3FddNoQdY4qIW6LGFV epqw== 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=h8C+AkSSxjD2I6RXdGSsBwEWeDSTzFjVwyFJmn30s0c=; b=gkj6hwKlyV2cLr4Ah97yQoPVq5Ltu6iMFW9RxT6qy6dg+LQ3YpXYUJHIpRKB7AEbDu NSgbs1IFbXv84KS65rSAYNVypGGR3blOVg9c6I5DzeARbrcpvhI+s7TdykkxDTXrShto HAQhSzPQpGI7/tBCD1u70GYeufg8YnNqHYZYl5Hc+8Jy7n4sarxkPpuob4L899F00w8R QVHs04dp/F0NzPHn5O+RxMkW8EKJbjJbkplpOd6E2j5tRvdckUVr7j120wQ23WPOld5Z DUlURuRosvq2JG9qWjRbA8PZCiNOe1NFZZYn1mZMiDMBR9s9GSMH/czSm+a+oBVi4aYD XVpQ== X-Gm-Message-State: AOAM533mmcn5yj4Q1/uhnISaXOLsuP6JQn/4ix9i/jQ2LJLHiw9R8ezv xW9zF5OlG22AVyTaTkWS621ZLJYNg4k= X-Google-Smtp-Source: ABdhPJx+GeA32n6jMUHsP7WogSpQpinH4eyTOFkLIo8qvlVC8zogWUDIRuiTAtVqSj3R5xgXeAPAlnAcOpw= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a05:6214:134c:: with SMTP id b12mr24474131qvw.39.1628067532459; Wed, 04 Aug 2021 01:58:52 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:14 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-17-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 16/21] arm64: cpufeature: Enumerate support for Enhanced Counter Virtualization From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015854_659783_B8384463 X-CRM114-Status: GOOD ( 11.82 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Introduce a new cpucap to indicate if the system supports full enhanced counter virtualization (i.e. ID_AA64MMFR0_EL1.ECV==0x2). Signed-off-by: Oliver Upton --- arch/arm64/include/asm/sysreg.h | 2 ++ arch/arm64/kernel/cpufeature.c | 10 ++++++++++ arch/arm64/tools/cpucaps | 1 + 3 files changed, 13 insertions(+) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 7b9c3acba684..4dfc44066dfb 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -847,6 +847,8 @@ #define ID_AA64MMFR0_ASID_SHIFT 4 #define ID_AA64MMFR0_PARANGE_SHIFT 0 +#define ID_AA64MMFR0_ECV_VIRT 0x1 +#define ID_AA64MMFR0_ECV_PHYS 0x2 #define ID_AA64MMFR0_TGRAN4_NI 0xf #define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0 #define ID_AA64MMFR0_TGRAN64_NI 0xf diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 0ead8bfedf20..94c349e179d3 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2301,6 +2301,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .matches = has_cpuid_feature, .min_field_value = 1, }, + { + .desc = "Enhanced Counter Virtualization (Physical)", + .capability = ARM64_ECV, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .sys_reg = SYS_ID_AA64MMFR0_EL1, + .sign = FTR_UNSIGNED, + .field_pos = ID_AA64MMFR0_ECV_SHIFT, + .matches = has_cpuid_feature, + .min_field_value = ID_AA64MMFR0_ECV_PHYS, + }, {}, }; diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 49305c2e6dfd..d819ea614da5 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -3,6 +3,7 @@ # Internal CPU capabilities constants, keep this list sorted BTI +ECV # Unreliable: use system_supports_32bit_el0() instead. HAS_32BIT_EL0_DO_NOT_USE HAS_32BIT_EL1 From patchwork Wed Aug 4 08:58:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418193 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 B36F7C432BE for ; Wed, 4 Aug 2021 09:11:47 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 77A5360F10 for ; Wed, 4 Aug 2021 09:11:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 77A5360F10 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=xCfiz8zdYVoOMNKxj9zoZYcDuyDRz/HaK6eCxa3cWbQ=; b=mBwNEQ2Tjmdi3v1TC23dyOBmLf 44/fEI08YmBqAziPOzLP/bz8qBH2TNZh7zpN3HaRQnZy6iAbRmcVXoMRA9KhUxFIQuzcqBBt3S/Ac U9D93tIW3DvSKA2tQWtnBh6IPI3Qtry5Abz0wFh/sTmPzHWA/m48zgzUE4BDfCNL2eS2WHAvHwdZr xamxtKbtcP50nUvl5LGur9c8X3Ktzr4DAbgko68Jcvt93Ap1OJ7MGqj/k17soRsKqjyde8kDGDR1R clJXbSNcw1MFURcZhIxRwFpX9plIXbHls4lWnV+3smUZeqExIS2Hm88eTnK09eJFFrCmRIEX4ySsx 9BZeLJmg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCtt-005K6b-GY; Wed, 04 Aug 2021 09:09:22 +0000 Received: from mail-oi1-x249.google.com ([2607:f8b0:4864:20::249]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjn-005Fdv-DX for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:57 +0000 Received: by mail-oi1-x249.google.com with SMTP id r7-20020acaf3070000b029026241cf3dbfso815355oih.16 for ; Wed, 04 Aug 2021 01:58:54 -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=kFwwMIpnmqOzxqT89bHMdsWlLDW/5PXBmoq4iDX0eaw=; b=YIwgyuXhvqVBtX51VOKKk6u9LfEBspNfXwujueAbUBIapLhehiLsFrngx90jPYlEe9 MB5ElPvTBNd+uIi+Mav5Qz+f0sZKbUN56TcZ4zNiAbkwg/DPcedQrhv+zLaCD8v60aYf MnOo8w3Z4/a7gRNM01oLHeVFvqqfcO0Gh7bwOrIeAr0Wao/Qiq8u+/WTZ066EmNi50oY XMLZm/ixZ+hiG3rYwV2OMFjFYPka7EglMBj4lnueqeMmTVnWXHp/Wi249rvt/2e2jqex jyZWEPMpVub8y1UOH8F6ERXSvOItCs7DkmwAIzr1fvO7ij9w9aDm/qGwGLYDmHJt2aNn qegQ== 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=kFwwMIpnmqOzxqT89bHMdsWlLDW/5PXBmoq4iDX0eaw=; b=J/GctUaZ6s6i+4harIIi98ak3FB6K8i3J1NoL+6fmB5L5OMoevofzvZybJYywoxeGH 8H7FLiwLJDWGCj3M0nVbID73bO6CGTb3jLinwATam4AywUK49vkt7iwDbpuOC7JIT7pm ePsHOV6LQ9PZ6IzNFCXcy/02JIYShBaXfjuyL/n8dDvN+TZsEgONsSQN7kGXIzgMcGX2 2kzvFwO8ACqBWRVRxjzL5NrHr1LwZNBrMe6zZ9ZosqeIQ5iDWWuw1O9GMZJrbxOLStTg 0MqCWXXUdUC/D9u6uVop4AqCK9U9wm9Xs75S6RfxovB9j1sAKB5fFMnLJKFHSEeETpQ7 INfw== X-Gm-Message-State: AOAM530hSBinJOtoDv4Rn0bS3gfO3l3Qf2geeImOySpr8KW/8enqOENm 0TrSlum2wqfVQVAt0cjQthgtvqUdHVE= X-Google-Smtp-Source: ABdhPJyuAtu1rbFc6HpuHaUiO2dj+fadWoeHL9t28wgyqqRe/01oBpVK787LMhXlOFyahOuzSrGIK043sC4= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:aca:6704:: with SMTP id z4mr17394391oix.89.1628067533524; Wed, 04 Aug 2021 01:58:53 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:15 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-18-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 17/21] KVM: arm64: Allow userspace to configure a guest's counter-timer offset From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015855_519514_D4306042 X-CRM114-Status: GOOD ( 25.01 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Presently, KVM provides no facilities for correctly migrating a guest that depends on the physical counter-timer. Whie most guests (barring NV, of course) should not depend on the physical counter-timer, an operator may wish to provide a consistent view of the physical counter-timer across migrations. Provide userspace with a new vCPU attribute to modify the guest counter-timer offset. Unlike KVM_REG_ARM_TIMER_OFFSET, this attribute is hidden from the guest's architectural state. The value offsets *both* the virtual and physical counter-timer views for the guest. Only support this attribute on ECV systems as ECV is required for hardware offsetting of the physical counter-timer. Signed-off-by: Oliver Upton Reviewed-by: Andrew Jones --- Documentation/virt/kvm/devices/vcpu.rst | 28 ++++++ arch/arm64/include/asm/kvm_asm.h | 2 + arch/arm64/include/asm/sysreg.h | 2 + arch/arm64/include/uapi/asm/kvm.h | 1 + arch/arm64/kvm/arch_timer.c | 122 +++++++++++++++++++++++- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 6 ++ arch/arm64/kvm/hyp/nvhe/timer-sr.c | 5 + arch/arm64/kvm/hyp/vhe/timer-sr.c | 5 + include/clocksource/arm_arch_timer.h | 1 + 9 files changed, 169 insertions(+), 3 deletions(-) diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst index 3b399d727c11..3ba35b9d9d03 100644 --- a/Documentation/virt/kvm/devices/vcpu.rst +++ b/Documentation/virt/kvm/devices/vcpu.rst @@ -139,6 +139,34 @@ configured values on other VCPUs. Userspace should configure the interrupt numbers on at least one VCPU after creating all VCPUs and before running any VCPUs. +2.2. ATTRIBUTE: KVM_ARM_VCPU_TIMER_OFFSET +----------------------------------------- + +:Parameters: in kvm_device_attr.addr the address for the timer offset is a + pointer to a __u64 + +Returns: + + ======= ================================== + -EFAULT Error reading/writing the provided + parameter address + -ENXIO Timer offsetting not implemented + ======= ================================== + +Specifies the guest's counter-timer offset from the host's virtual counter. +The guest's physical counter value is then derived by the following +equation: + + guest_cntpct = host_cntvct - KVM_ARM_VCPU_TIMER_OFFSET + +The guest's virtual counter value is derived by the following equation: + + guest_cntvct = host_cntvct - KVM_REG_ARM_TIMER_OFFSET + - KVM_ARM_VCPU_TIMER_OFFSET + +KVM does not allow the use of varying offset values for different vCPUs; +the last written offset value will be broadcasted to all vCPUs in a VM. + 3. GROUP: KVM_ARM_VCPU_PVTIME_CTRL ================================== diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 9f0bf2109be7..ab1c8fdb0177 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -65,6 +65,7 @@ #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize 19 #define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp 20 #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc 21 +#define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntpoff 22 #ifndef __ASSEMBLY__ @@ -200,6 +201,7 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa, extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu); extern void __kvm_timer_set_cntvoff(u64 cntvoff); +extern void __kvm_timer_set_cntpoff(u64 cntpoff); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 4dfc44066dfb..c34672aa65b9 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -586,6 +586,8 @@ #define SYS_ICH_LR14_EL2 __SYS__LR8_EL2(6) #define SYS_ICH_LR15_EL2 __SYS__LR8_EL2(7) +#define SYS_CNTPOFF_EL2 sys_reg(3, 4, 14, 0, 6) + /* VHE encodings for architectural EL0/1 system registers */ #define SYS_SCTLR_EL12 sys_reg(3, 5, 1, 0, 0) #define SYS_CPACR_EL12 sys_reg(3, 5, 1, 0, 2) diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 949a31bc10f0..15150f8224a1 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -366,6 +366,7 @@ struct kvm_arm_copy_mte_tags { #define KVM_ARM_VCPU_TIMER_CTRL 1 #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 +#define KVM_ARM_VCPU_TIMER_OFFSET 2 #define KVM_ARM_VCPU_PVTIME_CTRL 2 #define KVM_ARM_VCPU_PVTIME_IPA 0 diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index a8815b09da3e..f15058612994 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -85,11 +85,15 @@ u64 timer_get_cval(struct arch_timer_context *ctxt) static u64 timer_get_offset(struct arch_timer_context *ctxt) { struct kvm_vcpu *vcpu = ctxt->vcpu; + struct arch_timer_cpu *timer = vcpu_timer(vcpu); switch(arch_timer_ctx_index(ctxt)) { case TIMER_VTIMER: + case TIMER_PTIMER: return ctxt->host_offset; default: + WARN_ONCE(1, "unrecognized timer %ld\n", + arch_timer_ctx_index(ctxt)); return 0; } } @@ -144,6 +148,7 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset) switch(arch_timer_ctx_index(ctxt)) { case TIMER_VTIMER: + case TIMER_PTIMER: ctxt->host_offset = offset; break; default: @@ -572,6 +577,11 @@ static void set_cntvoff(u64 cntvoff) kvm_call_hyp(__kvm_timer_set_cntvoff, cntvoff); } +static void set_cntpoff(u64 cntpoff) +{ + kvm_call_hyp(__kvm_timer_set_cntpoff, cntpoff); +} + static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active) { int r; @@ -647,6 +657,8 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu) } set_cntvoff(timer_get_offset(map.direct_vtimer)); + if (cpus_have_const_cap(ARM64_ECV)) + set_cntpoff(timer_get_offset(vcpu_ptimer(vcpu))); kvm_timer_unblocking(vcpu); @@ -814,6 +826,22 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff) mutex_unlock(&kvm->lock); } +static void update_ptimer_cntpoff(struct kvm_vcpu *vcpu, u64 cntpoff) +{ + struct kvm *kvm = vcpu->kvm; + u64 cntvoff; + + mutex_lock(&kvm->lock); + + /* adjustments to the physical offset also affect vtimer */ + cntvoff = timer_get_offset(vcpu_vtimer(vcpu)); + cntvoff += cntpoff - timer_get_offset(vcpu_ptimer(vcpu)); + + update_timer_offset(vcpu, TIMER_PTIMER, cntpoff, false); + update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, false); + mutex_unlock(&kvm->lock); +} + void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = vcpu_timer(vcpu); @@ -932,6 +960,29 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid) return (u64)-1; } +/** + * kvm_arm_timer_read_offset - returns the guest value of CNTVOFF_EL2. + * @vcpu: the vcpu pointer + * + * Computes the guest value of CNTVOFF_EL2 by subtracting the physical + * counter offset. Note that KVM defines CNTVOFF_EL2 as the offset from the + * guest's physical counter-timer, not the host's. + * + * Returns: the guest value for CNTVOFF_EL2 + */ +static u64 kvm_arm_timer_read_offset(struct kvm_vcpu *vcpu) +{ + struct kvm *kvm = vcpu->kvm; + u64 offset; + + mutex_lock(&kvm->lock); + offset = timer_get_offset(vcpu_vtimer(vcpu)) - + timer_get_offset(vcpu_ptimer(vcpu)); + mutex_unlock(&kvm->lock); + + return offset; +} + static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu, struct arch_timer_context *timer, enum kvm_arch_timer_regs treg) @@ -957,7 +1008,7 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu, break; case TIMER_REG_OFFSET: - val = timer_get_offset(timer); + val = kvm_arm_timer_read_offset(vcpu); break; default: @@ -1350,6 +1401,9 @@ void kvm_timer_init_vhe(void) val = read_sysreg(cnthctl_el2); val |= (CNTHCTL_EL1PCEN << cnthctl_shift); val |= (CNTHCTL_EL1PCTEN << cnthctl_shift); + + if (cpus_have_const_cap(ARM64_ECV)) + val |= CNTHCTL_ECV; write_sysreg(val, cnthctl_el2); } @@ -1364,7 +1418,8 @@ static void set_timer_irqs(struct kvm *kvm, int vtimer_irq, int ptimer_irq) } } -int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) +static int kvm_arm_timer_set_attr_irq(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) { int __user *uaddr = (int __user *)(long)attr->addr; struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); @@ -1397,7 +1452,37 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) return 0; } -int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) +static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + u64 __user *uaddr = (u64 __user *)(long)attr->addr; + u64 offset; + + if (!cpus_have_const_cap(ARM64_ECV)) + return -ENXIO; + + if (get_user(offset, uaddr)) + return -EFAULT; + + update_ptimer_cntpoff(vcpu, offset); + return 0; +} + +int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) +{ + switch (attr->attr) { + case KVM_ARM_VCPU_TIMER_IRQ_VTIMER: + case KVM_ARM_VCPU_TIMER_IRQ_PTIMER: + return kvm_arm_timer_set_attr_irq(vcpu, attr); + case KVM_ARM_VCPU_TIMER_OFFSET: + return kvm_arm_timer_set_attr_offset(vcpu, attr); + default: + return -ENXIO; + } +} + +static int kvm_arm_timer_get_attr_irq(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) { int __user *uaddr = (int __user *)(long)attr->addr; struct arch_timer_context *timer; @@ -1418,12 +1503,43 @@ int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) return put_user(irq, uaddr); } +static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + u64 __user *uaddr = (u64 __user *)(long)attr->addr; + u64 offset; + + if (!cpus_have_const_cap(ARM64_ECV)) + return -ENXIO; + + offset = timer_get_offset(vcpu_ptimer(vcpu)); + return put_user(offset, uaddr); +} + +int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + switch (attr->attr) { + case KVM_ARM_VCPU_TIMER_IRQ_VTIMER: + case KVM_ARM_VCPU_TIMER_IRQ_PTIMER: + return kvm_arm_timer_get_attr_irq(vcpu, attr); + case KVM_ARM_VCPU_TIMER_OFFSET: + return kvm_arm_timer_get_attr_offset(vcpu, attr); + default: + return -ENXIO; + } +} + int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) { switch (attr->attr) { case KVM_ARM_VCPU_TIMER_IRQ_VTIMER: case KVM_ARM_VCPU_TIMER_IRQ_PTIMER: return 0; + case KVM_ARM_VCPU_TIMER_OFFSET: + if (cpus_have_const_cap(ARM64_ECV)) + return 0; + break; } return -ENXIO; diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 1632f001f4ed..cfa923df3af6 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -68,6 +68,11 @@ static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt) __kvm_timer_set_cntvoff(cpu_reg(host_ctxt, 1)); } +static void handle___kvm_timer_set_cntpoff(struct kvm_cpu_context *host_ctxt) +{ + __kvm_timer_set_cntpoff(cpu_reg(host_ctxt, 1)); +} + static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt) { u64 tmp; @@ -197,6 +202,7 @@ static const hcall_t host_hcall[] = { HANDLE_FUNC(__pkvm_create_private_mapping), HANDLE_FUNC(__pkvm_prot_finalize), HANDLE_FUNC(__pkvm_mark_hyp), + HANDLE_FUNC(__kvm_timer_set_cntpoff), }; static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c index 9072e71693ba..5b8b4cd02506 100644 --- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c +++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c @@ -15,6 +15,11 @@ void __kvm_timer_set_cntvoff(u64 cntvoff) write_sysreg(cntvoff, cntvoff_el2); } +void __kvm_timer_set_cntpoff(u64 cntpoff) +{ + write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2); +} + /* * Should only be called on non-VHE systems. * VHE systems use EL2 timers and configure EL1 timers in kvm_timer_init_vhe(). diff --git a/arch/arm64/kvm/hyp/vhe/timer-sr.c b/arch/arm64/kvm/hyp/vhe/timer-sr.c index 4cda674a8be6..231e16a071a5 100644 --- a/arch/arm64/kvm/hyp/vhe/timer-sr.c +++ b/arch/arm64/kvm/hyp/vhe/timer-sr.c @@ -10,3 +10,8 @@ void __kvm_timer_set_cntvoff(u64 cntvoff) { write_sysreg(cntvoff, cntvoff_el2); } + +void __kvm_timer_set_cntpoff(u64 cntpoff) +{ + write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2); +} diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h index 73c7139c866f..7252ffa3d675 100644 --- a/include/clocksource/arm_arch_timer.h +++ b/include/clocksource/arm_arch_timer.h @@ -21,6 +21,7 @@ #define CNTHCTL_EVNTEN (1 << 2) #define CNTHCTL_EVNTDIR (1 << 3) #define CNTHCTL_EVNTI (0xF << 4) +#define CNTHCTL_ECV (1 << 12) enum arch_timer_reg { ARCH_TIMER_REG_CTRL, From patchwork Wed Aug 4 08:58:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418195 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 35F93C4338F for ; Wed, 4 Aug 2021 09:13:30 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E8F8860EE7 for ; Wed, 4 Aug 2021 09:13:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E8F8860EE7 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=S8QTSR8xKYflJdW6Ibw0pF4ZoRsR6vw+v4HyViQSiuE=; b=J/uPFZlIB+SMnNMTGoAAWT8fV1 dVRgQ9IKb5O/JAVxS4yyWOgq+ZMQyUMn0FCCVOLo7arTeRaEf5sFxlqh6UiFp5+bMf/tXiGyFiRaP YGnevPJ7wkLRYMCZL0XZwpG5fnpESV1PGdSWULVjJ9ty4fQF1nmmYFqGXe5RTWZCFF1VGBJR37pKi 4lnAdXvojjbl/FUVHlnC6rSrTvpkdvSHeKdQWKnccjW9VKfyb08N8E2JQhHx7OJKx9K+SzbF9glHA XPUWNbjYJV3AvDOTaorkk7GtsRS/7u3qz3E/tY+cKJXmq937lptLi/9OO2PFT0/bRUKwD3EoAcBHg 0W9qYH2Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCvJ-005Kdh-Cc; Wed, 04 Aug 2021 09:10:51 +0000 Received: from mail-qt1-x84a.google.com ([2607:f8b0:4864:20::84a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjo-005FeK-M3 for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:58 +0000 Received: by mail-qt1-x84a.google.com with SMTP id w19-20020ac87e930000b029025a2609eb04so731352qtj.17 for ; Wed, 04 Aug 2021 01:58:55 -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=xEsi9T4OqglNe742KkivPaDxPwp3ZoFaFAtWROXbBVo=; b=ChSZQBwkJB66ulFJ3pUxF49mjFQq4MBi3vZvx3rv+9LE+Wi7bTs1eRJQzexlr+JRSY n8GGWqtHE6Gj0UzXp8u7OVcee5UjmtXgNekWCLLa5kYlfHloNwdxCdc+Ct0rKHZ9H5MS Lkfrmt/805DmNFA9xjBhD6iryqm8HFC8yEIAfGsd6QT62XFkkQdbUnqv+KeQRQQcaoKc ooADx9GQgfZmou14MKEHG/t4rhEESUtzhs6w4fmnvAlQZTc1x6TOFShLv0Ltd4CyQ4mp W5tQu0tDthrEE4M9igHoxYjuLR+gA4eHJ/5/Iob0qnQunOUx/bJFNJrWm1phkPrntUr2 kgbQ== 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=xEsi9T4OqglNe742KkivPaDxPwp3ZoFaFAtWROXbBVo=; b=iEN1kF32sz7gjmSmquO1EkI2CmAEc4nXBtCk+OR2pMxLvoxtlNJX+bNDHMyYpmxKpn Tvy2S4sBN0i+kV3Nvph46EaTYAYGSxlcArGOSS2xaHXMxCaxvP4LCuneI7Rmackwmy0e i/1fS/Yw4hsBdjjWOvyIDIkjB4lxkx3dTNSlPaBwanRgiZmnyJpNxdigU87AsN4Wp3tq RQDcJNKdzyHJXwmjp8UNN+wKFEPW1rDy9MfyM3ng3rn3PsstV61YkIscS5MCPmpBVpec rxkdFn/7vzThLyTyxKkKRbcoXsNtwzySATgy9Zk4Jd/qdN3SjNPITh/gAMrtTxpGv1K8 6Wsw== X-Gm-Message-State: AOAM530M4VQ/G50EEi1jJsBOSHM0ecgxnLt8Yk8cVBPiBv318Bv7b+Ak v8q+QE2aPmqzBml8fwws+aiSy4P+0Jo= X-Google-Smtp-Source: ABdhPJw4uOQBnarbZ8Pq5S9gvLmcNwTMIjaIMpvh+qw/OSoRZsXJkePXii8fJVoN7ZA8FRpp8uLdyyoJ81g= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a05:6214:104b:: with SMTP id l11mr25726502qvr.40.1628067534598; Wed, 04 Aug 2021 01:58:54 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:16 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-19-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 18/21] KVM: arm64: Configure timer traps in vcpu_load() for VHE From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015856_765644_4572F39B X-CRM114-Status: GOOD ( 15.51 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org In preparation for emulated physical counter-timer offsetting, configure traps on every vcpu_load() for VHE systems. As before, these trap settings do not affect host userspace, and are only active for the guest. Suggested-by: Marc Zyngier Signed-off-by: Oliver Upton Reviewed-by: Andrew Jones --- arch/arm64/kvm/arch_timer.c | 10 +++++++--- arch/arm64/kvm/arm.c | 4 +--- include/kvm/arm_arch_timer.h | 2 -- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index f15058612994..9ead94aa867d 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -51,6 +51,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu, static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu, struct arch_timer_context *timer, enum kvm_arch_timer_regs treg); +static void kvm_timer_enable_traps_vhe(void); u32 timer_get_ctl(struct arch_timer_context *ctxt) { @@ -668,6 +669,9 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu) if (map.emul_ptimer) timer_emulate(map.emul_ptimer); + + if (has_vhe()) + kvm_timer_enable_traps_vhe(); } bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu) @@ -1383,12 +1387,12 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) } /* - * On VHE system, we only need to configure the EL2 timer trap register once, - * not for every world switch. + * On VHE system, we only need to configure the EL2 timer trap register on + * vcpu_load(), but not every world switch into the guest. * The host kernel runs at EL2 with HCR_EL2.TGE == 1, * and this makes those bits have no effect for the host kernel execution. */ -void kvm_timer_init_vhe(void) +static void kvm_timer_enable_traps_vhe(void) { /* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */ u32 cnthctl_shift = 10; diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index e9a2b8f27792..47ea1e1ba80b 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1558,9 +1558,7 @@ static void cpu_hyp_reinit(void) cpu_hyp_reset(); - if (is_kernel_in_hyp_mode()) - kvm_timer_init_vhe(); - else + if (!is_kernel_in_hyp_mode()) cpu_init_hyp_mode(); cpu_set_hyp_vector(); diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index 615f9314f6a5..254653b42da0 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -87,8 +87,6 @@ u64 kvm_phys_timer_read(void); void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu); void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu); -void kvm_timer_init_vhe(void); - bool kvm_arch_timer_get_input_level(int vintid); #define vcpu_timer(v) (&(v)->arch.timer_cpu) From patchwork Wed Aug 4 08:58:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418197 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 1CED2C4338F for ; Wed, 4 Aug 2021 09:14:37 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D349160F10 for ; Wed, 4 Aug 2021 09:14:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org D349160F10 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=++jvXkx35d3TZShXkwfwURNDpWPA6q0jTyHey6XIdUI=; b=Ag+rx/TbjUOXlBbJKd6zsELxLH +jGe/cJsW4V4GzBboeglrJLR/JJRhx3JeVt9K2sSnvdSs0RMdFvXXQRqwjD1g6LxEuLk2/K83tFfI ziPJX0J6D8ahdgaIQo5R7RPrcTRRRBfAJEK4eLjejqIJ+UCACiTDFMxGBhrX2ba+GRj26U9f13jAH 7Qx4Or020BIrZapXBuiyiVSxmMHzdkx/szhnu53GXkYN8OoL6o57+WfX9QrN57hljAa4GgBiVFM3f 4Sr4x/pXMYzXbcXizQ7g54yXWArktCjiyRG7KfSIeqO2s+Iz1mFhRr1oO3WAYAVwn4RGtEWwY8QZ+ pYgVhzVQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCwr-005L68-TI; Wed, 04 Aug 2021 09:12:27 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjo-005Fec-Vo for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:59 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id w200-20020a25c7d10000b02905585436b530so2197165ybe.21 for ; Wed, 04 Aug 2021 01:58:56 -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=5F2XBId6Ml8d60ozFayhTnFPlnF21xMQYH0bLBzTlnY=; b=P/k5j1VS70sB8KLubXHq8/9bo8zjwK2ApmesXmWhSfReRNFGLt7FgvYu9pxbL6CMou jqHRyYf9SLnUjdLKJDC/uGZe+5hsYe27lfpfmoaEpKXJ0DV/3X4nK9CLFDBUyABhnYLK 0Z44gI8AjTXpmoIvCKRNQDfMcuTKGA36vz7aezWaRVzygXDtNs0MdO82Vja0e+m9cry0 BVMfsfEVyxRXREMb1Kyb9F5T0WGSTugrH4X2p9veldb6WExGhuBbstJKbJKsQrdZ1+C2 CXxBgk3nuMutZaqFqkrD2cNUjfrbWvLYbbUJX+u9gb95Zb/lCrlxb2YcX179DIalG6bX kYow== 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=5F2XBId6Ml8d60ozFayhTnFPlnF21xMQYH0bLBzTlnY=; b=sHHFcWcaxQjxvpdqZ2uYsjaUtQQIv5dOHkUFsB76gMjCJc82uXb3W4KzgMXCSiSZyO Gh9q7MtVWTLJ8UtsU8AdiBAvJH4Gd7+Fpg7fA/w3WTwpXXCx2908+dnBAUzN76malUBB oIWAdFwZjE4DBfb9VCOM2UEob4ARUmDmR4OoK7pmHCwLAD99DoDnWa21g0X3mzv7Hya1 OUHBUGZ9HkS4zPksyF4NXOpUYyP0t99Q5N2eneWdaF44+/tYz9oRWGqAmosU1Zfka63O YQ0zY+ohoZ3km9mLTXzFQwkUWdq+M5vDdNkZOsp6dChI+VzIk+9oXieS41PEwB5fMV+i KZ7g== X-Gm-Message-State: AOAM5319+oEMGeUvAi8pL+y7r8lkV1AyAFbqlvKAMDdde0CKl+Fwcwfl fIo4/ky1YGKsG1ZdVN1NOCMEcXV6uLo= X-Google-Smtp-Source: ABdhPJyliD4AsBjXCLBTaK2m63jx3rCYhGHEqJklXaxkWK0zm/UKQW1pH50RYWgtA27P4BN9OFdyiRL9jr0= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a25:5844:: with SMTP id m65mr33677475ybb.199.1628067535625; Wed, 04 Aug 2021 01:58:55 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:17 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-20-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 19/21] KVM: arm64: Emulate physical counter offsetting on non-ECV systems From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015857_090251_140A4705 X-CRM114-Status: GOOD ( 22.74 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Unfortunately, ECV hasn't yet arrived in any tangible hardware. At the same time, controlling the guest view of the physical counter-timer is useful. Support guest counter-timer offsetting on non-ECV systems by trapping guest accesses to the physical counter-timer. Emulate reads of the physical counter in the fast exit path. Signed-off-by: Oliver Upton Reviewed-by: Andrew Jones --- arch/arm64/include/asm/sysreg.h | 1 + arch/arm64/kvm/arch_timer.c | 53 +++++++++++++++---------- arch/arm64/kvm/hyp/include/hyp/switch.h | 29 ++++++++++++++ arch/arm64/kvm/hyp/nvhe/timer-sr.c | 11 ++++- 4 files changed, 70 insertions(+), 24 deletions(-) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index c34672aa65b9..e49790ae5da4 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -505,6 +505,7 @@ #define SYS_AMEVCNTR0_MEM_STALL SYS_AMEVCNTR0_EL0(3) #define SYS_CNTFRQ_EL0 sys_reg(3, 3, 14, 0, 0) +#define SYS_CNTPCT_EL0 sys_reg(3, 3, 14, 0, 1) #define SYS_CNTP_TVAL_EL0 sys_reg(3, 3, 14, 2, 0) #define SYS_CNTP_CTL_EL0 sys_reg(3, 3, 14, 2, 1) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 9ead94aa867d..b7cb63acf2a0 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -51,7 +51,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu, static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu, struct arch_timer_context *timer, enum kvm_arch_timer_regs treg); -static void kvm_timer_enable_traps_vhe(void); +static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu); u32 timer_get_ctl(struct arch_timer_context *ctxt) { @@ -175,6 +175,12 @@ static void timer_set_guest_offset(struct arch_timer_context *ctxt, u64 offset) } } +static bool ptimer_emulation_required(struct kvm_vcpu *vcpu) +{ + return timer_get_offset(vcpu_ptimer(vcpu)) && + !cpus_have_const_cap(ARM64_ECV); +} + u64 kvm_phys_timer_read(void) { return timecounter->cc->read(timecounter->cc); @@ -184,8 +190,13 @@ static void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map) { if (has_vhe()) { map->direct_vtimer = vcpu_vtimer(vcpu); - map->direct_ptimer = vcpu_ptimer(vcpu); - map->emul_ptimer = NULL; + if (!ptimer_emulation_required(vcpu)) { + map->direct_ptimer = vcpu_ptimer(vcpu); + map->emul_ptimer = NULL; + } else { + map->direct_ptimer = NULL; + map->emul_ptimer = vcpu_ptimer(vcpu); + } } else { map->direct_vtimer = vcpu_vtimer(vcpu); map->direct_ptimer = NULL; @@ -671,7 +682,7 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu) timer_emulate(map.emul_ptimer); if (has_vhe()) - kvm_timer_enable_traps_vhe(); + kvm_timer_enable_traps_vhe(vcpu); } bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu) @@ -1392,22 +1403,29 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) * The host kernel runs at EL2 with HCR_EL2.TGE == 1, * and this makes those bits have no effect for the host kernel execution. */ -static void kvm_timer_enable_traps_vhe(void) +static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu) { /* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */ u32 cnthctl_shift = 10; - u64 val; + u64 val, mask; + + mask = CNTHCTL_EL1PCEN << cnthctl_shift; + mask |= CNTHCTL_EL1PCTEN << cnthctl_shift; - /* - * VHE systems allow the guest direct access to the EL1 physical - * timer/counter. - */ val = read_sysreg(cnthctl_el2); - val |= (CNTHCTL_EL1PCEN << cnthctl_shift); - val |= (CNTHCTL_EL1PCTEN << cnthctl_shift); if (cpus_have_const_cap(ARM64_ECV)) val |= CNTHCTL_ECV; + + /* + * VHE systems allow the guest direct access to the EL1 physical + * timer/counter if offsetting isn't requested on a non-ECV system. + */ + if (ptimer_emulation_required(vcpu)) + val &= ~mask; + else + val |= mask; + write_sysreg(val, cnthctl_el2); } @@ -1462,9 +1480,6 @@ static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu, u64 __user *uaddr = (u64 __user *)(long)attr->addr; u64 offset; - if (!cpus_have_const_cap(ARM64_ECV)) - return -ENXIO; - if (get_user(offset, uaddr)) return -EFAULT; @@ -1513,9 +1528,6 @@ static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu, u64 __user *uaddr = (u64 __user *)(long)attr->addr; u64 offset; - if (!cpus_have_const_cap(ARM64_ECV)) - return -ENXIO; - offset = timer_get_offset(vcpu_ptimer(vcpu)); return put_user(offset, uaddr); } @@ -1539,11 +1551,8 @@ int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) switch (attr->attr) { case KVM_ARM_VCPU_TIMER_IRQ_VTIMER: case KVM_ARM_VCPU_TIMER_IRQ_PTIMER: - return 0; case KVM_ARM_VCPU_TIMER_OFFSET: - if (cpus_have_const_cap(ARM64_ECV)) - return 0; - break; + return 0; } return -ENXIO; diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index e4a2f295a394..abd3813a709e 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -405,6 +406,31 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu) return true; } +static inline u64 __timer_read_cntpct(struct kvm_vcpu *vcpu) +{ + return __arch_counter_get_cntpct() - vcpu_ptimer(vcpu)->host_offset; +} + +static inline bool __hyp_handle_counter(struct kvm_vcpu *vcpu) +{ + u32 sysreg; + int rt; + u64 rv; + + if (kvm_vcpu_trap_get_class(vcpu) != ESR_ELx_EC_SYS64) + return false; + + sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu)); + if (sysreg != SYS_CNTPCT_EL0) + return false; + + rt = kvm_vcpu_sys_get_rt(vcpu); + rv = __timer_read_cntpct(vcpu); + vcpu_set_reg(vcpu, rt, rv); + __kvm_skip_instr(vcpu); + return true; +} + /* * Return true when we were able to fixup the guest exit and should return to * the guest, false when we should restore the host state and return to the @@ -439,6 +465,9 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) if (*exit_code != ARM_EXCEPTION_TRAP) goto exit; + if (__hyp_handle_counter(vcpu)) + goto guest; + if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) && kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 && handle_tx2_tvm(vcpu)) diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c index 5b8b4cd02506..67236c2e0ba7 100644 --- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c +++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c @@ -44,10 +44,17 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu) /* * Disallow physical timer access for the guest - * Physical counter access is allowed */ val = read_sysreg(cnthctl_el2); val &= ~CNTHCTL_EL1PCEN; - val |= CNTHCTL_EL1PCTEN; + + /* + * Disallow physical counter access for the guest if offsetting is + * requested on a non-ECV system. + */ + if (vcpu_ptimer(vcpu)->host_offset && !cpus_have_const_cap(ARM64_ECV)) + val &= ~CNTHCTL_EL1PCTEN; + else + val |= CNTHCTL_EL1PCTEN; write_sysreg(val, cnthctl_el2); } From patchwork Wed Aug 4 08:58:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418213 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 1506DC4338F for ; Wed, 4 Aug 2021 09:16:32 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C495A60EBB for ; Wed, 4 Aug 2021 09:16:31 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org C495A60EBB Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=hwy7M/Kog3cAOXpaddnATbxWero0ywIPpAkI3A6kcp8=; b=OdbzHts2vPjLfFiFS48F1fQjJ7 dhP5XdofuBD/RGDzK3z6il5LGJT0VkUfkrJeaETcxiKTyoS4hLEfbkisWo+RLuvNg0T1hszDIh5my gcSB3yVXgD/1DwYHuT+9a52tKDf6crUWeVYBjMpH7vTpU6eLtwFSruIMm50uaAoGRlW1Cg5bHC7S+ VBfBtxlVlwIADwnsJST1Gz58NsFAfp4lhgEXucavzRgVrh3jshJxLBR/HMGJ9XR648uxdLFDcVjqs tTo0AYUhf0rvK17VoWNYt21RWZpWDFSO8+AMNln2xr0DHOpv4WoeSxiuh48mIYXPUKfQZVy2SnU4z D3wV29zg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCyS-005Law-SW; Wed, 04 Aug 2021 09:14:06 +0000 Received: from mail-qv1-xf49.google.com ([2607:f8b0:4864:20::f49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjq-005Ff0-0A for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:58:59 +0000 Received: by mail-qv1-xf49.google.com with SMTP id t18-20020a0cd4120000b02902fbda5d4988so1283598qvh.11 for ; Wed, 04 Aug 2021 01:58:57 -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=P+wj7LgLjEuWRbpjKCXjEpBSkxsEIWcdrd+/OVNGjgQ=; b=U2RWOObCpS8DFZJ10Fp2o+XLbL0l1Du9Q2Q9GE9WrsZOYR4vwBJQlSHULYkGmuvObp qkHivooxec/DqyZKsQVcgoEPCJi+6nxBSJa++GLLq4UkYPeTO/PnhQU8BxXCanAd/n3b 1VAAXmzHLRgzm8XB6suWss1/HgHWX8AsDQjtvEEKe6uBRGu5tM62spN1T/IizoXmP1ZL /bcqtSUX18eaq6JGBkF1Jl6CZbI9tnVwffM2msHBTiN69mXBBWf9eO+ZEhofwM/eDIVc AgUFDx/s8u2xV/CUIjyX8OpmxWHZj6alRmINi+u/RPuPYEpQrLqUs/YiaPtSGXJY1Ysc UVRg== 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=P+wj7LgLjEuWRbpjKCXjEpBSkxsEIWcdrd+/OVNGjgQ=; b=YG4RWrMePuTQa78hjX91fzWB2vMpUt4euhtWrPVCwCEsfzRRYRw8Y4EsoafIQQ3fGa e7spR1XxKdfYPgHw4IhcCtum8cb1IvaC5MUio2xpdD1hDKrtPVl3RKTm84T0bLylFEo+ 1MlJqovHNKngzVbPuIpOP6FyBZfLyZ+RlcqkVDvz9yeqLf1h7eqH0fuWDbLBv25Nql4+ QpzS6DnYTR4F2vCOF4MsFxRUlDH4KiBuuP2BLNxmUrNGLu4pkE+P/5F+lJ3jWa2ur1nw TnDJn0pSQzJXHTfoHt3/BRo5zf512n7H/fk5Y+iWcAGmcWc30me5SC8gVOVr7DPtvyyr HGSQ== X-Gm-Message-State: AOAM5325ko6bp1JVJnGrfvL7Bh/+jZxJRyq2P5e0Sog18avnLydM+U32 EV7ZxJ75I+Ykp8u2zWRfF5c1DAlAcFc= X-Google-Smtp-Source: ABdhPJxwuRb6Dx8CoyJvkFTha9TsHjRjV9Svfskn24Ka80JcxAcKjGHT4By5V5+EQXZYVffGDUwuCZ/2cFY= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a05:6214:e67:: with SMTP id jz7mr23858033qvb.0.1628067536659; Wed, 04 Aug 2021 01:58:56 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:18 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-21-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 20/21] selftests: KVM: Test physical counter offsetting From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015858_103121_2138F2C7 X-CRM114-Status: GOOD ( 15.38 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Test that userspace adjustment of the guest physical counter-timer results in the correct view within the guest. Cc: Andrew Jones Signed-off-by: Oliver Upton Reviewed-by: Andrew Jones --- .../selftests/kvm/include/aarch64/processor.h | 12 +++++++ .../kvm/system_counter_offset_test.c | 31 +++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h index 3168cdbae6ee..7f53d90e9512 100644 --- a/tools/testing/selftests/kvm/include/aarch64/processor.h +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h @@ -141,4 +141,16 @@ static inline uint64_t read_cntvct_ordered(void) return r; } +static inline uint64_t read_cntpct_ordered(void) +{ + uint64_t r; + + __asm__ __volatile__("isb\n\t" + "mrs %0, cntpct_el0\n\t" + "isb\n\t" + : "=r"(r)); + + return r; +} + #endif /* SELFTEST_KVM_PROCESSOR_H */ diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c index ac933db83d03..82d26a45cc48 100644 --- a/tools/testing/selftests/kvm/system_counter_offset_test.c +++ b/tools/testing/selftests/kvm/system_counter_offset_test.c @@ -57,6 +57,9 @@ static uint64_t host_read_guest_system_counter(struct test_case *test) enum arch_counter { VIRTUAL, + PHYSICAL, + /* offset physical, read virtual */ + PHYSICAL_READ_VIRTUAL, }; struct test_case { @@ -68,32 +71,54 @@ static struct test_case test_cases[] = { { .counter = VIRTUAL, .offset = 0 }, { .counter = VIRTUAL, .offset = 180 * NSEC_PER_SEC }, { .counter = VIRTUAL, .offset = -180 * NSEC_PER_SEC }, + { .counter = PHYSICAL, .offset = 0 }, + { .counter = PHYSICAL, .offset = 180 * NSEC_PER_SEC }, + { .counter = PHYSICAL, .offset = -180 * NSEC_PER_SEC }, + { .counter = PHYSICAL_READ_VIRTUAL, .offset = 0 }, + { .counter = PHYSICAL_READ_VIRTUAL, .offset = 180 * NSEC_PER_SEC }, + { .counter = PHYSICAL_READ_VIRTUAL, .offset = -180 * NSEC_PER_SEC }, }; static void check_preconditions(struct kvm_vm *vm) { - if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET)) + if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET) && + !_vcpu_has_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL, + KVM_ARM_VCPU_TIMER_OFFSET)) return; - print_skip("KVM_REG_ARM_TIMER_OFFSET not supported; skipping test"); + print_skip("KVM_REG_ARM_TIMER_OFFSET|KVM_ARM_VCPU_TIMER_OFFSET not supported; skipping test"); exit(KSFT_SKIP); } static void setup_system_counter(struct kvm_vm *vm, struct test_case *test) { + uint64_t cntvoff, cntpoff; struct kvm_one_reg reg = { .id = KVM_REG_ARM_TIMER_OFFSET, - .addr = (__u64)&test->offset, + .addr = (__u64)&cntvoff, }; + if (test->counter == VIRTUAL) { + cntvoff = test->offset; + cntpoff = 0; + } else { + cntvoff = 0; + cntpoff = test->offset; + } + vcpu_set_reg(vm, VCPU_ID, ®); + vcpu_access_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL, + KVM_ARM_VCPU_TIMER_OFFSET, &cntpoff, true); } static uint64_t guest_read_system_counter(struct test_case *test) { switch (test->counter) { case VIRTUAL: + case PHYSICAL_READ_VIRTUAL: return read_cntvct_ordered(); + case PHYSICAL: + return read_cntpct_ordered(); default: GUEST_ASSERT(0); } From patchwork Wed Aug 4 08:58:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12418215 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=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 0A0AAC4338F for ; Wed, 4 Aug 2021 09:17:38 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B4FF860F14 for ; Wed, 4 Aug 2021 09:17:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B4FF860F14 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=IRiBTh5jBXnKM2/38mW4NSZJsO6x8wKypMCYqqThG34=; b=sH0TllKofE5EsaU84Q5QW7cehE +d3dY9U8pfaQ4LvToPYqeSQmo2HBcRZ2nAwJS1ger+nSdnPjuhDyy8xAiV1jyk5CWERK3wvUsmwGf QwEqbsacr3yZY4V5xdZblx7oAOgKB+1/k+IIhdmsMJcVvGXhnT43IL6hKSclrWalmmwkuIu5YRS3m K4i+lfUYxvNZOcoJU7U/QFffj5cfPlIc3SoL5cHPJQ6oNTjDZSyvF9tiGaYsCU+t7exUhDb8i1Ggd 1RcbVOtpu2nhMHDrMpW8DlpJHiM9dQRq+vntGljpZxMenvNMlAlbKdG4xPx99o/d6OT5rqYsXG1Sk KjOlv5mw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCzf-005Lz6-CP; Wed, 04 Aug 2021 09:15:21 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBCjr-005Ffh-GB for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 08:59:01 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id j9-20020a2581490000b02905897d81c63fso2250951ybm.8 for ; Wed, 04 Aug 2021 01:58:58 -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=UrN6m22ne+2MDYWmyXjq51ogwq7uHAta0bj5onntA/Q=; b=X4aQIf8yY3OqfJSDV8MlcNYs7slUX/vTpR24OgXx6PSahsoKpv0qisbUa/rdP8tKQY doGothQObaQt5PslknADkm26iL6BfA0QWrR1Mj/mzQ6WzcJyEcJgTs1CizI3TeE8C2Qc ZL7DVu/56+5uybvagLIuXJQEHfHMO7Q+x7dKo+3NotXG6p5YZ7q3+kSsFlShYtAwnCjy eQiB5facl9w8oJAK0Okdq+qDc2gcMUzqP/DhcL/xYm2f1AiWMJWB1n0YVZ1Pm/zfdt3I FHorZUUmFt666pCUyB/NFNmAzWhlF1bNSigEOtoR3kKK4D95DpK11HQcq07BDf8kdicJ 1H3w== 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=UrN6m22ne+2MDYWmyXjq51ogwq7uHAta0bj5onntA/Q=; b=ZP06VPKNdT45TuKwX40da8Z8o07NUuavE+XnZ+2D5FRAbVpdxKU3eWdz6tZPFwRTsD Gd4V2E9hDYBVKI+hOEUnUApxjsn/tnOAOUgvbI7XfCQgjO6PVYpWuyGY42w+AkDNX6UE hHQ8WM3DEUkcONamnIreGBcHndL4G6gGarh6aAWAOUYslDuJlNtQFuvX07oDYYEoYEoS I8t9FDBzB/FIcoGS8huKvOndF6XHikvaheetnB+9mzO+Taua0G/a/S9Crh4aCJFozodB ivZYSWgYsmB5CgQHrhiBqxFUcfxzve320f5Os117ub/vila+C6cpgjqoarRRJsmlC+e+ 9zSQ== X-Gm-Message-State: AOAM533jyViCFhCt59dajMZ0TrW+KAfwGZ1HqbmdxbEojvu2b1cRqiZ+ idwG+vHr3g8h/TO89Ojyv3s4rih7C9E= X-Google-Smtp-Source: ABdhPJxFToUuap9PjZfQaJuBYSR+z/ZU9ES4PaTde5JBTP0latCK18tVERJnR8zhdVc33boETZ6k3PUDCPw= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a25:a241:: with SMTP id b59mr33766938ybi.522.1628067537771; Wed, 04 Aug 2021 01:58:57 -0700 (PDT) Date: Wed, 4 Aug 2021 08:58:19 +0000 In-Reply-To: <20210804085819.846610-1-oupton@google.com> Message-Id: <20210804085819.846610-22-oupton@google.com> Mime-Version: 1.0 References: <20210804085819.846610-1-oupton@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v6 21/21] selftests: KVM: Add counter emulation benchmark From: Oliver Upton To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: Paolo Bonzini , Sean Christopherson , Marc Zyngier , Peter Shier , Jim Mattson , David Matlack , Ricardo Koller , Jing Zhang , Raghavendra Rao Anata , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Will Deacon , Catalin Marinas , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_015859_630432_DEAD2DED X-CRM114-Status: GOOD ( 21.36 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a test case for counter emulation on arm64. A side effect of how KVM handles physical counter offsetting on non-ECV systems is that the virtual counter will always hit hardware and the physical could be emulated. Force emulation by writing a nonzero offset to the physical counter and compare the elapsed cycles to a direct read of the hardware register. Reviewed-by: Ricardo Koller Signed-off-by: Oliver Upton Reviewed-by: Andrew Jones --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../kvm/aarch64/counter_emulation_benchmark.c | 207 ++++++++++++++++++ 3 files changed, 209 insertions(+) create mode 100644 tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index 3d2585f0bffc..a5953f92f6b1 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/counter_emulation_benchmark /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 fab42e7c23ee..d24f7a914992 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -87,6 +87,7 @@ TEST_GEN_PROGS_x86_64 += steal_time TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test TEST_GEN_PROGS_x86_64 += system_counter_offset_test +TEST_GEN_PROGS_aarch64 += aarch64/counter_emulation_benchmark 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/counter_emulation_benchmark.c b/tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c new file mode 100644 index 000000000000..09ff79ab3d6f --- /dev/null +++ b/tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * counter_emulation_benchmark.c -- test to measure the effects of counter + * emulation on guest reads of the physical counter. + * + * Copyright (c) 2021, Google LLC. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include "kvm_util.h" +#include "processor.h" +#include "test_util.h" + +#define VCPU_ID 0 + +static struct counter_values { + uint64_t cntvct_start; + uint64_t cntpct; + uint64_t cntvct_end; +} counter_values; + +static uint64_t nr_iterations = 1000; + +static void do_test(void) +{ + /* + * Open-coded approach instead of using helper methods to keep a tight + * interval around the physical counter read. + */ + asm volatile("isb\n\t" + "mrs %[cntvct_start], cntvct_el0\n\t" + "isb\n\t" + "mrs %[cntpct], cntpct_el0\n\t" + "isb\n\t" + "mrs %[cntvct_end], cntvct_el0\n\t" + "isb\n\t" + : [cntvct_start] "=r"(counter_values.cntvct_start), + [cntpct] "=r"(counter_values.cntpct), + [cntvct_end] "=r"(counter_values.cntvct_end)); +} + +static void guest_main(void) +{ + int i; + + for (i = 0; i < nr_iterations; i++) { + do_test(); + GUEST_SYNC(i); + } + + for (i = 0; i < nr_iterations; i++) { + do_test(); + GUEST_SYNC(i); + } +} + +static void enter_guest(struct kvm_vm *vm) +{ + struct ucall uc; + + vcpu_ioctl(vm, VCPU_ID, KVM_RUN, NULL); + + switch (get_ucall(vm, VCPU_ID, &uc)) { + case UCALL_SYNC: + break; + case UCALL_ABORT: + TEST_ASSERT(false, "%s at %s:%ld", (const char *)uc.args[0], + __FILE__, uc.args[1]); + break; + default: + TEST_ASSERT(false, "unexpected exit: %s", + exit_reason_str(vcpu_state(vm, VCPU_ID)->exit_reason)); + break; + } +} + +static double counter_frequency(void) +{ + uint32_t freq; + + asm volatile("mrs %0, cntfrq_el0" + : "=r" (freq)); + + return freq / 1000000.0; +} + +static void log_csv(FILE *csv, bool trapped) +{ + double freq = counter_frequency(); + + fprintf(csv, "%s,%.02f,%lu,%lu,%lu\n", + trapped ? "true" : "false", freq, + counter_values.cntvct_start, + counter_values.cntpct, + counter_values.cntvct_end); +} + +static double run_loop(struct kvm_vm *vm, FILE *csv, bool trapped) +{ + double avg = 0; + int i; + + for (i = 0; i < nr_iterations; i++) { + uint64_t delta; + + enter_guest(vm); + sync_global_from_guest(vm, counter_values); + + if (csv) + log_csv(csv, trapped); + + delta = counter_values.cntvct_end - counter_values.cntvct_start; + avg = ((avg * i) + delta) / (i + 1); + } + + return avg; +} + +static void setup_counter(struct kvm_vm *vm, uint64_t offset) +{ + vcpu_access_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL, + KVM_ARM_VCPU_TIMER_OFFSET, &offset, + true); +} + +static void run_tests(struct kvm_vm *vm, FILE *csv) +{ + double avg_trapped, avg_native, freq; + + freq = counter_frequency(); + + if (csv) + fputs("trapped,freq_mhz,cntvct_start,cntpct,cntvct_end\n", csv); + + /* no physical offsetting; kvm allows reads of cntpct_el0 */ + setup_counter(vm, 0); + avg_native = run_loop(vm, csv, false); + + /* force emulation of the physical counter */ + setup_counter(vm, 1); + avg_trapped = run_loop(vm, csv, true); + + pr_info("%lu iterations: average cycles (@%.02fMHz) native: %.02f, trapped: %.02f\n", + nr_iterations, freq, avg_native, avg_trapped); +} + +static void usage(const char *program_name) +{ + fprintf(stderr, + "Usage: %s [-h] [-o csv_file] [-n iterations]\n" + " -h prints this message\n" + " -n number of test iterations (default: %lu)\n" + " -o csv file to write data\n", + program_name, nr_iterations); +} + +int main(int argc, char **argv) +{ + struct kvm_vm *vm; + FILE *csv = NULL; + int opt; + + while ((opt = getopt(argc, argv, "hn:o:")) != -1) { + switch (opt) { + case 'o': + csv = fopen(optarg, "w"); + if (!csv) { + fprintf(stderr, "failed to open file '%s': %d\n", + optarg, errno); + exit(1); + } + break; + case 'n': + nr_iterations = strtoul(optarg, NULL, 0); + break; + default: + fprintf(stderr, "unrecognized option: '-%c'\n", opt); + /* fallthrough */ + case 'h': + usage(argv[0]); + exit(1); + } + } + + vm = vm_create_default(VCPU_ID, 0, guest_main); + sync_global_to_guest(vm, nr_iterations); + ucall_init(vm, NULL); + + if (_vcpu_has_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL, + KVM_ARM_VCPU_TIMER_OFFSET)) { + print_skip("KVM_ARM_VCPU_TIMER_OFFSET not supported."); + exit(KSFT_SKIP); + } + + run_tests(vm, csv); + kvm_vm_free(vm); + + if (csv) + fclose(csv); +}