All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes
@ 2022-05-04  7:31 Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 01/14] x86/cpufeatures: Introduce x2AVIC CPUID bit Suravee Suthikulpanit
                   ` (13 more replies)
  0 siblings, 14 replies; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

Introducing support for AMD x2APIC virtualization. This feature is
indicated by the CPUID Fn8000_000A EDX[14], and it can be activated
by setting bit 31 (enable AVIC) and bit 30 (x2APIC mode) of VMCB
offset 60h.

With x2AVIC support, the guest local APIC can be fully virtualized in
both xAPIC and x2APIC modes, and the mode can be changed during runtime.
For example, when AVIC is enabled, the hypervisor set VMCB bit 31
to activate AVIC for each vCPU. Then, it keeps track of each vCPU's
APIC mode, and updates VMCB bit 30 to enable/disable x2APIC
virtualization mode accordingly.

Besides setting bit VMCB bit 30 and 31, for x2AVIC, kvm_amd driver needs
to disable interception for the x2APIC MSR range to allow AVIC hardware
to virtualize register accesses.

This series also introduce a partial APIC virtualization (hybrid-AVIC)
mode, where APIC register accesses are trapped (i.e. not virtualized
by hardware), but leverage AVIC doorbell for interrupt injection.
This eliminates need to disable x2APIC in the guest on system without
x2AVIC support. (Note: suggested by Maxim)

Regards,
Suravee

Testing for v3:
  * Tested booting a Linux VM with x2APIC physical and logical modes upto 512 vCPUs.
  * Test enable AVIC in L0 with xAPIC and x2AVIC modes in L1 and launch L2 guest
  * Test partial AVIC mode by launching a VM with x2APIC mode

Changes from v2
(https://lore.kernel.org/all/20220412115822.14351-1-suravee.suthikulpanit@amd.com/)
  * Rebase to kvm/queue
  * Patch  3: Moving force_avic option declaration to avic.c
  * Patch  7: Change to only setup x2APIC msrs supported by x2AVIC in svm_direct_access_msrs.
  * Patch  8: Add back avic_refresh_apicv_exec_ctrl() in avic_set_virtual_apic_mode()
  * Patch  9: Update avic_set_x2apic_msr_interception() logic
  * Patch 11: Introduce hybrid-AVIC mode (NEW)
  * Patch 12: Modify warning to check for vcpu with xAPIC or x2APIC mode only.
  * Patch 13: Add support for avic_kick_target_vcpus_fast() (NEW)
  * Patch 14: Add doorbell tracepoint (NEW)

Suravee Suthikulpanit (14):
  x86/cpufeatures: Introduce x2AVIC CPUID bit
  KVM: x86: lapic: Rename [GET/SET]_APIC_DEST_FIELD to
    [GET/SET]_XAPIC_DEST_FIELD
  KVM: SVM: Detect X2APIC virtualization (x2AVIC) support
  KVM: SVM: Update max number of vCPUs supported for x2AVIC mode
  KVM: SVM: Update avic_kick_target_vcpus to support 32-bit APIC ID
  KVM: SVM: Do not support updating APIC ID when in x2APIC mode
  KVM: SVM: Adding support for configuring x2APIC MSRs interception
  KVM: SVM: Update AVIC settings when changing APIC mode
  KVM: SVM: Introduce helper functions to (de)activate AVIC and x2AVIC
  KVM: SVM: Do not throw warning when calling avic_vcpu_load on a
    running vcpu
  KVM: SVM: Introduce hybrid-AVIC mode
  kvm/x86: Warning APICv inconsistency only when vcpu APIC mode is valid
  KVM: SVM: Use target APIC ID to complete x2AVIC IRQs when possible
  KVM: SVM: Add AVIC doorbell tracepoint

 arch/x86/hyperv/hv_apic.c          |   2 +-
 arch/x86/include/asm/apicdef.h     |   4 +-
 arch/x86/include/asm/cpufeatures.h |   1 +
 arch/x86/include/asm/svm.h         |  21 +++-
 arch/x86/kernel/apic/apic.c        |   2 +-
 arch/x86/kernel/apic/ipi.c         |   2 +-
 arch/x86/kvm/lapic.c               |   2 +-
 arch/x86/kvm/svm/avic.c            | 181 ++++++++++++++++++++++++++---
 arch/x86/kvm/svm/svm.c             |  56 ++++-----
 arch/x86/kvm/svm/svm.h             |   6 +-
 arch/x86/kvm/trace.h               |  18 +++
 arch/x86/kvm/x86.c                 |   8 +-
 12 files changed, 251 insertions(+), 52 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 01/14] x86/cpufeatures: Introduce x2AVIC CPUID bit
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 02/14] KVM: x86: lapic: Rename [GET/SET]_APIC_DEST_FIELD to [GET/SET]_XAPIC_DEST_FIELD Suravee Suthikulpanit
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

Introduce a new feature bit for virtualized x2APIC (x2AVIC) in
CPUID_Fn8000000A_EDX [SVM Revision and Feature Identification].

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/include/asm/cpufeatures.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 1d6826eac3e6..2721bd1e8e1e 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -343,6 +343,7 @@
 #define X86_FEATURE_AVIC		(15*32+13) /* Virtual Interrupt Controller */
 #define X86_FEATURE_V_VMSAVE_VMLOAD	(15*32+15) /* Virtual VMSAVE VMLOAD */
 #define X86_FEATURE_VGIF		(15*32+16) /* Virtual GIF */
+#define X86_FEATURE_X2AVIC		(15*32+18) /* Virtual x2apic */
 #define X86_FEATURE_V_SPEC_CTRL		(15*32+20) /* Virtual SPEC_CTRL */
 #define X86_FEATURE_SVME_ADDR_CHK	(15*32+28) /* "" SVME addr check */
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 02/14] KVM: x86: lapic: Rename [GET/SET]_APIC_DEST_FIELD to [GET/SET]_XAPIC_DEST_FIELD
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 01/14] x86/cpufeatures: Introduce x2AVIC CPUID bit Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 03/14] KVM: SVM: Detect X2APIC virtualization (x2AVIC) support Suravee Suthikulpanit
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

To signify that the macros only support 8-bit xAPIC destination ID.

Suggested-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/hyperv/hv_apic.c      | 2 +-
 arch/x86/include/asm/apicdef.h | 4 ++--
 arch/x86/kernel/apic/apic.c    | 2 +-
 arch/x86/kernel/apic/ipi.c     | 2 +-
 arch/x86/kvm/lapic.c           | 2 +-
 arch/x86/kvm/svm/avic.c        | 4 ++--
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index db2d92fb44da..fb8b2c088681 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -46,7 +46,7 @@ static void hv_apic_icr_write(u32 low, u32 id)
 {
 	u64 reg_val;
 
-	reg_val = SET_APIC_DEST_FIELD(id);
+	reg_val = SET_XAPIC_DEST_FIELD(id);
 	reg_val = reg_val << 32;
 	reg_val |= low;
 
diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index 5716f22f81ac..863c2cad5872 100644
--- a/arch/x86/include/asm/apicdef.h
+++ b/arch/x86/include/asm/apicdef.h
@@ -89,8 +89,8 @@
 #define		APIC_DM_EXTINT		0x00700
 #define		APIC_VECTOR_MASK	0x000FF
 #define	APIC_ICR2	0x310
-#define		GET_APIC_DEST_FIELD(x)	(((x) >> 24) & 0xFF)
-#define		SET_APIC_DEST_FIELD(x)	((x) << 24)
+#define		GET_XAPIC_DEST_FIELD(x)	(((x) >> 24) & 0xFF)
+#define		SET_XAPIC_DEST_FIELD(x)	((x) << 24)
 #define	APIC_LVTT	0x320
 #define	APIC_LVTTHMR	0x330
 #define	APIC_LVTPC	0x340
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index b70344bf6600..e6b754e43ed7 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -275,7 +275,7 @@ void native_apic_icr_write(u32 low, u32 id)
 	unsigned long flags;
 
 	local_irq_save(flags);
-	apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id));
+	apic_write(APIC_ICR2, SET_XAPIC_DEST_FIELD(id));
 	apic_write(APIC_ICR, low);
 	local_irq_restore(flags);
 }
diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c
index d1fb874fbe64..2a6509e8c840 100644
--- a/arch/x86/kernel/apic/ipi.c
+++ b/arch/x86/kernel/apic/ipi.c
@@ -99,7 +99,7 @@ void native_send_call_func_ipi(const struct cpumask *mask)
 
 static inline int __prepare_ICR2(unsigned int mask)
 {
-	return SET_APIC_DEST_FIELD(mask);
+	return SET_XAPIC_DEST_FIELD(mask);
 }
 
 static inline void __xapic_wait_icr_idle(void)
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 137c3a2f5180..8b8c4a905976 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1326,7 +1326,7 @@ void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 icr_low, u32 icr_high)
 	if (apic_x2apic_mode(apic))
 		irq.dest_id = icr_high;
 	else
-		irq.dest_id = GET_APIC_DEST_FIELD(icr_high);
+		irq.dest_id = GET_XAPIC_DEST_FIELD(icr_high);
 
 	trace_kvm_apic_ipi(icr_low, irq.dest_id);
 
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 54fe03714f8a..a8f514212b87 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -328,7 +328,7 @@ static int avic_kick_target_vcpus_fast(struct kvm *kvm, struct kvm_lapic *source
 	if (apic_x2apic_mode(vcpu->arch.apic))
 		dest = icrh;
 	else
-		dest = GET_APIC_DEST_FIELD(icrh);
+		dest = GET_XAPIC_DEST_FIELD(icrh);
 
 	/*
 	 * Try matching the destination APIC ID with the vCPU.
@@ -364,7 +364,7 @@ static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source,
 	 */
 	kvm_for_each_vcpu(i, vcpu, kvm) {
 		if (kvm_apic_match_dest(vcpu, source, icrl & APIC_SHORT_MASK,
-					GET_APIC_DEST_FIELD(icrh),
+					GET_XAPIC_DEST_FIELD(icrh),
 					icrl & APIC_DEST_MASK)) {
 			vcpu->arch.apic->irr_pending = true;
 			svm_complete_interrupt_delivery(vcpu,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 03/14] KVM: SVM: Detect X2APIC virtualization (x2AVIC) support
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 01/14] x86/cpufeatures: Introduce x2AVIC CPUID bit Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 02/14] KVM: x86: lapic: Rename [GET/SET]_APIC_DEST_FIELD to [GET/SET]_XAPIC_DEST_FIELD Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04 12:12   ` Maxim Levitsky
  2022-05-04  7:31 ` [PATCH v3 04/14] KVM: SVM: Update max number of vCPUs supported for x2AVIC mode Suravee Suthikulpanit
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

Add CPUID check for the x2APIC virtualization (x2AVIC) feature.
If available, the SVM driver can support both AVIC and x2AVIC modes
when load the kvm_amd driver with avic=1. The operating mode will be
determined at runtime depending on the guest APIC mode.

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/include/asm/svm.h |  3 +++
 arch/x86/kvm/svm/avic.c    | 40 ++++++++++++++++++++++++++++++++++++++
 arch/x86/kvm/svm/svm.c     | 15 ++------------
 arch/x86/kvm/svm/svm.h     |  1 +
 4 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f70a5108d464..2c2a104b777e 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -195,6 +195,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
 #define AVIC_ENABLE_SHIFT 31
 #define AVIC_ENABLE_MASK (1 << AVIC_ENABLE_SHIFT)
 
+#define X2APIC_MODE_SHIFT 30
+#define X2APIC_MODE_MASK (1 << X2APIC_MODE_SHIFT)
+
 #define LBR_CTL_ENABLE_MASK BIT_ULL(0)
 #define VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK BIT_ULL(1)
 
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index a8f514212b87..fc3ba6071482 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -40,6 +40,15 @@
 #define AVIC_GATAG_TO_VMID(x)		((x >> AVIC_VCPU_ID_BITS) & AVIC_VM_ID_MASK)
 #define AVIC_GATAG_TO_VCPUID(x)		(x & AVIC_VCPU_ID_MASK)
 
+enum avic_modes {
+	AVIC_MODE_NONE = 0,
+	AVIC_MODE_X1,
+	AVIC_MODE_X2,
+};
+
+static bool force_avic;
+module_param_unsafe(force_avic, bool, 0444);
+
 /* Note:
  * This hash table is used to map VM_ID to a struct kvm_svm,
  * when handling AMD IOMMU GALOG notification to schedule in
@@ -50,6 +59,7 @@ static DEFINE_HASHTABLE(svm_vm_data_hash, SVM_VM_DATA_HASH_BITS);
 static u32 next_vm_id = 0;
 static bool next_vm_id_wrapped = 0;
 static DEFINE_SPINLOCK(svm_vm_data_hash_lock);
+static enum avic_modes avic_mode;
 
 /*
  * This is a wrapper of struct amd_iommu_ir_data.
@@ -1077,3 +1087,33 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
 
 	avic_vcpu_load(vcpu);
 }
+
+/*
+ * Note:
+ * - The module param avic enable both xAPIC and x2APIC mode.
+ * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
+ * - The mode can be switched at run-time.
+ */
+bool avic_hardware_setup(struct kvm_x86_ops *x86_ops)
+{
+	if (!npt_enabled)
+		return false;
+
+	if (boot_cpu_has(X86_FEATURE_AVIC)) {
+		avic_mode = AVIC_MODE_X1;
+		pr_info("AVIC enabled\n");
+	} else if (force_avic) {
+		pr_warn("AVIC is not supported in CPUID but force enabled");
+		pr_warn("Your system might crash and burn");
+	}
+
+	if (boot_cpu_has(X86_FEATURE_X2AVIC)) {
+		avic_mode = AVIC_MODE_X2;
+		pr_info("x2AVIC enabled\n");
+	}
+
+	if (avic_mode != AVIC_MODE_NONE)
+		amd_iommu_register_ga_log_notifier(&avic_ga_log_notifier);
+
+	return !!avic_mode;
+}
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 3b49337998ec..74e6f86f5dc3 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -188,9 +188,6 @@ module_param(tsc_scaling, int, 0444);
 static bool avic;
 module_param(avic, bool, 0444);
 
-static bool force_avic;
-module_param_unsafe(force_avic, bool, 0444);
-
 bool __read_mostly dump_invalid_vmcb;
 module_param(dump_invalid_vmcb, bool, 0644);
 
@@ -4913,17 +4910,9 @@ static __init int svm_hardware_setup(void)
 			nrips = false;
 	}
 
-	enable_apicv = avic = avic && npt_enabled && (boot_cpu_has(X86_FEATURE_AVIC) || force_avic);
+	enable_apicv = avic = avic && avic_hardware_setup(&svm_x86_ops);
 
-	if (enable_apicv) {
-		if (!boot_cpu_has(X86_FEATURE_AVIC)) {
-			pr_warn("AVIC is not supported in CPUID but force enabled");
-			pr_warn("Your system might crash and burn");
-		} else
-			pr_info("AVIC enabled\n");
-
-		amd_iommu_register_ga_log_notifier(&avic_ga_log_notifier);
-	} else {
+	if (!enable_apicv) {
 		svm_x86_ops.vcpu_blocking = NULL;
 		svm_x86_ops.vcpu_unblocking = NULL;
 		svm_x86_ops.vcpu_get_apicv_inhibit_reasons = NULL;
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 32220a1b0ea2..678fc7757fe4 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -603,6 +603,7 @@ extern struct kvm_x86_nested_ops svm_nested_ops;
 
 /* avic.c */
 
+bool avic_hardware_setup(struct kvm_x86_ops *ops);
 int avic_ga_log_notifier(u32 ga_tag);
 void avic_vm_destroy(struct kvm *kvm);
 int avic_vm_init(struct kvm *kvm);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 04/14] KVM: SVM: Update max number of vCPUs supported for x2AVIC mode
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (2 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 03/14] KVM: SVM: Detect X2APIC virtualization (x2AVIC) support Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 05/14] KVM: SVM: Update avic_kick_target_vcpus to support 32-bit APIC ID Suravee Suthikulpanit
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

xAVIC and x2AVIC modes can support diffferent number of vcpus.
Update existing logics to support each mode accordingly.

Also, modify the maximum physical APIC ID for AVIC to 255 to reflect
the actual value supported by the architecture.

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/include/asm/svm.h | 12 +++++++++---
 arch/x86/kvm/svm/avic.c    |  8 +++++---
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 2c2a104b777e..4c26b0d47d76 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -258,10 +258,16 @@ enum avic_ipi_failure_cause {
 
 
 /*
- * 0xff is broadcast, so the max index allowed for physical APIC ID
- * table is 0xfe.  APIC IDs above 0xff are reserved.
+ * For AVIC, the max index allowed for physical APIC ID
+ * table is 0xff (255).
  */
-#define AVIC_MAX_PHYSICAL_ID_COUNT	0xff
+#define AVIC_MAX_PHYSICAL_ID		0XFEULL
+
+/*
+ * For x2AVIC, the max index allowed for physical APIC ID
+ * table is 0x1ff (511).
+ */
+#define X2AVIC_MAX_PHYSICAL_ID		0x1FFUL
 
 #define AVIC_HPA_MASK	~((0xFFFULL << 52) | 0xFFF)
 #define VMCB_AVIC_APIC_BAR_MASK		0xFFFFFFFFFF000ULL
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index fc3ba6071482..182f4891c7ef 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -185,7 +185,7 @@ void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb)
 	vmcb->control.avic_backing_page = bpa & AVIC_HPA_MASK;
 	vmcb->control.avic_logical_id = lpa & AVIC_HPA_MASK;
 	vmcb->control.avic_physical_id = ppa & AVIC_HPA_MASK;
-	vmcb->control.avic_physical_id |= AVIC_MAX_PHYSICAL_ID_COUNT;
+	vmcb->control.avic_physical_id |= AVIC_MAX_PHYSICAL_ID;
 	vmcb->control.avic_vapic_bar = APIC_DEFAULT_PHYS_BASE & VMCB_AVIC_APIC_BAR_MASK;
 
 	if (kvm_apicv_activated(svm->vcpu.kvm))
@@ -200,7 +200,8 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu,
 	u64 *avic_physical_id_table;
 	struct kvm_svm *kvm_svm = to_kvm_svm(vcpu->kvm);
 
-	if (index >= AVIC_MAX_PHYSICAL_ID_COUNT)
+	if ((avic_mode == AVIC_MODE_X1 && index > AVIC_MAX_PHYSICAL_ID) ||
+	    (avic_mode == AVIC_MODE_X2 && index > X2AVIC_MAX_PHYSICAL_ID))
 		return NULL;
 
 	avic_physical_id_table = page_address(kvm_svm->avic_physical_id_table_page);
@@ -247,7 +248,8 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu)
 	int id = vcpu->vcpu_id;
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	if (id >= AVIC_MAX_PHYSICAL_ID_COUNT)
+	if ((avic_mode == AVIC_MODE_X1 && id > AVIC_MAX_PHYSICAL_ID) ||
+	    (avic_mode == AVIC_MODE_X2 && id > X2AVIC_MAX_PHYSICAL_ID))
 		return -EINVAL;
 
 	if (!vcpu->arch.apic->regs)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 05/14] KVM: SVM: Update avic_kick_target_vcpus to support 32-bit APIC ID
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (3 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 04/14] KVM: SVM: Update max number of vCPUs supported for x2AVIC mode Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 06/14] KVM: SVM: Do not support updating APIC ID when in x2APIC mode Suravee Suthikulpanit
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

In x2APIC mode, ICRH contains 32-bit destination APIC ID.
So, update the avic_kick_target_vcpus() accordingly.

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/avic.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 182f4891c7ef..9213e9d113dd 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -375,9 +375,15 @@ static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source,
 	 * since entered the guest will have processed pending IRQs at VMRUN.
 	 */
 	kvm_for_each_vcpu(i, vcpu, kvm) {
+		u32 dest;
+
+		if (apic_x2apic_mode(vcpu->arch.apic))
+			dest = icrh;
+		else
+			dest = GET_XAPIC_DEST_FIELD(icrh);
+
 		if (kvm_apic_match_dest(vcpu, source, icrl & APIC_SHORT_MASK,
-					GET_XAPIC_DEST_FIELD(icrh),
-					icrl & APIC_DEST_MASK)) {
+					dest, icrl & APIC_DEST_MASK)) {
 			vcpu->arch.apic->irr_pending = true;
 			svm_complete_interrupt_delivery(vcpu,
 							icrl & APIC_MODE_MASK,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 06/14] KVM: SVM: Do not support updating APIC ID when in x2APIC mode
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (4 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 05/14] KVM: SVM: Update avic_kick_target_vcpus to support 32-bit APIC ID Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 07/14] KVM: SVM: Adding support for configuring x2APIC MSRs interception Suravee Suthikulpanit
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

In X2APIC mode, the Logical Destination Register is read-only,
which provides a fixed mapping between the logical and physical
APIC IDs. Therefore, there is no Logical APIC ID table in X2AVIC
and the processor uses the X2APIC ID in the backing page to create
a vCPU’s logical ID.

In addition, KVM does not support updating APIC ID in x2APIC mode,
which means AVIC does not need to handle this case.

Therefore, check x2APIC mode when handling physical and logical
APIC ID update, and when invalidating logical APIC ID table.

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Suggested-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/avic.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 9213e9d113dd..3ebeea19b487 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -499,8 +499,13 @@ static void avic_invalidate_logical_id_entry(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 	bool flat = svm->dfr_reg == APIC_DFR_FLAT;
-	u32 *entry = avic_get_logical_id_entry(vcpu, svm->ldr_reg, flat);
+	u32 *entry;
 
+	/* Note: x2AVIC does not use logical APIC ID table */
+	if (apic_x2apic_mode(vcpu->arch.apic))
+		return;
+
+	entry = avic_get_logical_id_entry(vcpu, svm->ldr_reg, flat);
 	if (entry)
 		clear_bit(AVIC_LOGICAL_ID_ENTRY_VALID_BIT, (unsigned long *)entry);
 }
@@ -512,6 +517,10 @@ static int avic_handle_ldr_update(struct kvm_vcpu *vcpu)
 	u32 ldr = kvm_lapic_get_reg(vcpu->arch.apic, APIC_LDR);
 	u32 id = kvm_xapic_id(vcpu->arch.apic);
 
+	/* AVIC does not support LDR update for x2APIC */
+	if (apic_x2apic_mode(vcpu->arch.apic))
+		return 0;
+
 	if (ldr == svm->ldr_reg)
 		return 0;
 
@@ -532,6 +541,14 @@ static int avic_handle_apic_id_update(struct kvm_vcpu *vcpu)
 	struct vcpu_svm *svm = to_svm(vcpu);
 	u32 id = kvm_xapic_id(vcpu->arch.apic);
 
+	/*
+	 * KVM does not support apic ID update for x2APIC.
+	 * Also, need to check if the APIC ID exceed 254.
+	 */
+	if (apic_x2apic_mode(vcpu->arch.apic) ||
+	    (vcpu->vcpu_id >= APIC_BROADCAST))
+		return 0;
+
 	if (vcpu->vcpu_id == id)
 		return 0;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 07/14] KVM: SVM: Adding support for configuring x2APIC MSRs interception
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (5 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 06/14] KVM: SVM: Do not support updating APIC ID when in x2APIC mode Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04 12:14   ` Maxim Levitsky
  2022-05-04  7:31 ` [PATCH v3 08/14] KVM: SVM: Update AVIC settings when changing APIC mode Suravee Suthikulpanit
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

When enabling x2APIC virtualization (x2AVIC), the interception of
x2APIC MSRs must be disabled to let the hardware virtualize guest
MSR accesses.

Current implementation keeps track of list of MSR interception state
in the svm_direct_access_msrs array. Therefore, extends the array to
include x2APIC MSRs.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/svm.c | 25 +++++++++++++++++++++++++
 arch/x86/kvm/svm/svm.h |  4 ++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 74e6f86f5dc3..314628b6bff4 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -100,6 +100,31 @@ static const struct svm_direct_access_msrs {
 	{ .index = MSR_IA32_CR_PAT,			.always = false },
 	{ .index = MSR_AMD64_SEV_ES_GHCB,		.always = true  },
 	{ .index = MSR_TSC_AUX,				.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_ID),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_LVR),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_TASKPRI),	.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_ARBPRI),	.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_PROCPRI),	.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_EOI),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_RRR),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_LDR),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_DFR),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_SPIV),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_ISR),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_TMR),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_IRR),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_ESR),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_ICR),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_ICR2),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_LVTT),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_LVTTHMR),	.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_LVTPC),	.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_LVT0),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_LVT1),		.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_LVTERR),	.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_TMICT),	.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_TMCCT),	.always = false },
+	{ .index = (APIC_BASE_MSR + APIC_TDCR),		.always = false },
 	{ .index = MSR_INVALID,				.always = false },
 };
 
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 678fc7757fe4..5ed958863b81 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -29,8 +29,8 @@
 #define	IOPM_SIZE PAGE_SIZE * 3
 #define	MSRPM_SIZE PAGE_SIZE * 2
 
-#define MAX_DIRECT_ACCESS_MSRS	21
-#define MSRPM_OFFSETS	16
+#define MAX_DIRECT_ACCESS_MSRS	46
+#define MSRPM_OFFSETS	32
 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
 extern bool npt_enabled;
 extern int vgif;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 08/14] KVM: SVM: Update AVIC settings when changing APIC mode
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (6 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 07/14] KVM: SVM: Adding support for configuring x2APIC MSRs interception Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04 12:19   ` Maxim Levitsky
  2022-05-04  7:31 ` [PATCH v3 09/14] KVM: SVM: Introduce helper functions to (de)activate AVIC and x2AVIC Suravee Suthikulpanit
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

Update and refresh AVIC settings when guest APIC mode is updated
(e.g. changing between disabled, xAPIC, or x2APIC).

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/avic.c | 16 ++++++++++++++++
 arch/x86/kvm/svm/svm.c  |  1 +
 2 files changed, 17 insertions(+)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 3ebeea19b487..d185dd8ddf17 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -691,6 +691,22 @@ void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu)
 	avic_handle_ldr_update(vcpu);
 }
 
+void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+
+	if (!lapic_in_kernel(vcpu) || (avic_mode == AVIC_MODE_NONE))
+		return;
+
+	if (kvm_get_apic_mode(vcpu) == LAPIC_MODE_INVALID) {
+		WARN_ONCE(true, "Invalid local APIC state (vcpu_id=%d)", vcpu->vcpu_id);
+		return;
+	}
+
+	kvm_vcpu_update_apicv(&svm->vcpu);
+	avic_refresh_apicv_exec_ctrl(&svm->vcpu);
+}
+
 static int avic_set_pi_irte_mode(struct kvm_vcpu *vcpu, bool activate)
 {
 	int ret = 0;
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 314628b6bff4..9066568fd19d 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4692,6 +4692,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
 	.enable_nmi_window = svm_enable_nmi_window,
 	.enable_irq_window = svm_enable_irq_window,
 	.update_cr8_intercept = svm_update_cr8_intercept,
+	.set_virtual_apic_mode = avic_set_virtual_apic_mode,
 	.refresh_apicv_exec_ctrl = avic_refresh_apicv_exec_ctrl,
 	.check_apicv_inhibit_reasons = avic_check_apicv_inhibit_reasons,
 	.apicv_post_state_restore = avic_apicv_post_state_restore,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 09/14] KVM: SVM: Introduce helper functions to (de)activate AVIC and x2AVIC
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (7 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 08/14] KVM: SVM: Update AVIC settings when changing APIC mode Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 10/14] KVM: SVM: Do not throw warning when calling avic_vcpu_load on a running vcpu Suravee Suthikulpanit
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit, kernel test robot

Refactor the current logic for (de)activate AVIC into helper functions,
and also add logic for (de)activate x2AVIC. The helper function are used
when initializing AVIC and switching from AVIC to x2AVIC mode
(handled by svm_refresh_spicv_exec_ctrl()).

When an AVIC-enabled guest switches from APIC to x2APIC mode during
runtime, the SVM driver needs to perform the following steps:

1. Set the x2APIC mode bit for AVIC in VMCB along with the maximum
APIC ID support for each mode accodingly.

2. Disable x2APIC MSRs interception in order to allow the hardware
to virtualize x2APIC MSRs accesses.

Reported-by: kernel test robot <lkp@intel.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/include/asm/svm.h |  6 +++++
 arch/x86/kvm/svm/avic.c    | 54 ++++++++++++++++++++++++++++++++++----
 arch/x86/kvm/svm/svm.c     |  6 ++---
 arch/x86/kvm/svm/svm.h     |  1 +
 4 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 4c26b0d47d76..f5525c0e03f7 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -256,6 +256,7 @@ enum avic_ipi_failure_cause {
 	AVIC_IPI_FAILURE_INVALID_BACKING_PAGE,
 };
 
+#define AVIC_PHYSICAL_MAX_INDEX_MASK	GENMASK_ULL(9, 0)
 
 /*
  * For AVIC, the max index allowed for physical APIC ID
@@ -500,4 +501,9 @@ DEFINE_GHCB_ACCESSORS(sw_exit_info_2)
 DEFINE_GHCB_ACCESSORS(sw_scratch)
 DEFINE_GHCB_ACCESSORS(xcr0)
 
+struct svm_direct_access_msrs {
+	u32 index;   /* Index of the MSR */
+	bool always; /* True if intercept is initially cleared */
+};
+
 #endif
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index d185dd8ddf17..f255ca221e56 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -69,6 +69,51 @@ struct amd_svm_iommu_ir {
 	void *data;		/* Storing pointer to struct amd_ir_data */
 };
 
+static inline void avic_set_x2apic_msr_interception(struct vcpu_svm *svm, bool disable)
+{
+	int i;
+
+	for (i = 0; i < MAX_DIRECT_ACCESS_MSRS; i++) {
+		int index = direct_access_msrs[i].index;
+
+		if ((index < APIC_BASE_MSR) ||
+		    (index > APIC_BASE_MSR + 0xff))
+			continue;
+		set_msr_interception(&svm->vcpu, svm->msrpm, index,
+				     !disable, !disable);
+	}
+}
+
+static void avic_activate_vmcb(struct vcpu_svm *svm)
+{
+	struct vmcb *vmcb = svm->vmcb01.ptr;
+
+	vmcb->control.int_ctl &= ~(AVIC_ENABLE_MASK | X2APIC_MODE_MASK);
+	vmcb->control.avic_physical_id &= ~AVIC_PHYSICAL_MAX_INDEX_MASK;
+
+	vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
+	if (apic_x2apic_mode(svm->vcpu.arch.apic)) {
+		vmcb->control.int_ctl |= X2APIC_MODE_MASK;
+		vmcb->control.avic_physical_id |= X2AVIC_MAX_PHYSICAL_ID;
+		/* Disabling MSR intercept for x2APIC registers */
+		avic_set_x2apic_msr_interception(svm, false);
+	} else {
+		vmcb->control.avic_physical_id |= AVIC_MAX_PHYSICAL_ID;
+		/* Enabling MSR intercept for x2APIC registers */
+		avic_set_x2apic_msr_interception(svm, true);
+	}
+}
+
+static void avic_deactivate_vmcb(struct vcpu_svm *svm)
+{
+	struct vmcb *vmcb = svm->vmcb01.ptr;
+
+	vmcb->control.int_ctl &= ~(AVIC_ENABLE_MASK | X2APIC_MODE_MASK);
+	vmcb->control.avic_physical_id &= ~AVIC_PHYSICAL_MAX_INDEX_MASK;
+
+	/* Enabling MSR intercept for x2APIC registers */
+	avic_set_x2apic_msr_interception(svm, true);
+}
 
 /* Note:
  * This function is called from IOMMU driver to notify
@@ -185,13 +230,12 @@ void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb)
 	vmcb->control.avic_backing_page = bpa & AVIC_HPA_MASK;
 	vmcb->control.avic_logical_id = lpa & AVIC_HPA_MASK;
 	vmcb->control.avic_physical_id = ppa & AVIC_HPA_MASK;
-	vmcb->control.avic_physical_id |= AVIC_MAX_PHYSICAL_ID;
 	vmcb->control.avic_vapic_bar = APIC_DEFAULT_PHYS_BASE & VMCB_AVIC_APIC_BAR_MASK;
 
 	if (kvm_apicv_activated(svm->vcpu.kvm))
-		vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
+		avic_activate_vmcb(svm);
 	else
-		vmcb->control.int_ctl &= ~AVIC_ENABLE_MASK;
+		avic_deactivate_vmcb(svm);
 }
 
 static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu,
@@ -1086,9 +1130,9 @@ void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
 		 * accordingly before re-activating.
 		 */
 		avic_apicv_post_state_restore(vcpu);
-		vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
+		avic_activate_vmcb(svm);
 	} else {
-		vmcb->control.int_ctl &= ~AVIC_ENABLE_MASK;
+		avic_deactivate_vmcb(svm);
 	}
 	vmcb_mark_dirty(vmcb, VMCB_AVIC);
 
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 9066568fd19d..96a1fc1a1d1b 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -74,10 +74,8 @@ static uint64_t osvw_len = 4, osvw_status;
 
 static DEFINE_PER_CPU(u64, current_tsc_ratio);
 
-static const struct svm_direct_access_msrs {
-	u32 index;   /* Index of the MSR */
-	bool always; /* True if intercept is initially cleared */
-} direct_access_msrs[MAX_DIRECT_ACCESS_MSRS] = {
+const struct svm_direct_access_msrs
+direct_access_msrs[MAX_DIRECT_ACCESS_MSRS] = {
 	{ .index = MSR_STAR,				.always = true  },
 	{ .index = MSR_IA32_SYSENTER_CS,		.always = true  },
 	{ .index = MSR_IA32_SYSENTER_EIP,		.always = false },
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 5ed958863b81..bb5bf70de3b2 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -600,6 +600,7 @@ void nested_vmcb02_compute_g_pat(struct vcpu_svm *svm);
 void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vmcb);
 
 extern struct kvm_x86_nested_ops svm_nested_ops;
+extern const struct svm_direct_access_msrs direct_access_msrs[];
 
 /* avic.c */
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 10/14] KVM: SVM: Do not throw warning when calling avic_vcpu_load on a running vcpu
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (8 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 09/14] KVM: SVM: Introduce helper functions to (de)activate AVIC and x2AVIC Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 11/14] KVM: SVM: Introduce hybrid-AVIC mode Suravee Suthikulpanit
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

Originalliy, this WARN_ON is designed to detect when calling
avic_vcpu_load() on an already running vcpu in AVIC mode (i.e. the AVIC
is_running bit is set).

However, for x2AVIC, the vCPU can switch from xAPIC to x2APIC mode while in
running state, in which the avic_vcpu_load() will be called from
svm_refresh_apicv_exec_ctrl().

Therefore, remove this warning since it is no longer appropriate.

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/avic.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index f255ca221e56..d07c58f06bed 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -1063,7 +1063,6 @@ void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		return;
 
 	entry = READ_ONCE(*(svm->avic_physical_id_cache));
-	WARN_ON(entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK);
 
 	entry &= ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK;
 	entry |= (h_physical_id & AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 11/14] KVM: SVM: Introduce hybrid-AVIC mode
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (9 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 10/14] KVM: SVM: Do not throw warning when calling avic_vcpu_load on a running vcpu Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04 12:32   ` Maxim Levitsky
  2022-05-04  7:31 ` [PATCH v3 12/14] kvm/x86: Warning APICv inconsistency only when vcpu APIC mode is valid Suravee Suthikulpanit
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

Currently, AVIC is inhibited when booting a VM w/ x2APIC support.
because AVIC cannot virtualize x2APIC MSR register accesses.
However, the AVIC doorbell can be used to accelerate interrupt
injection into a running vCPU, while all guest accesses to x2APIC MSRs
will be intercepted and emulated by KVM.

With hybrid-AVIC support, the APICV_INHIBIT_REASON_X2APIC is
no longer enforced.

Suggested-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/avic.c | 10 +++++++++-
 arch/x86/kvm/svm/svm.c  |  9 ---------
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index d07c58f06bed..3b6a96043633 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -92,12 +92,20 @@ static void avic_activate_vmcb(struct vcpu_svm *svm)
 	vmcb->control.avic_physical_id &= ~AVIC_PHYSICAL_MAX_INDEX_MASK;
 
 	vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
-	if (apic_x2apic_mode(svm->vcpu.arch.apic)) {
+
+	/* Note:
+	 * KVM can support hybrid-x2AVIC mode, where KVM emulates x2APIC
+	 * MSR accesses, while interrupt injection to a running vCPU
+	 * can be achieve using AVIC doorbell.
+	 */
+	if (apic_x2apic_mode(svm->vcpu.arch.apic) &&
+	    (avic_mode == AVIC_MODE_X2)) {
 		vmcb->control.int_ctl |= X2APIC_MODE_MASK;
 		vmcb->control.avic_physical_id |= X2AVIC_MAX_PHYSICAL_ID;
 		/* Disabling MSR intercept for x2APIC registers */
 		avic_set_x2apic_msr_interception(svm, false);
 	} else {
+		/* For xAVIC and hybrid-x2AVIC modes */
 		vmcb->control.avic_physical_id |= AVIC_MAX_PHYSICAL_ID;
 		/* Enabling MSR intercept for x2APIC registers */
 		avic_set_x2apic_msr_interception(svm, true);
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 96a1fc1a1d1b..c0a3d4a1f3dc 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4041,7 +4041,6 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 	struct kvm_cpuid_entry2 *best;
-	struct kvm *kvm = vcpu->kvm;
 
 	vcpu->arch.xsaves_enabled = guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) &&
 				    boot_cpu_has(X86_FEATURE_XSAVE) &&
@@ -4073,14 +4072,6 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 			vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f));
 	}
 
-	if (kvm_vcpu_apicv_active(vcpu)) {
-		/*
-		 * AVIC does not work with an x2APIC mode guest. If the X2APIC feature
-		 * is exposed to the guest, disable AVIC.
-		 */
-		if (guest_cpuid_has(vcpu, X86_FEATURE_X2APIC))
-			kvm_set_apicv_inhibit(kvm, APICV_INHIBIT_REASON_X2APIC);
-	}
 	init_vmcb_after_set_cpuid(vcpu);
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 12/14] kvm/x86: Warning APICv inconsistency only when vcpu APIC mode is valid
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (10 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 11/14] KVM: SVM: Introduce hybrid-AVIC mode Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04 12:33   ` Maxim Levitsky
  2022-05-04  7:31 ` [PATCH v3 13/14] KVM: SVM: Use target APIC ID to complete x2AVIC IRQs when possible Suravee Suthikulpanit
  2022-05-04  7:31 ` [PATCH v3 14/14] KVM: SVM: Add AVIC doorbell tracepoint Suravee Suthikulpanit
  13 siblings, 1 reply; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

When launching a VM with x2APIC and specify more than 255 vCPUs,
the guest kernel can disable x2APIC (e.g. specify nox2apic kernel option).
The VM fallbacks to xAPIC mode, and disable the vCPU ID 255 and greater.

In this case, APICV should be deactivated for the disabled vCPUs.
However, the current APICv consistency warning does not account for
this case, which results in a warning.

Therefore, modify warning logic to report only when vCPU APIC mode
is valid.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/x86.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 8ee8c91fa762..b14e02ea0ff6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9838,6 +9838,10 @@ void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu)
 
 	activate = kvm_vcpu_apicv_activated(vcpu);
 
+	/* Do not activate AVIC when APIC is disabled */
+	if (kvm_get_apic_mode(vcpu) == LAPIC_MODE_DISABLED)
+		activate = false;
+
 	if (vcpu->arch.apicv_active == activate)
 		goto out;
 
@@ -10240,7 +10244,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 		 * per-VM state, and responsing vCPUs must wait for the update
 		 * to complete before servicing KVM_REQ_APICV_UPDATE.
 		 */
-		WARN_ON_ONCE(kvm_vcpu_apicv_activated(vcpu) != kvm_vcpu_apicv_active(vcpu));
+		if (kvm_vcpu_apicv_activated(vcpu) != kvm_vcpu_apicv_active(vcpu))
+			WARN_ON_ONCE(kvm_get_apic_mode(vcpu) != LAPIC_MODE_DISABLED);
 
 		exit_fastpath = static_call(kvm_x86_vcpu_run)(vcpu);
 		if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST))
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 13/14] KVM: SVM: Use target APIC ID to complete x2AVIC IRQs when possible
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (11 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 12/14] kvm/x86: Warning APICv inconsistency only when vcpu APIC mode is valid Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04 12:34   ` Maxim Levitsky
  2022-05-04  7:31 ` [PATCH v3 14/14] KVM: SVM: Add AVIC doorbell tracepoint Suravee Suthikulpanit
  13 siblings, 1 reply; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

For x2AVIC, the index from incomplete IPI #vmexit info is invalid
for logical cluster mode. Only ICRH/ICRL values can be used
to determine the IPI destination APIC ID.

Since QEMU defines guest physical APIC ID to be the same as
vCPU ID, it can be used to quickly identify the target vCPU to deliver IPI,
and avoid the overhead from searching through all vCPUs to match the target
vCPU.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/avic.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 3b6a96043633..a526fbc60bbd 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -377,7 +377,26 @@ static int avic_kick_target_vcpus_fast(struct kvm *kvm, struct kvm_lapic *source
 			/* For xAPIC logical mode, the index is for logical APIC table. */
 			apic_id = avic_logical_id_table[index] & 0x1ff;
 		} else {
-			return -EINVAL;
+			/* For x2APIC logical mode, cannot leverage the index.
+			 * Instead, calculate physical ID from logical ID in ICRH.
+			 */
+			int apic;
+			int first = ffs(icrh & 0xffff);
+			int last = fls(icrh & 0xffff);
+			int cluster = (icrh & 0xffff0000) >> 16;
+
+			/*
+			 * If the x2APIC logical ID sub-field (i.e. icrh[15:0]) contains zero
+			 * or more than 1 bits, we cannot match just one vcpu to kick for
+			 * fast path.
+			 */
+			if (!first || (first != last))
+				return -EINVAL;
+
+			apic = first - 1;
+			if ((apic < 0) || (apic > 15) || (cluster >= 0xfffff))
+				return -EINVAL;
+			apic_id = (cluster << 4) + apic;
 		}
 	}
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 14/14] KVM: SVM: Add AVIC doorbell tracepoint
  2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
                   ` (12 preceding siblings ...)
  2022-05-04  7:31 ` [PATCH v3 13/14] KVM: SVM: Use target APIC ID to complete x2AVIC IRQs when possible Suravee Suthikulpanit
@ 2022-05-04  7:31 ` Suravee Suthikulpanit
  2022-05-04 12:36   ` Maxim Levitsky
  13 siblings, 1 reply; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-04  7:31 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: pbonzini, mlevitsk, seanjc, joro, jon.grimm, wei.huang2,
	terry.bowman, Suravee Suthikulpanit

Add a tracepoint to track number of doorbells being sent
to signal a running vCPU to process IRQ after being injected.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/avic.c |  4 +++-
 arch/x86/kvm/trace.h    | 18 ++++++++++++++++++
 arch/x86/kvm/x86.c      |  1 +
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index a526fbc60bbd..e3343cfc55cd 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -343,8 +343,10 @@ void avic_ring_doorbell(struct kvm_vcpu *vcpu)
 	 */
 	int cpu = READ_ONCE(vcpu->cpu);
 
-	if (cpu != get_cpu())
+	if (cpu != get_cpu()) {
 		wrmsrl(MSR_AMD64_SVM_AVIC_DOORBELL, kvm_cpu_get_apicid(cpu));
+		trace_kvm_avic_doorbell(vcpu->vcpu_id, kvm_cpu_get_apicid(cpu));
+	}
 	put_cpu();
 }
 
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index de4762517569..a47bb0fdea70 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -1479,6 +1479,24 @@ TRACE_EVENT(kvm_avic_kick_vcpu_slowpath,
 		  __entry->icrh, __entry->icrl, __entry->index)
 );
 
+TRACE_EVENT(kvm_avic_doorbell,
+	    TP_PROTO(u32 vcpuid, u32 apicid),
+	    TP_ARGS(vcpuid, apicid),
+
+	TP_STRUCT__entry(
+		__field(u32, vcpuid)
+		__field(u32, apicid)
+	),
+
+	TP_fast_assign(
+		__entry->vcpuid = vcpuid;
+		__entry->apicid = apicid;
+	),
+
+	TP_printk("vcpuid=%u, apicid=%u",
+		  __entry->vcpuid, __entry->apicid)
+);
+
 TRACE_EVENT(kvm_hv_timer_state,
 		TP_PROTO(unsigned int vcpu_id, unsigned int hv_timer_in_use),
 		TP_ARGS(vcpu_id, hv_timer_in_use),
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b14e02ea0ff6..69a91f47a509 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -13097,6 +13097,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_unaccelerated_access);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_incomplete_ipi);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_ga_log);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_kick_vcpu_slowpath);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_doorbell);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_apicv_accept_irq);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_enter);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_exit);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 03/14] KVM: SVM: Detect X2APIC virtualization (x2AVIC) support
  2022-05-04  7:31 ` [PATCH v3 03/14] KVM: SVM: Detect X2APIC virtualization (x2AVIC) support Suravee Suthikulpanit
@ 2022-05-04 12:12   ` Maxim Levitsky
  2022-05-05  4:07     ` Suravee Suthikulpanit
  0 siblings, 1 reply; 27+ messages in thread
From: Maxim Levitsky @ 2022-05-04 12:12 UTC (permalink / raw)
  To: Suravee Suthikulpanit, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

On Wed, 2022-05-04 at 02:31 -0500, Suravee Suthikulpanit wrote:
> Add CPUID check for the x2APIC virtualization (x2AVIC) feature.
> If available, the SVM driver can support both AVIC and x2AVIC modes
> when load the kvm_amd driver with avic=1. The operating mode will be
> determined at runtime depending on the guest APIC mode.
> 
> Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
>  arch/x86/include/asm/svm.h |  3 +++
>  arch/x86/kvm/svm/avic.c    | 40 ++++++++++++++++++++++++++++++++++++++
>  arch/x86/kvm/svm/svm.c     | 15 ++------------
>  arch/x86/kvm/svm/svm.h     |  1 +
>  4 files changed, 46 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
> index f70a5108d464..2c2a104b777e 100644
> --- a/arch/x86/include/asm/svm.h
> +++ b/arch/x86/include/asm/svm.h
> @@ -195,6 +195,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
>  #define AVIC_ENABLE_SHIFT 31
>  #define AVIC_ENABLE_MASK (1 << AVIC_ENABLE_SHIFT)
>  
> +#define X2APIC_MODE_SHIFT 30
> +#define X2APIC_MODE_MASK (1 << X2APIC_MODE_SHIFT)
> +
>  #define LBR_CTL_ENABLE_MASK BIT_ULL(0)
>  #define VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK BIT_ULL(1)
>  
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index a8f514212b87..fc3ba6071482 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -40,6 +40,15 @@
>  #define AVIC_GATAG_TO_VMID(x)		((x >> AVIC_VCPU_ID_BITS) & AVIC_VM_ID_MASK)
>  #define AVIC_GATAG_TO_VCPUID(x)		(x & AVIC_VCPU_ID_MASK)
>  
> +enum avic_modes {
> +	AVIC_MODE_NONE = 0,
> +	AVIC_MODE_X1,
> +	AVIC_MODE_X2,
> +};
> +
> +static bool force_avic;
> +module_param_unsafe(force_avic, bool, 0444);
> +
>  /* Note:
>   * This hash table is used to map VM_ID to a struct kvm_svm,
>   * when handling AMD IOMMU GALOG notification to schedule in
> @@ -50,6 +59,7 @@ static DEFINE_HASHTABLE(svm_vm_data_hash, SVM_VM_DATA_HASH_BITS);
>  static u32 next_vm_id = 0;
>  static bool next_vm_id_wrapped = 0;
>  static DEFINE_SPINLOCK(svm_vm_data_hash_lock);
> +static enum avic_modes avic_mode;
>  
>  /*
>   * This is a wrapper of struct amd_iommu_ir_data.
> @@ -1077,3 +1087,33 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
>  
>  	avic_vcpu_load(vcpu);
>  }
> +
> +/*
> + * Note:
> + * - The module param avic enable both xAPIC and x2APIC mode.
> + * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
> + * - The mode can be switched at run-time.
> + */
> +bool avic_hardware_setup(struct kvm_x86_ops *x86_ops)
> +{
> +	if (!npt_enabled)
> +		return false;
> +
> +	if (boot_cpu_has(X86_FEATURE_AVIC)) {
> +		avic_mode = AVIC_MODE_X1;
> +		pr_info("AVIC enabled\n");
> +	} else if (force_avic) {
> +		pr_warn("AVIC is not supported in CPUID but force enabled");
> +		pr_warn("Your system might crash and burn");

I think in this case avic_mode should also be set to AVIC_MODE_X1
(Hopefully this won't be needed for systems that have x2avic enabled)

Best regards,
	Maxim Levitsky

> +	}
> +
> +	if (boot_cpu_has(X86_FEATURE_X2AVIC)) {
> +		avic_mode = AVIC_MODE_X2;
> +		pr_info("x2AVIC enabled\n");
> +	}
> +
> +	if (avic_mode != AVIC_MODE_NONE)
> +		amd_iommu_register_ga_log_notifier(&avic_ga_log_notifier);
> +
> +	return !!avic_mode;
> +}
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 3b49337998ec..74e6f86f5dc3 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -188,9 +188,6 @@ module_param(tsc_scaling, int, 0444);
>  static bool avic;
>  module_param(avic, bool, 0444);
>  
> -static bool force_avic;
> -module_param_unsafe(force_avic, bool, 0444);
> -
>  bool __read_mostly dump_invalid_vmcb;
>  module_param(dump_invalid_vmcb, bool, 0644);
>  
> @@ -4913,17 +4910,9 @@ static __init int svm_hardware_setup(void)
>  			nrips = false;
>  	}
>  
> -	enable_apicv = avic = avic && npt_enabled && (boot_cpu_has(X86_FEATURE_AVIC) || force_avic);
> +	enable_apicv = avic = avic && avic_hardware_setup(&svm_x86_ops);
>  
> -	if (enable_apicv) {
> -		if (!boot_cpu_has(X86_FEATURE_AVIC)) {
> -			pr_warn("AVIC is not supported in CPUID but force enabled");
> -			pr_warn("Your system might crash and burn");
> -		} else
> -			pr_info("AVIC enabled\n");
> -
> -		amd_iommu_register_ga_log_notifier(&avic_ga_log_notifier);
> -	} else {
> +	if (!enable_apicv) {
>  		svm_x86_ops.vcpu_blocking = NULL;
>  		svm_x86_ops.vcpu_unblocking = NULL;
>  		svm_x86_ops.vcpu_get_apicv_inhibit_reasons = NULL;
> diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
> index 32220a1b0ea2..678fc7757fe4 100644
> --- a/arch/x86/kvm/svm/svm.h
> +++ b/arch/x86/kvm/svm/svm.h
> @@ -603,6 +603,7 @@ extern struct kvm_x86_nested_ops svm_nested_ops;
>  
>  /* avic.c */
>  
> +bool avic_hardware_setup(struct kvm_x86_ops *ops);
>  int avic_ga_log_notifier(u32 ga_tag);
>  void avic_vm_destroy(struct kvm *kvm);
>  int avic_vm_init(struct kvm *kvm);



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 07/14] KVM: SVM: Adding support for configuring x2APIC MSRs interception
  2022-05-04  7:31 ` [PATCH v3 07/14] KVM: SVM: Adding support for configuring x2APIC MSRs interception Suravee Suthikulpanit
@ 2022-05-04 12:14   ` Maxim Levitsky
  0 siblings, 0 replies; 27+ messages in thread
From: Maxim Levitsky @ 2022-05-04 12:14 UTC (permalink / raw)
  To: Suravee Suthikulpanit, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

On Wed, 2022-05-04 at 02:31 -0500, Suravee Suthikulpanit wrote:
> When enabling x2APIC virtualization (x2AVIC), the interception of
> x2APIC MSRs must be disabled to let the hardware virtualize guest
> MSR accesses.
> 
> Current implementation keeps track of list of MSR interception state
> in the svm_direct_access_msrs array. Therefore, extends the array to
> include x2APIC MSRs.
> 
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
>  arch/x86/kvm/svm/svm.c | 25 +++++++++++++++++++++++++
>  arch/x86/kvm/svm/svm.h |  4 ++--
>  2 files changed, 27 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 74e6f86f5dc3..314628b6bff4 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -100,6 +100,31 @@ static const struct svm_direct_access_msrs {
>  	{ .index = MSR_IA32_CR_PAT,			.always = false },
>  	{ .index = MSR_AMD64_SEV_ES_GHCB,		.always = true  },
>  	{ .index = MSR_TSC_AUX,				.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_ID),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_LVR),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_TASKPRI),	.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_ARBPRI),	.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_PROCPRI),	.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_EOI),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_RRR),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_LDR),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_DFR),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_SPIV),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_ISR),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_TMR),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_IRR),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_ESR),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_ICR),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_ICR2),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_LVTT),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_LVTTHMR),	.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_LVTPC),	.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_LVT0),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_LVT1),		.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_LVTERR),	.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_TMICT),	.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_TMCCT),	.always = false },
> +	{ .index = (APIC_BASE_MSR + APIC_TDCR),		.always = false },
>  	{ .index = MSR_INVALID,				.always = false },
>  };
>  
> diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
> index 678fc7757fe4..5ed958863b81 100644
> --- a/arch/x86/kvm/svm/svm.h
> +++ b/arch/x86/kvm/svm/svm.h
> @@ -29,8 +29,8 @@
>  #define	IOPM_SIZE PAGE_SIZE * 3
>  #define	MSRPM_SIZE PAGE_SIZE * 2
>  
> -#define MAX_DIRECT_ACCESS_MSRS	21
> -#define MSRPM_OFFSETS	16
> +#define MAX_DIRECT_ACCESS_MSRS	46
> +#define MSRPM_OFFSETS	32
>  extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
>  extern bool npt_enabled;
>  extern int vgif;


Looks good.

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>

Best regards,
	Maxim Levitsky


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 08/14] KVM: SVM: Update AVIC settings when changing APIC mode
  2022-05-04  7:31 ` [PATCH v3 08/14] KVM: SVM: Update AVIC settings when changing APIC mode Suravee Suthikulpanit
@ 2022-05-04 12:19   ` Maxim Levitsky
  2022-05-05  1:38     ` Suravee Suthikulpanit
  0 siblings, 1 reply; 27+ messages in thread
From: Maxim Levitsky @ 2022-05-04 12:19 UTC (permalink / raw)
  To: Suravee Suthikulpanit, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

On Wed, 2022-05-04 at 02:31 -0500, Suravee Suthikulpanit wrote:
> Update and refresh AVIC settings when guest APIC mode is updated
> (e.g. changing between disabled, xAPIC, or x2APIC).
> 
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
>  arch/x86/kvm/svm/avic.c | 16 ++++++++++++++++
>  arch/x86/kvm/svm/svm.c  |  1 +
>  2 files changed, 17 insertions(+)
> 
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index 3ebeea19b487..d185dd8ddf17 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -691,6 +691,22 @@ void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu)
>  	avic_handle_ldr_update(vcpu);
>  }
>  
> +void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
> +{
> +	struct vcpu_svm *svm = to_svm(vcpu);
> +
> +	if (!lapic_in_kernel(vcpu) || (avic_mode == AVIC_MODE_NONE))
> +		return;
> +
> +	if (kvm_get_apic_mode(vcpu) == LAPIC_MODE_INVALID) {
> +		WARN_ONCE(true, "Invalid local APIC state (vcpu_id=%d)", vcpu->vcpu_id);
> +		return;
> +	}
> +
> +	kvm_vcpu_update_apicv(&svm->vcpu);

Why to have this call? I think that all that is needed is only to call the
avic_refresh_apicv_exec_ctrl.

Best regards,
	Maxim Levitsky


> +	avic_refresh_apicv_exec_ctrl(&svm->vcpu);
> +}
> +
>  static int avic_set_pi_irte_mode(struct kvm_vcpu *vcpu, bool activate)
>  {
>  	int ret = 0;
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 314628b6bff4..9066568fd19d 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -4692,6 +4692,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
>  	.enable_nmi_window = svm_enable_nmi_window,
>  	.enable_irq_window = svm_enable_irq_window,
>  	.update_cr8_intercept = svm_update_cr8_intercept,
> +	.set_virtual_apic_mode = avic_set_virtual_apic_mode,
>  	.refresh_apicv_exec_ctrl = avic_refresh_apicv_exec_ctrl,
>  	.check_apicv_inhibit_reasons = avic_check_apicv_inhibit_reasons,
>  	.apicv_post_state_restore = avic_apicv_post_state_restore,



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 11/14] KVM: SVM: Introduce hybrid-AVIC mode
  2022-05-04  7:31 ` [PATCH v3 11/14] KVM: SVM: Introduce hybrid-AVIC mode Suravee Suthikulpanit
@ 2022-05-04 12:32   ` Maxim Levitsky
  2022-05-05  3:57     ` Suravee Suthikulpanit
  0 siblings, 1 reply; 27+ messages in thread
From: Maxim Levitsky @ 2022-05-04 12:32 UTC (permalink / raw)
  To: Suravee Suthikulpanit, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

On Wed, 2022-05-04 at 02:31 -0500, Suravee Suthikulpanit wrote:
> Currently, AVIC is inhibited when booting a VM w/ x2APIC support.
> because AVIC cannot virtualize x2APIC MSR register accesses.
> However, the AVIC doorbell can be used to accelerate interrupt
> injection into a running vCPU, while all guest accesses to x2APIC MSRs
> will be intercepted and emulated by KVM.
> 
> With hybrid-AVIC support, the APICV_INHIBIT_REASON_X2APIC is
> no longer enforced.
> 
> Suggested-by: Maxim Levitsky <mlevitsk@redhat.com>
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
>  arch/x86/kvm/svm/avic.c | 10 +++++++++-
>  arch/x86/kvm/svm/svm.c  |  9 ---------
>  2 files changed, 9 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index d07c58f06bed..3b6a96043633 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -92,12 +92,20 @@ static void avic_activate_vmcb(struct vcpu_svm *svm)
>  	vmcb->control.avic_physical_id &= ~AVIC_PHYSICAL_MAX_INDEX_MASK;
>  
>  	vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
> -	if (apic_x2apic_mode(svm->vcpu.arch.apic)) {
> +
> +	/* Note:
> +	 * KVM can support hybrid-x2AVIC mode, where KVM emulates x2APIC
> +	 * MSR accesses, while interrupt injection to a running vCPU
> +	 * can be achieve using AVIC doorbell.
> +	 */
> +	if (apic_x2apic_mode(svm->vcpu.arch.apic) &&
> +	    (avic_mode == AVIC_MODE_X2)) {
>  		vmcb->control.int_ctl |= X2APIC_MODE_MASK;
>  		vmcb->control.avic_physical_id |= X2AVIC_MAX_PHYSICAL_ID;
>  		/* Disabling MSR intercept for x2APIC registers */
>  		avic_set_x2apic_msr_interception(svm, false);
>  	} else {
> +		/* For xAVIC and hybrid-x2AVIC modes */
>  		vmcb->control.avic_physical_id |= AVIC_MAX_PHYSICAL_ID;
>  		/* Enabling MSR intercept for x2APIC registers */
>  		avic_set_x2apic_msr_interception(svm, true);
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 96a1fc1a1d1b..c0a3d4a1f3dc 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -4041,7 +4041,6 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
>  {
>  	struct vcpu_svm *svm = to_svm(vcpu);
>  	struct kvm_cpuid_entry2 *best;
> -	struct kvm *kvm = vcpu->kvm;
>  
>  	vcpu->arch.xsaves_enabled = guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) &&
>  				    boot_cpu_has(X86_FEATURE_XSAVE) &&
> @@ -4073,14 +4072,6 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
>  			vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f));
>  	}
>  
> -	if (kvm_vcpu_apicv_active(vcpu)) {
> -		/*
> -		 * AVIC does not work with an x2APIC mode guest. If the X2APIC feature
> -		 * is exposed to the guest, disable AVIC.
> -		 */
> -		if (guest_cpuid_has(vcpu, X86_FEATURE_X2APIC))
> -			kvm_set_apicv_inhibit(kvm, APICV_INHIBIT_REASON_X2APIC);
> -	}
>  	init_vmcb_after_set_cpuid(vcpu);
>  }
>  


Well strictly speaking, another thing that has to be done, other that removing the inhibit,
is to 'hide' the AVIC's private memslot if one of vCPUs is in x2apic mode, 
although not doing this doesn't cause any harm as the guest is not supposed to poke at xAPIC
mmio even when uses x2apic, and if it does it will get the normal AVIC acceleration,
so probably it is better to not add any more complexity and leave it like that.

Besides that my only note on this is that you forgot the most satisfying part of this,
removing the APICV_INHIBIT_REASON_X2APIC value ;-)

So besides the removal of the APICV_INHIBIT_REASON_X2APIC:

Reviewed-by: Maxim Levitsky <mlevisk@redhat.com>


BTW, hardware wise, does 'X2APIC_MODE' keeps the emulation of the AVIC mmio, or
not?

Best regards,
	Maxim Levitsky


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 12/14] kvm/x86: Warning APICv inconsistency only when vcpu APIC mode is valid
  2022-05-04  7:31 ` [PATCH v3 12/14] kvm/x86: Warning APICv inconsistency only when vcpu APIC mode is valid Suravee Suthikulpanit
@ 2022-05-04 12:33   ` Maxim Levitsky
  0 siblings, 0 replies; 27+ messages in thread
From: Maxim Levitsky @ 2022-05-04 12:33 UTC (permalink / raw)
  To: Suravee Suthikulpanit, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

On Wed, 2022-05-04 at 02:31 -0500, Suravee Suthikulpanit wrote:
> When launching a VM with x2APIC and specify more than 255 vCPUs,
> the guest kernel can disable x2APIC (e.g. specify nox2apic kernel option).
> The VM fallbacks to xAPIC mode, and disable the vCPU ID 255 and greater.
> 
> In this case, APICV should be deactivated for the disabled vCPUs.
> However, the current APICv consistency warning does not account for
> this case, which results in a warning.
> 
> Therefore, modify warning logic to report only when vCPU APIC mode
> is valid.
> 
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
>  arch/x86/kvm/x86.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 8ee8c91fa762..b14e02ea0ff6 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -9838,6 +9838,10 @@ void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu)
>  
>  	activate = kvm_vcpu_apicv_activated(vcpu);
>  
> +	/* Do not activate AVIC when APIC is disabled */
> +	if (kvm_get_apic_mode(vcpu) == LAPIC_MODE_DISABLED)
> +		activate = false;
> +
>  	if (vcpu->arch.apicv_active == activate)
>  		goto out;
>  
> @@ -10240,7 +10244,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
>  		 * per-VM state, and responsing vCPUs must wait for the update
>  		 * to complete before servicing KVM_REQ_APICV_UPDATE.
>  		 */
> -		WARN_ON_ONCE(kvm_vcpu_apicv_activated(vcpu) != kvm_vcpu_apicv_active(vcpu));
> +		if (kvm_vcpu_apicv_activated(vcpu) != kvm_vcpu_apicv_active(vcpu))
> +			WARN_ON_ONCE(kvm_get_apic_mode(vcpu) != LAPIC_MODE_DISABLED);
>  
>  		exit_fastpath = static_call(kvm_x86_vcpu_run)(vcpu);
>  		if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST))

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>

Best regards,
	Maxim Levitsky


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 13/14] KVM: SVM: Use target APIC ID to complete x2AVIC IRQs when possible
  2022-05-04  7:31 ` [PATCH v3 13/14] KVM: SVM: Use target APIC ID to complete x2AVIC IRQs when possible Suravee Suthikulpanit
@ 2022-05-04 12:34   ` Maxim Levitsky
  0 siblings, 0 replies; 27+ messages in thread
From: Maxim Levitsky @ 2022-05-04 12:34 UTC (permalink / raw)
  To: Suravee Suthikulpanit, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

On Wed, 2022-05-04 at 02:31 -0500, Suravee Suthikulpanit wrote:
> For x2AVIC, the index from incomplete IPI #vmexit info is invalid
> for logical cluster mode. Only ICRH/ICRL values can be used
> to determine the IPI destination APIC ID.
> 
> Since QEMU defines guest physical APIC ID to be the same as
> vCPU ID, it can be used to quickly identify the target vCPU to deliver IPI,
> and avoid the overhead from searching through all vCPUs to match the target
> vCPU.
> 
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
>  arch/x86/kvm/svm/avic.c | 21 ++++++++++++++++++++-
>  1 file changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index 3b6a96043633..a526fbc60bbd 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -377,7 +377,26 @@ static int avic_kick_target_vcpus_fast(struct kvm *kvm, struct kvm_lapic *source
>  			/* For xAPIC logical mode, the index is for logical APIC table. */
>  			apic_id = avic_logical_id_table[index] & 0x1ff;
>  		} else {
> -			return -EINVAL;
> +			/* For x2APIC logical mode, cannot leverage the index.
> +			 * Instead, calculate physical ID from logical ID in ICRH.
> +			 */
> +			int apic;
> +			int first = ffs(icrh & 0xffff);
> +			int last = fls(icrh & 0xffff);
> +			int cluster = (icrh & 0xffff0000) >> 16;
> +
> +			/*
> +			 * If the x2APIC logical ID sub-field (i.e. icrh[15:0]) contains zero
> +			 * or more than 1 bits, we cannot match just one vcpu to kick for
> +			 * fast path.
> +			 */
> +			if (!first || (first != last))
> +				return -EINVAL;
> +
> +			apic = first - 1;
> +			if ((apic < 0) || (apic > 15) || (cluster >= 0xfffff))
> +				return -EINVAL;
> +			apic_id = (cluster << 4) + apic;
>  		}
>  	}
>  

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>

Best regards,
        Maxim Levitsky


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 14/14] KVM: SVM: Add AVIC doorbell tracepoint
  2022-05-04  7:31 ` [PATCH v3 14/14] KVM: SVM: Add AVIC doorbell tracepoint Suravee Suthikulpanit
@ 2022-05-04 12:36   ` Maxim Levitsky
  0 siblings, 0 replies; 27+ messages in thread
From: Maxim Levitsky @ 2022-05-04 12:36 UTC (permalink / raw)
  To: Suravee Suthikulpanit, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

On Wed, 2022-05-04 at 02:31 -0500, Suravee Suthikulpanit wrote:
> Add a tracepoint to track number of doorbells being sent
> to signal a running vCPU to process IRQ after being injected.
> 
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
>  arch/x86/kvm/svm/avic.c |  4 +++-
>  arch/x86/kvm/trace.h    | 18 ++++++++++++++++++
>  arch/x86/kvm/x86.c      |  1 +
>  3 files changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index a526fbc60bbd..e3343cfc55cd 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -343,8 +343,10 @@ void avic_ring_doorbell(struct kvm_vcpu *vcpu)
>  	 */
>  	int cpu = READ_ONCE(vcpu->cpu);
>  
> -	if (cpu != get_cpu())
> +	if (cpu != get_cpu()) {
>  		wrmsrl(MSR_AMD64_SVM_AVIC_DOORBELL, kvm_cpu_get_apicid(cpu));
> +		trace_kvm_avic_doorbell(vcpu->vcpu_id, kvm_cpu_get_apicid(cpu));
> +	}
>  	put_cpu();
>  }
>  
> diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
> index de4762517569..a47bb0fdea70 100644
> --- a/arch/x86/kvm/trace.h
> +++ b/arch/x86/kvm/trace.h
> @@ -1479,6 +1479,24 @@ TRACE_EVENT(kvm_avic_kick_vcpu_slowpath,
>  		  __entry->icrh, __entry->icrl, __entry->index)
>  );
>  
> +TRACE_EVENT(kvm_avic_doorbell,
> +	    TP_PROTO(u32 vcpuid, u32 apicid),
> +	    TP_ARGS(vcpuid, apicid),
> +
> +	TP_STRUCT__entry(
> +		__field(u32, vcpuid)
> +		__field(u32, apicid)
> +	),
> +
> +	TP_fast_assign(
> +		__entry->vcpuid = vcpuid;
> +		__entry->apicid = apicid;
> +	),
> +
> +	TP_printk("vcpuid=%u, apicid=%u",
> +		  __entry->vcpuid, __entry->apicid)
> +);
> +
>  TRACE_EVENT(kvm_hv_timer_state,
>  		TP_PROTO(unsigned int vcpu_id, unsigned int hv_timer_in_use),
>  		TP_ARGS(vcpu_id, hv_timer_in_use),
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index b14e02ea0ff6..69a91f47a509 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -13097,6 +13097,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_unaccelerated_access);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_incomplete_ipi);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_ga_log);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_kick_vcpu_slowpath);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_doorbell);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_apicv_accept_irq);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_enter);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_exit);


To be honest we already have the 'kvm_apicv_accept_irq'
which usually results in a doorbell, but no objections
to add this tracepoint.

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>

Best regards,
        Maxim Levitsky


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 08/14] KVM: SVM: Update AVIC settings when changing APIC mode
  2022-05-04 12:19   ` Maxim Levitsky
@ 2022-05-05  1:38     ` Suravee Suthikulpanit
  2022-05-05  7:34       ` Maxim Levitsky
  0 siblings, 1 reply; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-05  1:38 UTC (permalink / raw)
  To: Maxim Levitsky, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

Maxim,

On 5/4/22 7:19 PM, Maxim Levitsky wrote:
> On Wed, 2022-05-04 at 02:31 -0500, Suravee Suthikulpanit wrote:
>> Update and refresh AVIC settings when guest APIC mode is updated
>> (e.g. changing between disabled, xAPIC, or x2APIC).
>>
>> Signed-off-by: Suravee Suthikulpanit<suravee.suthikulpanit@amd.com>
>> ---
>>   arch/x86/kvm/svm/avic.c | 16 ++++++++++++++++
>>   arch/x86/kvm/svm/svm.c  |  1 +
>>   2 files changed, 17 insertions(+)
>>
>> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
>> index 3ebeea19b487..d185dd8ddf17 100644
>> --- a/arch/x86/kvm/svm/avic.c
>> +++ b/arch/x86/kvm/svm/avic.c
>> @@ -691,6 +691,22 @@ void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu)
>>   	avic_handle_ldr_update(vcpu);
>>   }
>>   
>> +void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
>> +{
>> +	struct vcpu_svm *svm = to_svm(vcpu);
>> +
>> +	if (!lapic_in_kernel(vcpu) || (avic_mode == AVIC_MODE_NONE))
>> +		return;
>> +
>> +	if (kvm_get_apic_mode(vcpu) == LAPIC_MODE_INVALID) {
>> +		WARN_ONCE(true, "Invalid local APIC state (vcpu_id=%d)", vcpu->vcpu_id);
>> +		return;
>> +	}
>> +
>> +	kvm_vcpu_update_apicv(&svm->vcpu);
> Why to have this call? I think that all that is needed is only to call the
> avic_refresh_apicv_exec_ctrl.

When APIC mode is updated on each vCPU, we need to check and update
vcpu->arch.apicv_active accordingly, which happens in the kvm_vcpu_update_apicv()

One test case that would fail w/o the kvm_vcpu_update_apicv() is when
we boot a Linux guest w/ guest kernel option _nox2apic_, which Linux forces APIC
mode of vCPUs with APIC ID 255 and higher to disable. W/o this line of code, the VM
would not boot w/ more than 255 vCPUs.

Regards,
Suravee

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 11/14] KVM: SVM: Introduce hybrid-AVIC mode
  2022-05-04 12:32   ` Maxim Levitsky
@ 2022-05-05  3:57     ` Suravee Suthikulpanit
  0 siblings, 0 replies; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-05  3:57 UTC (permalink / raw)
  To: Maxim Levitsky, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

Maxim

On 5/4/22 7:32 PM, Maxim Levitsky wrote:
> Well strictly speaking, another thing that has to be done, other that removing the inhibit,
> is to 'hide' the AVIC's private memslot if one of vCPUs is in x2apic mode,
> although not doing this doesn't cause any harm as the guest is not supposed to poke at xAPIC
> mmio even when uses x2apic, and if it does it will get the normal AVIC acceleration,
> so probably it is better to not add any more complexity and leave it like that.

Agree, I'll note this detail in the comment above.

> ... 
> BTW, hardware wise, does 'X2APIC_MODE' keeps the emulation of the AVIC mmio, or
> not?

According to the AVIC documentation, when the AVIC is configured to use x2 APIC mode
the MMIO access method will be disabled. This is consistent with the Intel x2APIC specification,
where it states "accessing the MMIO interface when in x2APIC mode, the behavior is identical
to xAPIC in globally disabled state".

Regards,
Suravee

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 03/14] KVM: SVM: Detect X2APIC virtualization (x2AVIC) support
  2022-05-04 12:12   ` Maxim Levitsky
@ 2022-05-05  4:07     ` Suravee Suthikulpanit
  2022-05-05  7:38       ` Maxim Levitsky
  0 siblings, 1 reply; 27+ messages in thread
From: Suravee Suthikulpanit @ 2022-05-05  4:07 UTC (permalink / raw)
  To: Maxim Levitsky, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

Maxim,

On 5/4/22 7:12 PM, Maxim Levitsky wrote:
>> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
>> index a8f514212b87..fc3ba6071482 100644
>> --- a/arch/x86/kvm/svm/avic.c
>> +++ b/arch/x86/kvm/svm/avic.c
>> @@ -40,6 +40,15 @@
>>   #define AVIC_GATAG_TO_VMID(x)		((x >> AVIC_VCPU_ID_BITS) & AVIC_VM_ID_MASK)
>>   #define AVIC_GATAG_TO_VCPUID(x)		(x & AVIC_VCPU_ID_MASK)
>>   
>> +enum avic_modes {
>> +	AVIC_MODE_NONE = 0,
>> +	AVIC_MODE_X1,
>> +	AVIC_MODE_X2,
>> +};
>> +
>> +static bool force_avic;
>> +module_param_unsafe(force_avic, bool, 0444);
>> +
>>   /* Note:
>>    * This hash table is used to map VM_ID to a struct kvm_svm,
>>    * when handling AMD IOMMU GALOG notification to schedule in
>> @@ -50,6 +59,7 @@ static DEFINE_HASHTABLE(svm_vm_data_hash, SVM_VM_DATA_HASH_BITS);
>>   static u32 next_vm_id = 0;
>>   static bool next_vm_id_wrapped = 0;
>>   static DEFINE_SPINLOCK(svm_vm_data_hash_lock);
>> +static enum avic_modes avic_mode;
>>   
>>   /*
>>    * This is a wrapper of struct amd_iommu_ir_data.
>> @@ -1077,3 +1087,33 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
>>   
>>   	avic_vcpu_load(vcpu);
>>   }
>> +
>> +/*
>> + * Note:
>> + * - The module param avic enable both xAPIC and x2APIC mode.
>> + * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
>> + * - The mode can be switched at run-time.
>> + */
>> +bool avic_hardware_setup(struct kvm_x86_ops *x86_ops)
>> +{
>> +	if (!npt_enabled)
>> +		return false;
>> +
>> +	if (boot_cpu_has(X86_FEATURE_AVIC)) {
>> +		avic_mode = AVIC_MODE_X1;
>> +		pr_info("AVIC enabled\n");
>> +	} else if (force_avic) {
>> +		pr_warn("AVIC is not supported in CPUID but force enabled");
>> +		pr_warn("Your system might crash and burn");
> I think in this case avic_mode should also be set to AVIC_MODE_X1
> (Hopefully this won't be needed for systems that have x2avic enabled)

You are right. My appology :(

Actually, x2AVIC depends on both CPUID bits (i.e. X86_FEATURE_AVIC and X86_FEATURE_X2AVIC).
If the force_avic option is only applicable to only the X86_FEATURE_AVIC bit, we would
need to check for the following condition before enabling x2AVIC support in the driver:

   if ((X86_FEATURE_AVIC | avic_force) & X86_FEATURE_X2AVIC)
	avic_mode = AVIC_MODE_X2

Regards,
Suravee



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 08/14] KVM: SVM: Update AVIC settings when changing APIC mode
  2022-05-05  1:38     ` Suravee Suthikulpanit
@ 2022-05-05  7:34       ` Maxim Levitsky
  0 siblings, 0 replies; 27+ messages in thread
From: Maxim Levitsky @ 2022-05-05  7:34 UTC (permalink / raw)
  To: Suravee Suthikulpanit, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

On Thu, 2022-05-05 at 08:38 +0700, Suravee Suthikulpanit wrote:
> Maxim,
> 
> On 5/4/22 7:19 PM, Maxim Levitsky wrote:
> > On Wed, 2022-05-04 at 02:31 -0500, Suravee Suthikulpanit wrote:
> > > Update and refresh AVIC settings when guest APIC mode is updated
> > > (e.g. changing between disabled, xAPIC, or x2APIC).
> > > 
> > > Signed-off-by: Suravee Suthikulpanit<suravee.suthikulpanit@amd.com>
> > > ---
> > >   arch/x86/kvm/svm/avic.c | 16 ++++++++++++++++
> > >   arch/x86/kvm/svm/svm.c  |  1 +
> > >   2 files changed, 17 insertions(+)
> > > 
> > > diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> > > index 3ebeea19b487..d185dd8ddf17 100644
> > > --- a/arch/x86/kvm/svm/avic.c
> > > +++ b/arch/x86/kvm/svm/avic.c
> > > @@ -691,6 +691,22 @@ void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu)
> > >   	avic_handle_ldr_update(vcpu);
> > >   }
> > >   
> > > +void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
> > > +{
> > > +	struct vcpu_svm *svm = to_svm(vcpu);
> > > +
> > > +	if (!lapic_in_kernel(vcpu) || (avic_mode == AVIC_MODE_NONE))
> > > +		return;
> > > +
> > > +	if (kvm_get_apic_mode(vcpu) == LAPIC_MODE_INVALID) {
> > > +		WARN_ONCE(true, "Invalid local APIC state (vcpu_id=%d)", vcpu->vcpu_id);
> > > +		return;
> > > +	}
> > > +
> > > +	kvm_vcpu_update_apicv(&svm->vcpu);
> > Why to have this call? I think that all that is needed is only to call the
> > avic_refresh_apicv_exec_ctrl.
> 
> When APIC mode is updated on each vCPU, we need to check and update
> vcpu->arch.apicv_active accordingly, which happens in the kvm_vcpu_update_apicv()

This makes sense, but IMHO it would be better then to call kvm_vcpu_update_apicv
from the common code when apic mode changes then, because this logic should apply
to APICv as well.

In fact that logic of not activating AVIC was added in patch 12 
(and on second thought I think it  should be split to a separate patch), 
was added to common code, thus calling kvm_vcpu_update_apicv when the condition
of 'apic is disabled on this vCPU' should also be done by the common code.

Best regards,
	Maxim Levitsky

> 
> One test case that would fail w/o the kvm_vcpu_update_apicv() is when
> we boot a Linux guest w/ guest kernel option _nox2apic_, which Linux forces APIC
> mode of vCPUs with APIC ID 255 and higher to disable. W/o this line of code, the VM
> would not boot w/ more than 255 vCPUs.
> 
> Regards,
> Suravee
> 



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 03/14] KVM: SVM: Detect X2APIC virtualization (x2AVIC) support
  2022-05-05  4:07     ` Suravee Suthikulpanit
@ 2022-05-05  7:38       ` Maxim Levitsky
  0 siblings, 0 replies; 27+ messages in thread
From: Maxim Levitsky @ 2022-05-05  7:38 UTC (permalink / raw)
  To: Suravee Suthikulpanit, linux-kernel, kvm
  Cc: pbonzini, seanjc, joro, jon.grimm, wei.huang2, terry.bowman

On Thu, 2022-05-05 at 11:07 +0700, Suravee Suthikulpanit wrote:
> Maxim,
> 
> On 5/4/22 7:12 PM, Maxim Levitsky wrote:
> > > diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> > > index a8f514212b87..fc3ba6071482 100644
> > > --- a/arch/x86/kvm/svm/avic.c
> > > +++ b/arch/x86/kvm/svm/avic.c
> > > @@ -40,6 +40,15 @@
> > >   #define AVIC_GATAG_TO_VMID(x)		((x >> AVIC_VCPU_ID_BITS) & AVIC_VM_ID_MASK)
> > >   #define AVIC_GATAG_TO_VCPUID(x)		(x & AVIC_VCPU_ID_MASK)
> > >   
> > > +enum avic_modes {
> > > +	AVIC_MODE_NONE = 0,
> > > +	AVIC_MODE_X1,
> > > +	AVIC_MODE_X2,
> > > +};
> > > +
> > > +static bool force_avic;
> > > +module_param_unsafe(force_avic, bool, 0444);
> > > +
> > >   /* Note:
> > >    * This hash table is used to map VM_ID to a struct kvm_svm,
> > >    * when handling AMD IOMMU GALOG notification to schedule in
> > > @@ -50,6 +59,7 @@ static DEFINE_HASHTABLE(svm_vm_data_hash, SVM_VM_DATA_HASH_BITS);
> > >   static u32 next_vm_id = 0;
> > >   static bool next_vm_id_wrapped = 0;
> > >   static DEFINE_SPINLOCK(svm_vm_data_hash_lock);
> > > +static enum avic_modes avic_mode;
> > >   
> > >   /*
> > >    * This is a wrapper of struct amd_iommu_ir_data.
> > > @@ -1077,3 +1087,33 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
> > >   
> > >   	avic_vcpu_load(vcpu);
> > >   }
> > > +
> > > +/*
> > > + * Note:
> > > + * - The module param avic enable both xAPIC and x2APIC mode.
> > > + * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
> > > + * - The mode can be switched at run-time.
> > > + */
> > > +bool avic_hardware_setup(struct kvm_x86_ops *x86_ops)
> > > +{
> > > +	if (!npt_enabled)
> > > +		return false;
> > > +
> > > +	if (boot_cpu_has(X86_FEATURE_AVIC)) {
> > > +		avic_mode = AVIC_MODE_X1;
> > > +		pr_info("AVIC enabled\n");
> > > +	} else if (force_avic) {
> > > +		pr_warn("AVIC is not supported in CPUID but force enabled");
> > > +		pr_warn("Your system might crash and burn");
> > I think in this case avic_mode should also be set to AVIC_MODE_X1
> > (Hopefully this won't be needed for systems that have x2avic enabled)
> 
> You are right. My appology :(
> 
> Actually, x2AVIC depends on both CPUID bits (i.e. X86_FEATURE_AVIC and X86_FEATURE_X2AVIC).
> If the force_avic option is only applicable to only the X86_FEATURE_AVIC bit, we would
> need to check for the following condition before enabling x2AVIC support in the driver:
> 
>    if ((X86_FEATURE_AVIC | avic_force) & X86_FEATURE_X2AVIC)
> 	avic_mode = AVIC_MODE_X2

Let it be just for AVIC_MODE_X1, that is

else if (force_avic) {
	pr_warn("AVIC is not supported in CPUID but force enabled");
	pr_warn("Your system might crash and burn");
	avic_mode = AVIC_MODE_X1;

Best regards,
	Maxim Levitsky

> 
> Regards,
> Suravee
> 
> 



^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2022-05-05  7:42 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-04  7:31 [PATCH v3 00/14] Introducing AMD x2AVIC and hybrid-AVIC modes Suravee Suthikulpanit
2022-05-04  7:31 ` [PATCH v3 01/14] x86/cpufeatures: Introduce x2AVIC CPUID bit Suravee Suthikulpanit
2022-05-04  7:31 ` [PATCH v3 02/14] KVM: x86: lapic: Rename [GET/SET]_APIC_DEST_FIELD to [GET/SET]_XAPIC_DEST_FIELD Suravee Suthikulpanit
2022-05-04  7:31 ` [PATCH v3 03/14] KVM: SVM: Detect X2APIC virtualization (x2AVIC) support Suravee Suthikulpanit
2022-05-04 12:12   ` Maxim Levitsky
2022-05-05  4:07     ` Suravee Suthikulpanit
2022-05-05  7:38       ` Maxim Levitsky
2022-05-04  7:31 ` [PATCH v3 04/14] KVM: SVM: Update max number of vCPUs supported for x2AVIC mode Suravee Suthikulpanit
2022-05-04  7:31 ` [PATCH v3 05/14] KVM: SVM: Update avic_kick_target_vcpus to support 32-bit APIC ID Suravee Suthikulpanit
2022-05-04  7:31 ` [PATCH v3 06/14] KVM: SVM: Do not support updating APIC ID when in x2APIC mode Suravee Suthikulpanit
2022-05-04  7:31 ` [PATCH v3 07/14] KVM: SVM: Adding support for configuring x2APIC MSRs interception Suravee Suthikulpanit
2022-05-04 12:14   ` Maxim Levitsky
2022-05-04  7:31 ` [PATCH v3 08/14] KVM: SVM: Update AVIC settings when changing APIC mode Suravee Suthikulpanit
2022-05-04 12:19   ` Maxim Levitsky
2022-05-05  1:38     ` Suravee Suthikulpanit
2022-05-05  7:34       ` Maxim Levitsky
2022-05-04  7:31 ` [PATCH v3 09/14] KVM: SVM: Introduce helper functions to (de)activate AVIC and x2AVIC Suravee Suthikulpanit
2022-05-04  7:31 ` [PATCH v3 10/14] KVM: SVM: Do not throw warning when calling avic_vcpu_load on a running vcpu Suravee Suthikulpanit
2022-05-04  7:31 ` [PATCH v3 11/14] KVM: SVM: Introduce hybrid-AVIC mode Suravee Suthikulpanit
2022-05-04 12:32   ` Maxim Levitsky
2022-05-05  3:57     ` Suravee Suthikulpanit
2022-05-04  7:31 ` [PATCH v3 12/14] kvm/x86: Warning APICv inconsistency only when vcpu APIC mode is valid Suravee Suthikulpanit
2022-05-04 12:33   ` Maxim Levitsky
2022-05-04  7:31 ` [PATCH v3 13/14] KVM: SVM: Use target APIC ID to complete x2AVIC IRQs when possible Suravee Suthikulpanit
2022-05-04 12:34   ` Maxim Levitsky
2022-05-04  7:31 ` [PATCH v3 14/14] KVM: SVM: Add AVIC doorbell tracepoint Suravee Suthikulpanit
2022-05-04 12:36   ` Maxim Levitsky

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.