Re: [PATCH v12 06/24] KVM: x86: Introduce KVM_{G,S}ET_ONE_REG uAPIs support

From: Sean Christopherson
Date: Tue Aug 19 2025 - 13:38:27 EST


On Mon, Aug 11, 2025, Chao Gao wrote:
> From: Yang Weijiang <weijiang.yang@xxxxxxxxx>
>
> Enable KVM_{G,S}ET_ONE_REG uAPIs so that userspace can access HW MSR or
> KVM synthetic MSR through it.
>
> In CET KVM series [1], KVM "steals" an MSR from PV MSR space and access
> it via KVM_{G,S}ET_MSRs uAPIs, but the approach pollutes PV MSR space
> and hides the difference of synthetic MSRs and normal HW defined MSRs.
>
> Now carve out a separate room in KVM-customized MSR address space for
> synthetic MSRs. The synthetic MSRs are not exposed to userspace via
> KVM_GET_MSR_INDEX_LIST, instead userspace complies with KVM's setup and
> composes the uAPI params. KVM synthetic MSR indices start from 0 and
> increase linearly. Userspace caller should tag MSR type correctly in
> order to access intended HW or synthetic MSR.
>
> Suggested-by: Sean Christopherson <seanjc@xxxxxxxxxx>
> Signed-off-by: Yang Weijiang <weijiang.yang@xxxxxxxxx>
> Link: https://lore.kernel.org/all/20240219074733.122080-18-weijiang.yang@xxxxxxxxx/ [1]
> Tested-by: Mathias Krause <minipli@xxxxxxxxxxxxxx>
> Tested-by: John Allen <john.allen@xxxxxxx>
> Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx>
> ---
> arch/x86/include/uapi/asm/kvm.h | 10 +++++
> arch/x86/kvm/x86.c | 66 +++++++++++++++++++++++++++++++++
> 2 files changed, 76 insertions(+)
>
> diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
> index 0f15d683817d..e72d9e6c1739 100644
> --- a/arch/x86/include/uapi/asm/kvm.h
> +++ b/arch/x86/include/uapi/asm/kvm.h
> @@ -411,6 +411,16 @@ struct kvm_xcrs {
> __u64 padding[16];
> };
>
> +#define KVM_X86_REG_MSR (1 << 2)
> +#define KVM_X86_REG_SYNTHETIC (1 << 3)
> +
> +struct kvm_x86_reg_id {
> + __u32 index;
> + __u8 type;
> + __u8 rsvd;
> + __u16 rsvd16;
> +};

Some feedback from a while back never got addressed[*]. That feedback still
looks sane/good, so this for the uAPI:

--
#define KVM_X86_REG_TYPE_MSR 2ull

#define KVM_x86_REG_TYPE_SIZE(type) \
{( \
__u64 type_size = type; \
\
type_size |= type == KVM_X86_REG_TYPE_MSR ? KVM_REG_SIZE_U64 : \
type == KVM_X86_REG_TYPE_SYNTHETIC_MSR ? KVM_REG_SIZE_U64 :\
0; \
type_size; \
})

#define KVM_X86_REG_ENCODE(type, index) \
(KVM_REG_X86 | KVM_X86_REG_TYPE_SIZE(type) | index)

#define KVM_X86_REG_MSR(index) KVM_X86_REG_ENCODE(KVM_X86_REG_TYPE_MSR, index)
--

And then the kernel-only struct overlay becomes:

--
struct kvm_x86_reg_id {
__u32 index;
__u8 type;
__u8 rsvd;
__u8 rsvd4:4;
__u8 size:4;
__u8 x86;
}
--

[*] https://lore.kernel.org/all/ZuGpJtEPv1NtdYwM@xxxxxxxxxx