On Thu, Nov 02, 2023 at 08:10:58PM +0200, Maxim Levitsky wrote: > On Tue, 2023-10-10 at 20:02 +0000, John Allen wrote: > > When a guest issues a cpuid instruction for Fn0000000D_x0B > > (CetUserOffset), KVM will intercept and need to access the guest > > MSR_IA32_XSS value. For SEV-ES, this is encrypted and needs to be > > included in the GHCB to be visible to the hypervisor. > > > > Signed-off-by: John Allen <john.allen@xxxxxxx> > > --- > > arch/x86/include/asm/svm.h | 1 + > > arch/x86/kvm/svm/sev.c | 12 ++++++++++-- > > arch/x86/kvm/svm/svm.c | 1 + > > arch/x86/kvm/svm/svm.h | 3 ++- > > 4 files changed, 14 insertions(+), 3 deletions(-) > > > > diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h > > index 568d97084e44..5afc9e03379d 100644 > > --- a/arch/x86/include/asm/svm.h > > +++ b/arch/x86/include/asm/svm.h > > @@ -678,5 +678,6 @@ DEFINE_GHCB_ACCESSORS(sw_exit_info_1) > > DEFINE_GHCB_ACCESSORS(sw_exit_info_2) > > DEFINE_GHCB_ACCESSORS(sw_scratch) > > DEFINE_GHCB_ACCESSORS(xcr0) > > +DEFINE_GHCB_ACCESSORS(xss) > > I don't see anywhere in the patch adding xss to ghcb_save_area. > What kernel version/commit these patches are based on? Looks like it first got added to the vmcb save area here: 861377730aa9db4cbaa0f3bd3f4d295c152732c4 It was included in the ghcb save area when it was created it looks like: a4690359eaec985a1351786da887df1ba92440a0 Unless I'm misunderstanding the ask. Is there somewhere else this needs to be added? Thanks, John > > > > > #endif > > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c > > index bb4b18baa6f7..94ab7203525f 100644 > > --- a/arch/x86/kvm/svm/sev.c > > +++ b/arch/x86/kvm/svm/sev.c > > @@ -2445,8 +2445,13 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) > > > > svm->vmcb->save.cpl = kvm_ghcb_get_cpl_if_valid(svm, ghcb); > > > > - if (kvm_ghcb_xcr0_is_valid(svm)) { > > - vcpu->arch.xcr0 = ghcb_get_xcr0(ghcb); > > + if (kvm_ghcb_xcr0_is_valid(svm) || kvm_ghcb_xss_is_valid(svm)) { > > + if (kvm_ghcb_xcr0_is_valid(svm)) > > + vcpu->arch.xcr0 = ghcb_get_xcr0(ghcb); > > + > > + if (kvm_ghcb_xss_is_valid(svm)) > > + vcpu->arch.ia32_xss = ghcb_get_xss(ghcb); > > + > > kvm_update_cpuid_runtime(vcpu); > > } > > > > @@ -3032,6 +3037,9 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm) > > if (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP)) > > svm_clr_intercept(svm, INTERCEPT_RDTSCP); > > } > > + > > + if (kvm_caps.supported_xss) > > + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_XSS, 1, 1); > > This is not just a virtualization hole. This allows the guest to set MSR_IA32_XSS > to whatever value it wants, and thus it might allow XSAVES to access some host msrs > that guest must not be able to access. > > AMD might not yet have such msrs, but on Intel side I do see various components > like 'HDC State', 'HWP state' and such. > > I understand that this is needed so that #VC handler could read this msr, and trying > to read it will cause another #VC which is probably not allowed (I don't know this detail of SEV-ES) > > I guess #VC handler should instead use a kernel cached value of this msr instead, or at least > KVM should only allow reads and not writes to it. > > In addition to that, if we decide to open the read access to the IA32_XSS from the guest, > this IMHO should be done in a separate patch. > > Best regards, > Maxim Levitsky > > > > } > > > > void sev_init_vmcb(struct vcpu_svm *svm) > > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c > > index 984e89d7a734..ee7c7d0a09ab 100644 > > --- a/arch/x86/kvm/svm/svm.c > > +++ b/arch/x86/kvm/svm/svm.c > > @@ -146,6 +146,7 @@ static const struct svm_direct_access_msrs { > > { .index = MSR_IA32_PL1_SSP, .always = false }, > > { .index = MSR_IA32_PL2_SSP, .always = false }, > > { .index = MSR_IA32_PL3_SSP, .always = false }, > > + { .index = MSR_IA32_XSS, .always = false }, > > { .index = MSR_INVALID, .always = false }, > > }; > > > > diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h > > index bdc39003b955..2011456d2e9f 100644 > > --- a/arch/x86/kvm/svm/svm.h > > +++ b/arch/x86/kvm/svm/svm.h > > @@ -30,7 +30,7 @@ > > #define IOPM_SIZE PAGE_SIZE * 3 > > #define MSRPM_SIZE PAGE_SIZE * 2 > > > > -#define MAX_DIRECT_ACCESS_MSRS 53 > > +#define MAX_DIRECT_ACCESS_MSRS 54 > > #define MSRPM_OFFSETS 32 > > extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; > > extern bool npt_enabled; > > @@ -720,5 +720,6 @@ DEFINE_KVM_GHCB_ACCESSORS(sw_exit_info_1) > > DEFINE_KVM_GHCB_ACCESSORS(sw_exit_info_2) > > DEFINE_KVM_GHCB_ACCESSORS(sw_scratch) > > DEFINE_KVM_GHCB_ACCESSORS(xcr0) > > +DEFINE_KVM_GHCB_ACCESSORS(xss) > > > > #endif > > > >