public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Tom Lendacky <thomas.lendacky@amd.com>
To: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>,
	kvm@vger.kernel.org, seanjc@google.com, pbonzini@redhat.com
Cc: linux-kernel@vger.kernel.org, nikunj@amd.com,
	Santosh.Shukla@amd.com, Vasant.Hegde@amd.com,
	Suravee.Suthikulpanit@amd.com, bp@alien8.de,
	David.Kaplan@amd.com, huibo.wang@amd.com, naveen.rao@amd.com,
	tiala@microsoft.com
Subject: Re: [RFC PATCH v2 12/17] KVM: SVM: Add VMGEXIT handler for Secure AVIC backing page
Date: Tue, 23 Sep 2025 11:02:58 -0500	[thread overview]
Message-ID: <ca0133cd-4cef-8eb8-0698-1a130b40271f@amd.com> (raw)
In-Reply-To: <20250923050317.205482-13-Neeraj.Upadhyay@amd.com>

On 9/23/25 00:03, Neeraj Upadhyay wrote:
> The Secure AVIC hardware requires uninterrupted access to the guest's
> APIC backing page. If this page is not present in the Nested Page Table
> (NPT) during a hardware access, a non-recoverable nested page fault
> occurs. This sets a BUSY flag in the VMSA and causes subsequent
> VMRUNs to fail with an unrecoverable VMEXIT_BUSY, effectively
> killing the vCPU.
> 
> This situation can arise if the backing page resides within a 2MB large
> page in the NPT. If other parts of that large page are modified (e.g.,
> memory state changes), KVM would split the 2MB NPT entry into 4KB
> entries. This process can temporarily zap the PTE for the backing page,
> creating a window for the fatal hardware access.
> 
> Introduce a new GHCB VMGEXIT protocol, SVM_VMGEXIT_SECURE_AVIC, to
> allow the guest to explicitly inform KVM of the APIC backing page's
> location, thereby enabling KVM to guarantee its presence in the NPT.
> 
> Implement two actions for this protocol:
> 
> - SVM_VMGEXIT_SAVIC_REGISTER_BACKING_PAGE:
>   On this request, KVM receives the GPA of the backing page. To prevent
>   the 2MB page-split issue, immediately perform a PSMASH on the GPA by
>   calling sev_handle_rmp_fault(). This proactively breaks any
>   containing 2MB NPT entry into 4KB pages, isolating the backing page's
>   PTE and guaranteeing its presence. Store the GPA for future reference.
> 
> - SVM_VMGEXIT_SAVIC_UNREGISTER_BACKING_PAGE:
>   On this request, clear the stored GPA, releasing KVM from its
>   obligation to maintain the NPT entry. Return the previously
>   registered GPA to the guest.
> 
> This mechanism ensures the stability of the APIC backing page mapping,
> which is critical for the correct operation of Secure AVIC.
> 
> Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
> Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
> Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
> ---
>  arch/x86/include/uapi/asm/svm.h |  3 ++
>  arch/x86/kvm/svm/sev.c          | 59 +++++++++++++++++++++++++++++++++
>  arch/x86/kvm/svm/svm.h          |  1 +
>  3 files changed, 63 insertions(+)
> 
> diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
> index 9c640a521a67..f1ef52e0fab1 100644
> --- a/arch/x86/include/uapi/asm/svm.h
> +++ b/arch/x86/include/uapi/asm/svm.h
> @@ -118,6 +118,9 @@
>  #define SVM_VMGEXIT_AP_CREATE			1
>  #define SVM_VMGEXIT_AP_DESTROY			2
>  #define SVM_VMGEXIT_SNP_RUN_VMPL		0x80000018
> +#define SVM_VMGEXIT_SECURE_AVIC			0x8000001a
> +#define SVM_VMGEXIT_SAVIC_REGISTER_BACKING_PAGE	0
> +#define SVM_VMGEXIT_SAVIC_UNREGISTER_BACKING_PAGE	1
>  #define SVM_VMGEXIT_HV_FEATURES			0x8000fffd
>  #define SVM_VMGEXIT_TERM_REQUEST		0x8000fffe
>  #define SVM_VMGEXIT_TERM_REASON(reason_set, reason_code)	\
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index 7c66aefe428a..3e9cc50f2705 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -3399,6 +3399,15 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
>  		    !kvm_ghcb_rcx_is_valid(svm))
>  			goto vmgexit_err;
>  		break;
> +	case SVM_VMGEXIT_SECURE_AVIC:
> +		if (!sev_savic_active(vcpu->kvm))
> +			goto vmgexit_err;
> +		if (!kvm_ghcb_rax_is_valid(svm))
> +			goto vmgexit_err;
> +		if (svm->vmcb->control.exit_info_1 == SVM_VMGEXIT_SAVIC_REGISTER_BACKING_PAGE)
> +			if (!kvm_ghcb_rbx_is_valid(svm))
> +				goto vmgexit_err;
> +		break;
>  	case SVM_VMGEXIT_MMIO_READ:
>  	case SVM_VMGEXIT_MMIO_WRITE:
>  		if (!kvm_ghcb_sw_scratch_is_valid(svm))
> @@ -4490,6 +4499,53 @@ static bool savic_handle_msr_exit(struct kvm_vcpu *vcpu)
>  	return false;
>  }
>  
> +static int sev_handle_savic_vmgexit(struct vcpu_svm *svm)
> +{
> +	struct kvm_vcpu *vcpu = NULL;

This gets confusing below, how about calling this target_vcpu. Also, it
shouldn't need initializing, right?

> +	u64 apic_id;
> +
> +	apic_id = kvm_rax_read(&svm->vcpu);
> +
> +	if (apic_id == -1ULL) {
> +		vcpu = &svm->vcpu;
> +	} else {
> +		vcpu = kvm_get_vcpu_by_id(vcpu->kvm, apic_id);
> +		if (!vcpu)
> +			goto savic_request_invalid;
> +	}
> +
> +	switch (svm->vmcb->control.exit_info_1) {
> +	case SVM_VMGEXIT_SAVIC_REGISTER_BACKING_PAGE:
> +		gpa_t gpa;
> +
> +		gpa = kvm_rbx_read(&svm->vcpu);
> +		if (!PAGE_ALIGNED(gpa))
> +			goto savic_request_invalid;
> +
> +		/*
> +		 * sev_handle_rmp_fault() invocation would result in PSMASH if
> +		 * NPTE size is 2M.
> +		 */

Why you're invoking sev_handle_rmp_fault() would be more appropriate in
the comment.

Thanks,
Tom

> +		sev_handle_rmp_fault(vcpu, gpa, 0);
> +		to_svm(vcpu)->sev_savic_gpa = gpa;
> +		break;
> +	case SVM_VMGEXIT_SAVIC_UNREGISTER_BACKING_PAGE:
> +		kvm_rbx_write(&svm->vcpu, to_svm(vcpu)->sev_savic_gpa);
> +		to_svm(vcpu)->sev_savic_gpa = 0;
> +		break;
> +	default:
> +		goto savic_request_invalid;
> +	}
> +
> +	return 1;
> +
> +savic_request_invalid:
> +	ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2);
> +	ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_INPUT);
> +
> +	return 1;
> +}
> +
>  int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
>  {
>  	struct vcpu_svm *svm = to_svm(vcpu);
> @@ -4628,6 +4684,9 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
>  			    control->exit_info_1, control->exit_info_2);
>  		ret = -EINVAL;
>  		break;
> +	case SVM_VMGEXIT_SECURE_AVIC:
> +		ret = sev_handle_savic_vmgexit(svm);
> +		break;
>  	case SVM_EXIT_MSR:
>  		if (sev_savic_active(vcpu->kvm) && savic_handle_msr_exit(vcpu))
>  			return 1;
> diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
> index a3edb6e720cd..8043833a1a8c 100644
> --- a/arch/x86/kvm/svm/svm.h
> +++ b/arch/x86/kvm/svm/svm.h
> @@ -337,6 +337,7 @@ struct vcpu_svm {
>  	bool guest_gif;
>  
>  	bool sev_savic_has_pending_ipi;
> +	gpa_t sev_savic_gpa;
>  };
>  
>  struct svm_cpu_data {

  reply	other threads:[~2025-09-23 16:03 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-23  5:03 [RFC PATCH v2 00/17] AMD: Add Secure AVIC KVM Support Neeraj Upadhyay
2025-09-23  5:03 ` [RFC PATCH v2 01/17] KVM: x86/lapic: Differentiate protected APIC interrupt mechanisms Neeraj Upadhyay
2025-09-23  5:03 ` [RFC PATCH v2 02/17] x86/cpufeatures: Add Secure AVIC CPU feature Neeraj Upadhyay
2025-09-23  5:03 ` [RFC PATCH v2 03/17] KVM: SVM: Add support for Secure AVIC capability in KVM Neeraj Upadhyay
2025-09-23  5:03 ` [RFC PATCH v2 04/17] KVM: SVM: Set guest APIC protection flags for Secure AVIC Neeraj Upadhyay
2025-09-23  5:03 ` [RFC PATCH v2 05/17] KVM: SVM: Do not intercept SECURE_AVIC_CONTROL MSR for SAVIC guests Neeraj Upadhyay
2025-09-23 13:55   ` Tom Lendacky
2025-09-25  5:16     ` Upadhyay, Neeraj
2025-09-25 13:54       ` Tom Lendacky
2025-09-23  5:03 ` [RFC PATCH v2 06/17] KVM: SVM: Implement interrupt injection for Secure AVIC Neeraj Upadhyay
2025-09-23 14:47   ` Tom Lendacky
2025-09-23  5:03 ` [RFC PATCH v2 07/17] KVM: SVM: Add IPI Delivery Support " Neeraj Upadhyay
2025-09-23  5:03 ` [RFC PATCH v2 08/17] KVM: SVM: Do not inject exception " Neeraj Upadhyay
2025-09-23 15:00   ` Tom Lendacky
2025-09-23  5:03 ` [RFC PATCH v2 09/17] KVM: SVM: Do not intercept exceptions for Secure AVIC guests Neeraj Upadhyay
2025-09-23 15:15   ` Tom Lendacky
2025-09-23  5:03 ` [RFC PATCH v2 10/17] KVM: SVM: Set VGIF in VMSA area " Neeraj Upadhyay
2025-09-23 15:16   ` Tom Lendacky
2025-09-23  5:03 ` [RFC PATCH v2 11/17] KVM: SVM: Enable NMI support " Neeraj Upadhyay
2025-09-23 15:25   ` Tom Lendacky
2025-09-23  5:03 ` [RFC PATCH v2 12/17] KVM: SVM: Add VMGEXIT handler for Secure AVIC backing page Neeraj Upadhyay
2025-09-23 16:02   ` Tom Lendacky [this message]
2025-09-23  5:03 ` [RFC PATCH v2 13/17] KVM: SVM: Add IOAPIC EOI support for Secure AVIC guests Neeraj Upadhyay
2025-09-23 16:15   ` Tom Lendacky
2025-09-23  5:03 ` [RFC PATCH v2 14/17] KVM: x86/ioapic: Disable RTC EOI tracking for protected APIC guests Neeraj Upadhyay
2025-09-23 16:23   ` Tom Lendacky
2025-09-23  5:03 ` [RFC PATCH v2 15/17] KVM: SVM: Check injected timers for Secure AVIC guests Neeraj Upadhyay
2025-09-23 16:32   ` Tom Lendacky
2025-09-23  5:03 ` [RFC PATCH v2 16/17] KVM: x86/cpuid: Disable paravirt APIC features for protected APIC Neeraj Upadhyay
2025-09-23  5:03 ` [RFC PATCH v2 17/17] KVM: SVM: Advertise Secure AVIC support for SNP guests Neeraj Upadhyay
2025-09-23 10:02 ` [syzbot ci] Re: AMD: Add Secure AVIC KVM Support syzbot ci
2025-09-23 10:17   ` Upadhyay, Neeraj

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=ca0133cd-4cef-8eb8-0698-1a130b40271f@amd.com \
    --to=thomas.lendacky@amd.com \
    --cc=David.Kaplan@amd.com \
    --cc=Neeraj.Upadhyay@amd.com \
    --cc=Santosh.Shukla@amd.com \
    --cc=Suravee.Suthikulpanit@amd.com \
    --cc=Vasant.Hegde@amd.com \
    --cc=bp@alien8.de \
    --cc=huibo.wang@amd.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=naveen.rao@amd.com \
    --cc=nikunj@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=tiala@microsoft.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