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