From patchwork Tue Jul 21 04:17:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 11674921 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8397913A4 for ; Tue, 21 Jul 2020 04:19:41 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 5590920792 for ; Tue, 21 Jul 2020 04:19:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="eleqNKZD"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="oDDM7LtH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5590920792 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=+DXiSFyTyOr0UPvc71cwYuxf8vinvFEa05iOrOmDOJk=; b=eleqNKZDusFEFCwVZjYkrvZo2 /doQhxhyISi0bj4MFFxo5NuIbeoh/YKFw5f2yIWJRYWI7k0tcFdNroo2hgMQ5iOr2rogIBHUoDN33 9PscxREFeAwYxPNs1VPAs53CIffnQYgHSu8mH/whHJxw/ggXrkqtoUPgLuN8pdNBKiX1pfQNgf1ri q+OvZdo8XSG/YkO2nL0gedRhoaEMHF4VkNHqWU7BsxpkgxUZMnn2OFCjH33JIwi5eUWDGgHfeaG8I plRCNKBpvInWiRKj6hLl5PfZ00Kuw+v9bi+xAxgISFDTKlmf914WMqdZtxMgcdwz+TAIjja+KO13L tTVfBgLEQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxjjO-0005k5-E5; Tue, 21 Jul 2020 04:18:18 +0000 Received: from mail-pj1-x1041.google.com ([2607:f8b0:4864:20::1041]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jxjjL-0005jD-3V for linux-arm-kernel@lists.infradead.org; Tue, 21 Jul 2020 04:18:16 +0000 Received: by mail-pj1-x1041.google.com with SMTP id 8so359414pjj.1 for ; Mon, 20 Jul 2020 21:18:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=R2tHBpFD/zM6h4tVPj+IrVJrkSfg9TGKlPGPIT24nik=; b=oDDM7LtHqXp5qpYiVH+FGIF7mIeFw9g/H9ceCsGbukvs6IZheFo4rGnwuTYqTjnOki 03STa3SP9VOwJNdHhCUbMJyOnZs0f8h96t7P+jyufj1kK3CMKp+TXeMtdz8WHmv0Gyq3 B9NO1IV9zbuiC7/6SbmNUx7cHgP4dY8qtcGruBUDT0+imgs8aJfPRZyeZH8j6tkhlbWk AfElBlurX1Xx9rnLY8EdqmRmgyMSkZU7eNAfGSPIryTbgk+eFxgt3qdsZd7cbt+dKZIk GfGZGMXncVsr8enfp9zxjyZOHzpxNRGmU0U7bo19wHRH9R/0JZdE8Lsr3lIie2QH+znF YrFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=R2tHBpFD/zM6h4tVPj+IrVJrkSfg9TGKlPGPIT24nik=; b=U+GfJ01bZaeMLFkNvylEohz3A0IB+RzcS19s5EHKgjv1FNTHjJ5IKKywNCSMOBSr6i 2X1ixJ6MLxZegbr8oFacrrTBhc+fFHj9js1Acwmb7lSe/wOqLUqh954HjDT8TQuJrdig vPhYu8oSAcpEjD6SVAav8z17E+WSJSwGJDMFHItXGslL51nSIbyhAh5mQ2mlR2ETnMXV qYCRJS+9sCgJ4QVI8pMeRnHkSJNyW7EVhpabBX7T0hFul9T18I4Zlc3UII7pcE6adb5Y cWRMKAe2xtoCxiVZ1ceWsj06ONJ2x0tzLazpu6s251IsWyIlo6jHjKh6RNu8WwG+FgGK sVyQ== X-Gm-Message-State: AOAM532I5cdEvBqdEuqtPxOe4dXW3iTIO1Y23+SMsxkKH98FpwbTR7MT b/o1+j3LOHlYIIkl8AuW6J0= X-Google-Smtp-Source: ABdhPJz6jDEXiIALuJdwmDFR6vbfWPQbyUI4QPMyQxgQaCt9p5wG5NHhrMHzWwsT8nvAm/+lHWNlWw== X-Received: by 2002:a17:90b:390e:: with SMTP id ob14mr2450924pjb.221.1595305092914; Mon, 20 Jul 2020 21:18:12 -0700 (PDT) Received: from localhost.localdomain ([2409:10:2e40:5100:6e29:95ff:fe2d:8f34]) by smtp.gmail.com with ESMTPSA id e28sm18467270pfm.177.2020.07.20.21.18.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Jul 2020 21:18:12 -0700 (PDT) From: Sergey Senozhatsky To: Will Deacon , Marc Zyngier , James Morse , Julien Thierry , Suzuki K Poulose Subject: [RFC][PATCH 3/4] arm64: add host pvstate support Date: Tue, 21 Jul 2020 13:17:41 +0900 Message-Id: <20200721041742.197354-4-sergey.senozhatsky@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200721041742.197354-1-sergey.senozhatsky@gmail.com> References: <20200721041742.197354-1-sergey.senozhatsky@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200721_001815_196900_5398AEEE X-CRM114-Status: GOOD ( 21.61 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [sergey.senozhatsky[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:1041 listed in] [list.dnswl.org] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: joelaf@google.com, linux-kernel@vger.kernel.org, Sergey Senozhatsky , suleiman@google.com, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Add PV-state support bits to the host. Host uses the guest PV-state per-CPU pointers to update the VCPU state each time it kvm_arch_vcpu_load() or kvm_arch_vcpu_put() the VCPU, so that guest scheduler can become aware of the fact that not all VCPUs are always available. Currently guest scheduler on amr64 always assumes that all CPUs are available because vcpu_is_preempted() is not implemented on arm64. Signed-off-by: Sergey Senozhatsky --- arch/arm64/include/asm/kvm_host.h | 23 ++++++++++++ arch/arm64/kvm/Makefile | 2 +- arch/arm64/kvm/arm.c | 4 +++ arch/arm64/kvm/hypercalls.c | 11 ++++++ arch/arm64/kvm/pvstate.c | 58 +++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/kvm/pvstate.c diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index f6485c1b8c15..e6f325a4ba70 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -372,6 +372,12 @@ struct kvm_vcpu_arch { u64 last_steal; gpa_t base; } steal; + + /* PV state of the VCPU (e.g. vcpu_is_preempted()) */ + struct { + gpa_t base; + struct gfn_to_hva_cache ghc; + } pv_state; }; /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */ @@ -556,6 +562,23 @@ static inline bool kvm_arm_is_pvtime_enabled(struct kvm_vcpu_arch *vcpu_arch) return (vcpu_arch->steal.base != GPA_INVALID); } +int kvm_init_vcpu_state(struct kvm_vcpu *vcpu, gfn_t addr); +int kvm_release_vcpu_state(struct kvm_vcpu *vcpu); + +static inline void kvm_arm_vcpu_state_init(struct kvm_vcpu_arch *vcpu_arch) +{ + vcpu_arch->pv_state.base = GPA_INVALID; + memset(&vcpu_arch->pv_state.ghc, 0x00, sizeof(struct gfn_to_hva_cache)); +} + +static inline bool +kvm_arm_is_vcpu_state_enabled(struct kvm_vcpu_arch *vcpu_arch) +{ + return (vcpu_arch->pv_state.base != GPA_INVALID); +} + +void kvm_update_vcpu_preempted(struct kvm_vcpu *vcpu, bool preempted); + void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 syndrome); struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr); diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 99977c1972cc..efc05ac0d781 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_KVM) += hyp/ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ $(KVM)/vfio.o $(KVM)/irqchip.o \ - arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o \ + arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o pvstate.o \ inject_fault.o regmap.o va_layout.o hyp.o handle_exit.o \ guest.o debug.o reset.o sys_regs.o \ vgic-sys-reg-v3.o fpsimd.o pmu.o \ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 691d21e4c717..a1229e3b7117 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -265,6 +265,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) kvm_arm_pvtime_vcpu_init(&vcpu->arch); + kvm_arm_vcpu_state_init(&vcpu->arch); + vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; err = kvm_vgic_vcpu_init(vcpu); @@ -355,10 +357,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (vcpu_has_ptrauth(vcpu)) vcpu_ptrauth_disable(vcpu); + kvm_update_vcpu_preempted(vcpu, false); } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { + kvm_update_vcpu_preempted(vcpu, true); kvm_arch_vcpu_put_fp(vcpu); if (has_vhe()) kvm_vcpu_put_sysregs_vhe(vcpu); diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 550dfa3e53cd..3660552a8e02 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -52,6 +52,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) case ARM_SMCCC_HV_PV_TIME_FEATURES: val = SMCCC_RET_SUCCESS; break; + case ARM_SMCCC_HV_PV_STATE_FEATURES: + val = SMCCC_RET_SUCCESS; + break; } break; case ARM_SMCCC_HV_PV_TIME_FEATURES: @@ -62,6 +65,14 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) if (gpa != GPA_INVALID) val = gpa; break; + case ARM_SMCCC_HV_PV_STATE_INIT: + if (kvm_init_vcpu_state(vcpu, smccc_get_arg1(vcpu)) == 0) + val = SMCCC_RET_SUCCESS; + break; + case ARM_SMCCC_HV_PV_STATE_RELEASE: + if (kvm_release_vcpu_state(vcpu) == 0) + val = SMCCC_RET_SUCCESS; + break; default: return kvm_psci_call(vcpu); } diff --git a/arch/arm64/kvm/pvstate.c b/arch/arm64/kvm/pvstate.c new file mode 100644 index 000000000000..3152555f3ed2 --- /dev/null +++ b/arch/arm64/kvm/pvstate.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include + +#include +#include + +#include + +int kvm_init_vcpu_state(struct kvm_vcpu *vcpu, gpa_t addr) +{ + if (kvm_arm_is_vcpu_state_enabled(&vcpu->arch)) + return 0; + + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, + &vcpu->arch.pv_state.ghc, + addr, + sizeof(struct pvstate_vcpu_info))) + return -EINVAL; + + vcpu->arch.pv_state.base = addr; + return 0; +} + +int kvm_release_vcpu_state(struct kvm_vcpu *vcpu) +{ + if (!kvm_arm_is_vcpu_state_enabled(&vcpu->arch)) + return 0; + + vcpu->arch.pv_state.base = GPA_INVALID; + return 0; +} + +void kvm_update_vcpu_preempted(struct kvm_vcpu *vcpu, bool preempted) +{ + struct kvm *kvm = vcpu->kvm; + u64 idx; + + if (!kvm_arm_is_vcpu_state_enabled(&vcpu->arch)) + return; + + /* + * This function is called from atomic context, so we need to + * disable page faults. kvm_write_guest_cached() will call + * might_fault(). + */ + pagefault_disable(); + /* + * Need to take the SRCU lock because kvm_write_guest_offset_cached() + * calls kvm_memslots(); + */ + idx = srcu_read_lock(&kvm->srcu); + kvm_write_guest_cached(kvm, &vcpu->arch.pv_state.ghc, + &preempted, sizeof(bool)); + srcu_read_unlock(&kvm->srcu, idx); + pagefault_enable(); +}