diff mbox series

[12/13] KVM: SVM: Enable IBS virtualization on non SEV-ES and SEV-ES guests

Message ID 20230904095347.14994-13-manali.shukla@amd.com (mailing list archive)
State New, archived
Headers show
Series Implement support for IBS virtualization | expand

Commit Message

Manali Shukla Sept. 4, 2023, 9:53 a.m. UTC
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(-)

Comments

Tom Lendacky Sept. 5, 2023, 4 p.m. UTC | #1
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))
Chao Gao Sept. 12, 2023, 3:30 a.m. UTC | #2
>+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 mbox series

Patch

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))