public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Michael Roth <michael.roth@amd.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: <kvm@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	Sean Christopherson <seanjc@google.com>,
	Brijesh Singh <brijesh.singh@amd.com>,
	Ashish Kalra <ashish.kalra@amd.com>
Subject: [PULL 08/19] KVM: SEV: Add support to handle MSR based Page State Change VMGEXIT
Date: Fri, 10 May 2024 16:10:13 -0500	[thread overview]
Message-ID: <20240510211024.556136-9-michael.roth@amd.com> (raw)
In-Reply-To: <20240510211024.556136-1-michael.roth@amd.com>

SEV-SNP VMs can ask the hypervisor to change the page state in the RMP
table to be private or shared using the Page State Change MSR protocol
as defined in the GHCB specification.

When using gmem, private/shared memory is allocated through separate
pools, and KVM relies on userspace issuing a KVM_SET_MEMORY_ATTRIBUTES
KVM ioctl to tell the KVM MMU whether or not a particular GFN should be
backed by private memory or not.

Forward these page state change requests to userspace so that it can
issue the expected KVM ioctls. The KVM MMU will handle updating the RMP
entries when it is ready to map a private page into a guest.

Use the existing KVM_HC_MAP_GPA_RANGE hypercall format to deliver these
requests to userspace via KVM_EXIT_HYPERCALL.

Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
Message-ID: <20240501085210.2213060-10-michael.roth@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/include/asm/sev-common.h |  6 ++++
 arch/x86/kvm/svm/sev.c            | 48 +++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h
index 1006bfffe07a..6d68db812de1 100644
--- a/arch/x86/include/asm/sev-common.h
+++ b/arch/x86/include/asm/sev-common.h
@@ -101,11 +101,17 @@ enum psc_op {
 	/* GHCBData[11:0] */				\
 	GHCB_MSR_PSC_REQ)
 
+#define GHCB_MSR_PSC_REQ_TO_GFN(msr) (((msr) & GENMASK_ULL(51, 12)) >> 12)
+#define GHCB_MSR_PSC_REQ_TO_OP(msr) (((msr) & GENMASK_ULL(55, 52)) >> 52)
+
 #define GHCB_MSR_PSC_RESP		0x015
 #define GHCB_MSR_PSC_RESP_VAL(val)			\
 	/* GHCBData[63:32] */				\
 	(((u64)(val) & GENMASK_ULL(63, 32)) >> 32)
 
+/* Set highest bit as a generic error response */
+#define GHCB_MSR_PSC_RESP_ERROR (BIT_ULL(63) | GHCB_MSR_PSC_RESP)
+
 /* GHCB Hypervisor Feature Request/Response */
 #define GHCB_MSR_HV_FT_REQ		0x080
 #define GHCB_MSR_HV_FT_RESP		0x081
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 557f462fde04..438f2e8b8152 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3461,6 +3461,48 @@ static void set_ghcb_msr(struct vcpu_svm *svm, u64 value)
 	svm->vmcb->control.ghcb_gpa = value;
 }
 
+static int snp_complete_psc_msr(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+
+	if (vcpu->run->hypercall.ret)
+		set_ghcb_msr(svm, GHCB_MSR_PSC_RESP_ERROR);
+	else
+		set_ghcb_msr(svm, GHCB_MSR_PSC_RESP);
+
+	return 1; /* resume guest */
+}
+
+static int snp_begin_psc_msr(struct vcpu_svm *svm, u64 ghcb_msr)
+{
+	u64 gpa = gfn_to_gpa(GHCB_MSR_PSC_REQ_TO_GFN(ghcb_msr));
+	u8 op = GHCB_MSR_PSC_REQ_TO_OP(ghcb_msr);
+	struct kvm_vcpu *vcpu = &svm->vcpu;
+
+	if (op != SNP_PAGE_STATE_PRIVATE && op != SNP_PAGE_STATE_SHARED) {
+		set_ghcb_msr(svm, GHCB_MSR_PSC_RESP_ERROR);
+		return 1; /* resume guest */
+	}
+
+	if (!(vcpu->kvm->arch.hypercall_exit_enabled & (1 << KVM_HC_MAP_GPA_RANGE))) {
+		set_ghcb_msr(svm, GHCB_MSR_PSC_RESP_ERROR);
+		return 1; /* resume guest */
+	}
+
+	vcpu->run->exit_reason = KVM_EXIT_HYPERCALL;
+	vcpu->run->hypercall.nr = KVM_HC_MAP_GPA_RANGE;
+	vcpu->run->hypercall.args[0] = gpa;
+	vcpu->run->hypercall.args[1] = 1;
+	vcpu->run->hypercall.args[2] = (op == SNP_PAGE_STATE_PRIVATE)
+				       ? KVM_MAP_GPA_RANGE_ENCRYPTED
+				       : KVM_MAP_GPA_RANGE_DECRYPTED;
+	vcpu->run->hypercall.args[2] |= KVM_MAP_GPA_RANGE_PAGE_SZ_4K;
+
+	vcpu->arch.complete_userspace_io = snp_complete_psc_msr;
+
+	return 0; /* forward request to userspace */
+}
+
 static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
 {
 	struct vmcb_control_area *control = &svm->vmcb->control;
@@ -3566,6 +3608,12 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
 				  GHCB_MSR_INFO_POS);
 		break;
 	}
+	case GHCB_MSR_PSC_REQ:
+		if (!sev_snp_guest(vcpu->kvm))
+			goto out_terminate;
+
+		ret = snp_begin_psc_msr(svm, control->ghcb_gpa);
+		break;
 	case GHCB_MSR_TERM_REQ: {
 		u64 reason_set, reason_code;
 
-- 
2.25.1


  parent reply	other threads:[~2024-05-10 21:23 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-10 21:10 [PULL 00/19] KVM: Add AMD Secure Nested Paging (SEV-SNP) Hypervisor Support Michael Roth
2024-05-10 21:10 ` [PULL 01/19] KVM: MMU: Disable fast path if KVM_EXIT_MEMORY_FAULT is needed Michael Roth
2024-05-10 21:10 ` [PULL 02/19] KVM: SEV: Select KVM_GENERIC_PRIVATE_MEM when CONFIG_KVM_AMD_SEV=y Michael Roth
2024-05-10 21:10 ` [PULL 03/19] KVM: SEV: Add initial SEV-SNP support Michael Roth
2024-05-10 21:10 ` [PULL 04/19] KVM: SEV: Add KVM_SEV_SNP_LAUNCH_START command Michael Roth
2024-05-10 21:10 ` [PULL 05/19] KVM: SEV: Add KVM_SEV_SNP_LAUNCH_UPDATE command Michael Roth
2024-05-10 21:10 ` [PULL 06/19] KVM: SEV: Add KVM_SEV_SNP_LAUNCH_FINISH command Michael Roth
2024-05-10 21:10 ` [PULL 07/19] KVM: SEV: Add support to handle GHCB GPA register VMGEXIT Michael Roth
2024-05-10 21:10 ` Michael Roth [this message]
2024-05-10 21:10 ` [PULL 09/19] KVM: SEV: Add support to handle Page State Change VMGEXIT Michael Roth
2024-05-12  2:06   ` Michael Roth
2024-05-10 21:10 ` [PULL 10/19] KVM: SEV: Add support to handle RMP nested page faults Michael Roth
2024-05-10 21:10 ` [PULL 11/19] KVM: SEV: Support SEV-SNP AP Creation NAE event Michael Roth
2024-05-10 21:10 ` [PULL 12/19] KVM: SEV: Implement gmem hook for initializing private pages Michael Roth
2024-05-10 21:10 ` [PULL 13/19] KVM: SEV: Implement gmem hook for invalidating " Michael Roth
2024-05-15 22:32   ` Sean Christopherson
2024-05-16  3:11     ` Michael Roth
2024-05-21 16:55       ` Paolo Bonzini
2024-05-16 12:45     ` Paolo Bonzini
2024-05-10 21:10 ` [PULL 14/19] KVM: x86: Implement hook for determining max NPT mapping level Michael Roth
2024-05-10 21:10 ` [PULL 15/19] KVM: SEV: Avoid WBINVD for HVA-based MMU notifications for SNP Michael Roth
2024-05-10 21:10 ` [PULL 16/19] KVM: SVM: Add module parameter to enable SEV-SNP Michael Roth
2024-05-10 21:10 ` [PULL 17/19] KVM: SEV: Provide support for SNP_GUEST_REQUEST NAE event Michael Roth
2024-05-17 20:41   ` Edgecombe, Rick P
2024-05-17 22:01     ` Paolo Bonzini
2024-05-18 15:04       ` [PATCH] KVM: SEV: Fix guest memory leak when handling guest requests Michael Roth
2024-05-20 14:17         ` Sean Christopherson
2024-05-20 22:50           ` Michael Roth
2024-05-20 23:32             ` Sean Christopherson
2024-05-21  2:00               ` Michael Roth
2024-05-21 14:09                 ` Sean Christopherson
2024-05-21 15:34                   ` Michael Roth
2024-05-21 16:58                     ` Sean Christopherson
2024-05-21 21:00                       ` Michael Roth
2024-05-20 23:02         ` [PATCH v2] " Michael Roth
2024-05-10 21:10 ` [PULL 18/19] KVM: SEV: Provide support for SNP_EXTENDED_GUEST_REQUEST NAE event Michael Roth
2024-05-13 15:19   ` Nathan Chancellor
2024-05-13 16:53     ` Paolo Bonzini
2024-05-13 17:05       ` Michael Roth
2024-05-13 17:20         ` Paolo Bonzini
2024-05-13 21:18         ` Michael Roth
2024-05-10 21:10 ` [PULL 19/19] crypto: ccp: Add the SNP_VLEK_LOAD command Michael Roth
2024-05-12  7:14 ` [PULL 00/19] KVM: Add AMD Secure Nested Paging (SEV-SNP) Hypervisor Support Paolo Bonzini
2024-05-12  8:17   ` Paolo Bonzini
2024-05-13  1:06     ` Michael Roth
2024-05-13 22:08     ` Sean Christopherson
2024-05-31  3:22 ` Michael Roth
2024-06-03 16:44   ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240510211024.556136-9-michael.roth@amd.com \
    --to=michael.roth@amd.com \
    --cc=ashish.kalra@amd.com \
    --cc=brijesh.singh@amd.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox