Message ID | 20230904095347.14994-13-manali.shukla@amd.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Implement support for IBS virtualization | expand |
On 9/4/23 04:53, Manali Shukla wrote: > To enable IBS virtualization capability on non SEV-ES guests, bit 2 > at offset 0xb8 in VMCB is set to 1 for non SEV-ES guests. s/for non SEV-ES guests// > > To enable IBS virtualization capability on SEV-ES guests, bit 12 in > SEV_FEATURES in VMSA is set to 1 for SEV-ES guests. s/for SEV-ES guests// > > Signed-off-by: Manali Shukla <manali.shukla@amd.com> > --- > arch/x86/include/asm/svm.h | 4 ++++ > arch/x86/kvm/svm/sev.c | 5 ++++- > arch/x86/kvm/svm/svm.c | 26 +++++++++++++++++++++++++- > 3 files changed, 33 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h > index 58b60842a3b7..a31bf803b993 100644 > --- a/arch/x86/include/asm/svm.h > +++ b/arch/x86/include/asm/svm.h > @@ -215,6 +215,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area { > #define LBR_CTL_ENABLE_MASK BIT_ULL(0) > #define VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK BIT_ULL(1) > > +#define VIRTUAL_IBS_ENABLE_MASK BIT_ULL(2) > + > #define SVM_INTERRUPT_SHADOW_MASK BIT_ULL(0) > #define SVM_GUEST_INTERRUPT_MASK BIT_ULL(1) > > @@ -259,6 +261,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area { > > #define VMCB_AVIC_APIC_BAR_MASK 0xFFFFFFFFFF000ULL > > +#define SVM_SEV_ES_FEAT_VIBS BIT(12) Based on the SNP series, this shouldn't be added in between all the AVIC features, but rather after them, just before the vmcb_seg struct. And probably best to just call it SVM_SEV_FEAT_VIBS. > + > #define AVIC_UNACCEL_ACCESS_WRITE_MASK 1 > #define AVIC_UNACCEL_ACCESS_OFFSET_MASK 0xFF0 > #define AVIC_UNACCEL_ACCESS_VECTOR_MASK 0xFFFFFFFF > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c > index 41706335cedd..e0ef3a2323d6 100644 > --- a/arch/x86/kvm/svm/sev.c > +++ b/arch/x86/kvm/svm/sev.c > @@ -59,7 +59,7 @@ module_param_named(sev_es, sev_es_enabled, bool, 0444); > #define sev_es_enabled false > #endif /* CONFIG_KVM_AMD_SEV */ > > -static bool sev_es_vibs_enabled; > +static bool sev_es_vibs_enabled = true; No need to change this if you follow my comment from the previous patch. Also, maybe this should just be called sev_es_vibs, since it's more a capability (similar to how in svm.c it is just vibs). > static u8 sev_enc_bit; > static DECLARE_RWSEM(sev_deactivate_lock); > static DEFINE_MUTEX(sev_bitmap_lock); > @@ -607,6 +607,9 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm) > save->xss = svm->vcpu.arch.ia32_xss; > save->dr6 = svm->vcpu.arch.dr6; > > + if (svm->ibs_enabled && sev_es_vibs_enabled) This should solely rely on svm->ibs_enabled, which means that svm->ibs_enabled should have previously been set to false if sev_es_vibs_enabled is false. > + save->sev_features |= SVM_SEV_ES_FEAT_VIBS; > + > pr_debug("Virtual Machine Save Area (VMSA):\n"); > print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false); > > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c > index 0cfe23bb144a..b85120f0d3ac 100644 > --- a/arch/x86/kvm/svm/svm.c > +++ b/arch/x86/kvm/svm/svm.c > @@ -234,7 +234,7 @@ static int lbrv = true; > module_param(lbrv, int, 0444); > > /* enable/disable IBS virtualization */ > -static int vibs; > +static int vibs = true; > module_param(vibs, int, 0444); > > static int tsc_scaling = true; > @@ -1245,10 +1245,13 @@ static inline void init_vmcb_after_set_cpuid(struct kvm_vcpu *vcpu) > /* > * If hardware supports VIBS then no need to intercept IBS MSRS > * when VIBS is enabled in guest. > + * > + * Enable VIBS by setting bit 2 at offset 0xb8 in VMCB. > */ > if (vibs) { > if (guest_cpuid_has(&svm->vcpu, X86_FEATURE_IBS)) { > svm_ibs_msr_interception(svm, false); > + svm->vmcb->control.virt_ext |= VIRTUAL_IBS_ENABLE_MASK; This appears to do this for any type of guest, is this valid to do for SEV-ES guests? Thanks, Tom > svm->ibs_enabled = true; > > /* > @@ -5166,6 +5169,24 @@ static __init void svm_adjust_mmio_mask(void) > kvm_mmu_set_mmio_spte_mask(mask, mask, PT_WRITABLE_MASK | PT_USER_MASK); > } > > +static void svm_ibs_set_cpu_caps(void) > +{ > + kvm_cpu_cap_set(X86_FEATURE_IBS); > + kvm_cpu_cap_set(X86_FEATURE_EXTLVT); > + kvm_cpu_cap_set(X86_FEATURE_EXTAPIC); > + kvm_cpu_cap_set(X86_FEATURE_IBS_AVAIL); > + kvm_cpu_cap_set(X86_FEATURE_IBS_FETCHSAM); > + kvm_cpu_cap_set(X86_FEATURE_IBS_OPSAM); > + kvm_cpu_cap_set(X86_FEATURE_IBS_RDWROPCNT); > + kvm_cpu_cap_set(X86_FEATURE_IBS_OPCNT); > + kvm_cpu_cap_set(X86_FEATURE_IBS_BRNTRGT); > + kvm_cpu_cap_set(X86_FEATURE_IBS_OPCNTEXT); > + kvm_cpu_cap_set(X86_FEATURE_IBS_RIPINVALIDCHK); > + kvm_cpu_cap_set(X86_FEATURE_IBS_OPBRNFUSE); > + kvm_cpu_cap_set(X86_FEATURE_IBS_FETCHCTLEXTD); > + kvm_cpu_cap_set(X86_FEATURE_IBS_ZEN4_EXT); > +} > + > static __init void svm_set_cpu_caps(void) > { > kvm_set_cpu_caps(); > @@ -5208,6 +5229,9 @@ static __init void svm_set_cpu_caps(void) > kvm_cpu_cap_set(X86_FEATURE_SVME_ADDR_CHK); > } > > + if (vibs) > + svm_ibs_set_cpu_caps(); > + > /* CPUID 0x80000008 */ > if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD) || > boot_cpu_has(X86_FEATURE_AMD_SSBD))
>+static void svm_ibs_set_cpu_caps(void) >+{ >+ kvm_cpu_cap_set(X86_FEATURE_IBS); >+ kvm_cpu_cap_set(X86_FEATURE_EXTLVT); >+ kvm_cpu_cap_set(X86_FEATURE_EXTAPIC); EXTLVT is a misnomer to me. It indicates the AVIC change about handling guest's accesses to externed LVTs rather than the presence of extended LVTs (that's what EXTAPIC is for). >+ kvm_cpu_cap_set(X86_FEATURE_IBS_AVAIL); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_FETCHSAM); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_OPSAM); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_RDWROPCNT); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_OPCNT); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_BRNTRGT); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_OPCNTEXT); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_RIPINVALIDCHK); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_OPBRNFUSE); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_FETCHCTLEXTD); >+ kvm_cpu_cap_set(X86_FEATURE_IBS_ZEN4_EXT); any reason for not using kvm_cpu_cap_check_and_set(), which takes hardware capabilities into account?
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 58b60842a3b7..a31bf803b993 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -215,6 +215,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define LBR_CTL_ENABLE_MASK BIT_ULL(0) #define VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK BIT_ULL(1) +#define VIRTUAL_IBS_ENABLE_MASK BIT_ULL(2) + #define SVM_INTERRUPT_SHADOW_MASK BIT_ULL(0) #define SVM_GUEST_INTERRUPT_MASK BIT_ULL(1) @@ -259,6 +261,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define VMCB_AVIC_APIC_BAR_MASK 0xFFFFFFFFFF000ULL +#define SVM_SEV_ES_FEAT_VIBS BIT(12) + #define AVIC_UNACCEL_ACCESS_WRITE_MASK 1 #define AVIC_UNACCEL_ACCESS_OFFSET_MASK 0xFF0 #define AVIC_UNACCEL_ACCESS_VECTOR_MASK 0xFFFFFFFF diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 41706335cedd..e0ef3a2323d6 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -59,7 +59,7 @@ module_param_named(sev_es, sev_es_enabled, bool, 0444); #define sev_es_enabled false #endif /* CONFIG_KVM_AMD_SEV */ -static bool sev_es_vibs_enabled; +static bool sev_es_vibs_enabled = true; static u8 sev_enc_bit; static DECLARE_RWSEM(sev_deactivate_lock); static DEFINE_MUTEX(sev_bitmap_lock); @@ -607,6 +607,9 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm) save->xss = svm->vcpu.arch.ia32_xss; save->dr6 = svm->vcpu.arch.dr6; + if (svm->ibs_enabled && sev_es_vibs_enabled) + save->sev_features |= SVM_SEV_ES_FEAT_VIBS; + pr_debug("Virtual Machine Save Area (VMSA):\n"); print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 0cfe23bb144a..b85120f0d3ac 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -234,7 +234,7 @@ static int lbrv = true; module_param(lbrv, int, 0444); /* enable/disable IBS virtualization */ -static int vibs; +static int vibs = true; module_param(vibs, int, 0444); static int tsc_scaling = true; @@ -1245,10 +1245,13 @@ static inline void init_vmcb_after_set_cpuid(struct kvm_vcpu *vcpu) /* * If hardware supports VIBS then no need to intercept IBS MSRS * when VIBS is enabled in guest. + * + * Enable VIBS by setting bit 2 at offset 0xb8 in VMCB. */ if (vibs) { if (guest_cpuid_has(&svm->vcpu, X86_FEATURE_IBS)) { svm_ibs_msr_interception(svm, false); + svm->vmcb->control.virt_ext |= VIRTUAL_IBS_ENABLE_MASK; svm->ibs_enabled = true; /* @@ -5166,6 +5169,24 @@ static __init void svm_adjust_mmio_mask(void) kvm_mmu_set_mmio_spte_mask(mask, mask, PT_WRITABLE_MASK | PT_USER_MASK); } +static void svm_ibs_set_cpu_caps(void) +{ + kvm_cpu_cap_set(X86_FEATURE_IBS); + kvm_cpu_cap_set(X86_FEATURE_EXTLVT); + kvm_cpu_cap_set(X86_FEATURE_EXTAPIC); + kvm_cpu_cap_set(X86_FEATURE_IBS_AVAIL); + kvm_cpu_cap_set(X86_FEATURE_IBS_FETCHSAM); + kvm_cpu_cap_set(X86_FEATURE_IBS_OPSAM); + kvm_cpu_cap_set(X86_FEATURE_IBS_RDWROPCNT); + kvm_cpu_cap_set(X86_FEATURE_IBS_OPCNT); + kvm_cpu_cap_set(X86_FEATURE_IBS_BRNTRGT); + kvm_cpu_cap_set(X86_FEATURE_IBS_OPCNTEXT); + kvm_cpu_cap_set(X86_FEATURE_IBS_RIPINVALIDCHK); + kvm_cpu_cap_set(X86_FEATURE_IBS_OPBRNFUSE); + kvm_cpu_cap_set(X86_FEATURE_IBS_FETCHCTLEXTD); + kvm_cpu_cap_set(X86_FEATURE_IBS_ZEN4_EXT); +} + static __init void svm_set_cpu_caps(void) { kvm_set_cpu_caps(); @@ -5208,6 +5229,9 @@ static __init void svm_set_cpu_caps(void) kvm_cpu_cap_set(X86_FEATURE_SVME_ADDR_CHK); } + if (vibs) + svm_ibs_set_cpu_caps(); + /* CPUID 0x80000008 */ if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD) || boot_cpu_has(X86_FEATURE_AMD_SSBD))
To enable IBS virtualization capability on non SEV-ES guests, bit 2 at offset 0xb8 in VMCB is set to 1 for non SEV-ES guests. To enable IBS virtualization capability on SEV-ES guests, bit 12 in SEV_FEATURES in VMSA is set to 1 for SEV-ES guests. Signed-off-by: Manali Shukla <manali.shukla@amd.com> --- arch/x86/include/asm/svm.h | 4 ++++ arch/x86/kvm/svm/sev.c | 5 ++++- arch/x86/kvm/svm/svm.c | 26 +++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-)