[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aca9d389-f11e-4811-90cf-d98e345a5cc2@intel.com>
Date: Mon, 15 Sep 2025 14:55:05 +0800
From: Xiaoyao Li <xiaoyao.li@...el.com>
To: Sean Christopherson <seanjc@...gle.com>,
Paolo Bonzini <pbonzini@...hat.com>
Cc: kvm@...r.kernel.org, linux-kernel@...r.kernel.org,
Tom Lendacky <thomas.lendacky@....com>,
Mathias Krause <minipli@...ecurity.net>, John Allen <john.allen@....com>,
Rick Edgecombe <rick.p.edgecombe@...el.com>, Chao Gao <chao.gao@...el.com>,
Maxim Levitsky <mlevitsk@...hat.com>, Zhang Yi Z <yi.z.zhang@...ux.intel.com>
Subject: Re: [PATCH v15 13/41] KVM: x86: Enable guest SSP read/write interface
with new uAPIs
On 9/13/2025 7:22 AM, Sean Christopherson wrote:
> From: Yang Weijiang <weijiang.yang@...el.com>
>
> Enable guest shadow stack pointer(SSP) access interface with new uAPIs.
> CET guest SSP is HW register which has corresponding VMCS field to save
> and restore guest values when VM-{Exit,Entry} happens. KVM handles SSP
> as a fake/synthetic MSR for userspace access.
>
> Use a translation helper to set up mapping for SSP synthetic index and
> KVM-internal MSR index so that userspace doesn't need to take care of
> KVM's management for synthetic MSRs and avoid conflicts.
>
> Suggested-by: Sean Christopherson <seanjc@...gle.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@...el.com>
> Tested-by: Mathias Krause <minipli@...ecurity.net>
> Tested-by: John Allen <john.allen@....com>
> Tested-by: Rick Edgecombe <rick.p.edgecombe@...el.com>
> Signed-off-by: Chao Gao <chao.gao@...el.com>
> Co-developed-by: Sean Christopherson <seanjc@...gle.com>
> Signed-off-by: Sean Christopherson <seanjc@...gle.com>
> ---
> Documentation/virt/kvm/api.rst | 8 ++++++++
> arch/x86/include/uapi/asm/kvm.h | 3 +++
> arch/x86/kvm/x86.c | 23 +++++++++++++++++++++--
> arch/x86/kvm/x86.h | 10 ++++++++++
> 4 files changed, 42 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index abd02675a24d..6ae24c5ca559 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -2911,6 +2911,14 @@ such as set vcpu counter or reset vcpu, and they have the following id bit patte
> x86 MSR registers have the following id bit patterns::
> 0x2030 0002 <msr number:32>
>
> +Following are the KVM-defined registers for x86:
> +
> +======================= ========= =============================================
> + Encoding Register Description
> +======================= ========= =============================================
> + 0x2030 0003 0000 0000 SSP Shadow Stack Pointer
> +======================= ========= =============================================
> +
> 4.69 KVM_GET_ONE_REG
> --------------------
>
> diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
> index 508b713ca52e..8cc79eca34b2 100644
> --- a/arch/x86/include/uapi/asm/kvm.h
> +++ b/arch/x86/include/uapi/asm/kvm.h
> @@ -437,6 +437,9 @@ struct kvm_xcrs {
> #define KVM_X86_REG_KVM(index) \
> KVM_X86_REG_ENCODE(KVM_X86_REG_TYPE_KVM, index)
>
> +/* KVM-defined registers starting from 0 */
> +#define KVM_REG_GUEST_SSP 0
> +
> #define KVM_SYNC_X86_REGS (1UL << 0)
> #define KVM_SYNC_X86_SREGS (1UL << 1)
> #define KVM_SYNC_X86_EVENTS (1UL << 2)
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 2c9908bc8b32..460ceae11495 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6017,7 +6017,15 @@ struct kvm_x86_reg_id {
>
> static int kvm_translate_kvm_reg(struct kvm_x86_reg_id *reg)
> {
> - return -EINVAL;
> + switch (reg->index) {
> + case KVM_REG_GUEST_SSP:
> + reg->type = KVM_X86_REG_TYPE_MSR;
> + reg->index = MSR_KVM_INTERNAL_GUEST_SSP;
> + break;
> + default:
> + return -EINVAL;
> + }
> + return 0;
> }
>
> static int kvm_get_one_msr(struct kvm_vcpu *vcpu, u32 msr, u64 __user *user_val)
> @@ -6097,11 +6105,22 @@ static int kvm_get_set_one_reg(struct kvm_vcpu *vcpu, unsigned int ioctl,
> static int kvm_get_reg_list(struct kvm_vcpu *vcpu,
> struct kvm_reg_list __user *user_list)
> {
> - u64 nr_regs = 0;
> + u64 nr_regs = guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK) ? 1 : 0;
I wonder what's the semantic of KVM returning KVM_REG_GUEST_SSP on
KVM_GET_REG_LIST. Does it ensure KVM_{G,S}ET_ONE_REG returns -EINVAL on
KVM_REG_GUEST_SSP when it's not enumerated by KVM_GET_REG_LIST?
If so, but KVM_{G,S}ET_ONE_REG can succeed on GUEST_SSP even if
!guest_cpu_cap_has() when @ignore_msrs is true.
> + u64 user_nr_regs;
> +
> + if (get_user(user_nr_regs, &user_list->n))
> + return -EFAULT;
>
> if (put_user(nr_regs, &user_list->n))
> return -EFAULT;
>
> + if (user_nr_regs < nr_regs)
> + return -E2BIG;
> +
> + if (nr_regs &&
> + put_user(KVM_X86_REG_KVM(KVM_REG_GUEST_SSP), &user_list->reg[0]))
> + return -EFAULT;
> +
> return 0;
> }
>
> diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
> index 786e36fcd0fb..a7c9c72fca93 100644
> --- a/arch/x86/kvm/x86.h
> +++ b/arch/x86/kvm/x86.h
> @@ -101,6 +101,16 @@ do { \
> #define KVM_SVM_DEFAULT_PLE_WINDOW_MAX USHRT_MAX
> #define KVM_SVM_DEFAULT_PLE_WINDOW 3000
>
> +/*
> + * KVM's internal, non-ABI indices for synthetic MSRs. The values themselves
> + * are arbitrary and have no meaning, the only requirement is that they don't
> + * conflict with "real" MSRs that KVM supports. Use values at the upper end
> + * of KVM's reserved paravirtual MSR range to minimize churn, i.e. these values
> + * will be usable until KVM exhausts its supply of paravirtual MSR indices.
> + */
> +
> +#define MSR_KVM_INTERNAL_GUEST_SSP 0x4b564dff
> +
> static inline unsigned int __grow_ple_window(unsigned int val,
> unsigned int base, unsigned int modifier, unsigned int max)
> {
Powered by blists - more mailing lists