All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255
@ 2022-02-02  4:11 Suravee Suthikulpanit
  2022-02-02  4:11 ` [PATCH v4 1/3] KVM: SVM: Only call vcpu_(un)blocking when AVIC is enabled Suravee Suthikulpanit
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Suravee Suthikulpanit @ 2022-02-02  4:11 UTC (permalink / raw)
  To: linux-kernel, kvm, x86
  Cc: seanjc, mlevitsk, pbonzini, joro, tglx, mingo, bp, peterz, hpa,
	jon.grimm, Suravee Suthikulpanit

Originally, AMD SVM AVIC supports 8-bit host physical APIC ID.
However, newer AMD systems can have physical APIC ID larger than 255,
and AVIC hardware has been extended to support upto 12-bit host
physical APIC ID.

This series introduces a helper function in the APIC subsystem to get
the maximum physical APIC ID allowing the SVM AVIC driver to calculate
the proper size to program the host physical APIC ID in the AVIC
physical APIC ID table entry.

Regards,
Suravee Suthikulpanit

Changes from V3 (https://lkml.org/lkml/2021/12/13/1062)

 * Rename and modify patch 1/3 to also set vcpu_(un)blocking only
   when AVIC is enabled.

 * PATCH 3/3: Instead of dynamically calculate the host
   physical APIC ID mask value, use the max host physical APIC ID
   to determine whether to use 8-bit or 12-bit mask.

 * PATCH 3/3: change avic_host_physical_id_mask size.

 * PATCH 3/3: change warning condition in avic_vcpu_load()

Suravee Suthikulpanit (3):
  KVM: SVM: Only call vcpu_(un)blocking when AVIC is enabled.
  x86/apic: Add helper function to get maximum physical APIC ID
  KVM: SVM: Add support for 12-bit host physical APIC ID

 arch/x86/include/asm/apic.h |  1 +
 arch/x86/kernel/apic/apic.c |  6 +++++
 arch/x86/kvm/svm/avic.c     | 50 +++++++++++++++++++++++++++++--------
 arch/x86/kvm/svm/svm.c      | 10 ++------
 arch/x86/kvm/svm/svm.h      |  4 +--
 5 files changed, 49 insertions(+), 22 deletions(-)

-- 
2.25.1


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

* [PATCH v4 1/3] KVM: SVM: Only call vcpu_(un)blocking when AVIC is enabled.
  2022-02-02  4:11 [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255 Suravee Suthikulpanit
@ 2022-02-02  4:11 ` Suravee Suthikulpanit
  2022-02-02  6:26   ` Suthikulpanit, Suravee
  2022-02-02  4:11 ` [PATCH v4 2/3] x86/apic: Add helper function to get maximum physical APIC ID Suravee Suthikulpanit
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 6+ messages in thread
From: Suravee Suthikulpanit @ 2022-02-02  4:11 UTC (permalink / raw)
  To: linux-kernel, kvm, x86
  Cc: seanjc, mlevitsk, pbonzini, joro, tglx, mingo, bp, peterz, hpa,
	jon.grimm, Suravee Suthikulpanit

The kvm_x86_ops.vcpu_(un)blocking are needed by AVIC only.
Therefore, set the ops only when AVIC is enabled.

Also, refactor AVIC hardware setup logic into helper function
To prepare for upcoming AVIC changes.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/avic.c | 17 +++++++++++++++--
 arch/x86/kvm/svm/svm.c  | 10 ++--------
 arch/x86/kvm/svm/svm.h  |  3 +--
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 90364d02f22a..f5c6cab42d74 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -1027,7 +1027,7 @@ void avic_vcpu_put(struct kvm_vcpu *vcpu)
 	WRITE_ONCE(*(svm->avic_physical_id_cache), entry);
 }
 
-void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
+static void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
 {
 	if (!kvm_vcpu_apicv_active(vcpu))
 		return;
@@ -1052,7 +1052,7 @@ void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
 	preempt_enable();
 }
 
-void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
+static void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
 {
 	int cpu;
 
@@ -1066,3 +1066,16 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
 
 	put_cpu();
 }
+
+bool avic_hardware_setup(struct kvm_x86_ops *x86_ops)
+{
+	if (!npt_enabled || !boot_cpu_has(X86_FEATURE_AVIC))
+		return false;
+
+	x86_ops->vcpu_blocking = avic_vcpu_blocking,
+	x86_ops->vcpu_unblocking = avic_vcpu_unblocking,
+
+	pr_info("AVIC enabled\n");
+	amd_iommu_register_ga_log_notifier(&avic_ga_log_notifier);
+	return true;
+}
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 2c99b18d76c0..459edd2a1359 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4391,8 +4391,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
 	.prepare_guest_switch = svm_prepare_guest_switch,
 	.vcpu_load = svm_vcpu_load,
 	.vcpu_put = svm_vcpu_put,
-	.vcpu_blocking = avic_vcpu_blocking,
-	.vcpu_unblocking = avic_vcpu_unblocking,
 
 	.update_exception_bitmap = svm_update_exception_bitmap,
 	.get_msr_feature = svm_get_msr_feature,
@@ -4676,13 +4674,9 @@ static __init int svm_hardware_setup(void)
 			nrips = false;
 	}
 
-	enable_apicv = avic = avic && npt_enabled && boot_cpu_has(X86_FEATURE_AVIC);
+	enable_apicv = avic = avic && avic_hardware_setup(&svm_x86_ops);
 
-	if (enable_apicv) {
-		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;
 	}
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 47ef8f4a9358..f2507d11a31a 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -572,6 +572,7 @@ extern struct kvm_x86_nested_ops svm_nested_ops;
 
 #define VMCB_AVIC_APIC_BAR_MASK		0xFFFFFFFFFF000ULL
 
+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);
@@ -592,8 +593,6 @@ int svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec);
 bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu);
 int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
 		       uint32_t guest_irq, bool set);
-void avic_vcpu_blocking(struct kvm_vcpu *vcpu);
-void avic_vcpu_unblocking(struct kvm_vcpu *vcpu);
 
 /* sev.c */
 
-- 
2.25.1


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

* [PATCH v4 2/3] x86/apic: Add helper function to get maximum physical APIC ID
  2022-02-02  4:11 [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255 Suravee Suthikulpanit
  2022-02-02  4:11 ` [PATCH v4 1/3] KVM: SVM: Only call vcpu_(un)blocking when AVIC is enabled Suravee Suthikulpanit
@ 2022-02-02  4:11 ` Suravee Suthikulpanit
  2022-02-02  4:11 ` [PATCH v4 3/3] KVM: SVM: Add support for 12-bit host " Suravee Suthikulpanit
  2022-02-02 15:58 ` [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255 Sean Christopherson
  3 siblings, 0 replies; 6+ messages in thread
From: Suravee Suthikulpanit @ 2022-02-02  4:11 UTC (permalink / raw)
  To: linux-kernel, kvm, x86
  Cc: seanjc, mlevitsk, pbonzini, joro, tglx, mingo, bp, peterz, hpa,
	jon.grimm, Suravee Suthikulpanit

Export the max_physical_apicid via a helper function since this information
is required by AMD SVM AVIC support.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/include/asm/apic.h | 1 +
 arch/x86/kernel/apic/apic.c | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 48067af94678..77d9cb2a7e28 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -435,6 +435,7 @@ static inline void apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v)) {}
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 extern void apic_ack_irq(struct irq_data *data);
+extern u32 apic_get_max_phys_apicid(void);
 
 static inline void ack_APIC_irq(void)
 {
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index b70344bf6600..47653d8c05f2 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -2361,6 +2361,12 @@ bool apic_id_is_primary_thread(unsigned int apicid)
 }
 #endif
 
+u32 apic_get_max_phys_apicid(void)
+{
+	return max_physical_apicid;
+}
+EXPORT_SYMBOL_GPL(apic_get_max_phys_apicid);
+
 /*
  * Should use this API to allocate logical CPU IDs to keep nr_logical_cpuids
  * and cpuid_to_apicid[] synchronized.
-- 
2.25.1


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

* [PATCH v4 3/3] KVM: SVM: Add support for 12-bit host physical APIC ID
  2022-02-02  4:11 [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255 Suravee Suthikulpanit
  2022-02-02  4:11 ` [PATCH v4 1/3] KVM: SVM: Only call vcpu_(un)blocking when AVIC is enabled Suravee Suthikulpanit
  2022-02-02  4:11 ` [PATCH v4 2/3] x86/apic: Add helper function to get maximum physical APIC ID Suravee Suthikulpanit
@ 2022-02-02  4:11 ` Suravee Suthikulpanit
  2022-02-02 15:58 ` [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255 Sean Christopherson
  3 siblings, 0 replies; 6+ messages in thread
From: Suravee Suthikulpanit @ 2022-02-02  4:11 UTC (permalink / raw)
  To: linux-kernel, kvm, x86
  Cc: seanjc, mlevitsk, pbonzini, joro, tglx, mingo, bp, peterz, hpa,
	jon.grimm, Suravee Suthikulpanit

The AVIC physical APIC ID table entry contains the host physical
APIC ID field, which the hardware uses to keep track of where each
vCPU is running. Originally, the field is an 8-bit value. For system
w/ maximum physical APIC ID larger than 255, AVIC can support
upto 12-bit value.

However, there is no CPUID bit to help determine the AVIC capability
to support 12-bit host physical APIC ID. Therefore, use the maximum
physical APIC ID available on the system to determine the proper
host physical APIC ID mask size.

Cc: Sean Christopherson <seanjc@google.com>
Cc: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 arch/x86/kvm/svm/avic.c | 33 ++++++++++++++++++++++++---------
 arch/x86/kvm/svm/svm.h  |  1 -
 2 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index f5c6cab42d74..3ca5776348a8 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -19,6 +19,7 @@
 #include <linux/amd-iommu.h>
 #include <linux/kvm_host.h>
 
+#include <asm/apic.h>
 #include <asm/irq_remapping.h>
 
 #include "trace.h"
@@ -63,6 +64,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 u16 avic_host_physical_id_mask;
 static DEFINE_SPINLOCK(svm_vm_data_hash_lock);
 
 /*
@@ -133,6 +135,23 @@ void avic_vm_destroy(struct kvm *kvm)
 	spin_unlock_irqrestore(&svm_vm_data_hash_lock, flags);
 }
 
+static void avic_init_host_physical_apicid_mask(void)
+{
+	u32 count = get_count_order(apic_get_max_phys_apicid());
+
+	/*
+	 * Depending on the maximum host physical APIC ID available
+	 * on the system, AVIC can support upto 8-bit or 12-bit host
+	 * physical APIC ID.
+	 */
+	if (count <= 8)
+		avic_host_physical_id_mask = GENMASK(7, 0);
+	else
+		avic_host_physical_id_mask = GENMASK(11, 0);
+	pr_debug("Using AVIC host physical APIC ID mask %#0x\n",
+		 avic_host_physical_id_mask);
+}
+
 int avic_vm_init(struct kvm *kvm)
 {
 	unsigned long flags;
@@ -974,17 +993,12 @@ avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, bool r)
 void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
 	u64 entry;
-	/* ID = 0xff (broadcast), ID > 0xff (reserved) */
-	int h_physical_id = kvm_cpu_get_apicid(cpu);
+	u16 h_physical_id = (u16)kvm_cpu_get_apicid(cpu);
 	struct vcpu_svm *svm = to_svm(vcpu);
 
 	lockdep_assert_preemption_disabled();
 
-	/*
-	 * Since the host physical APIC id is 8 bits,
-	 * we can support host APIC ID upto 255.
-	 */
-	if (WARN_ON(h_physical_id > AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK))
+	if (WARN_ON((h_physical_id & avic_host_physical_id_mask) != h_physical_id))
 		return;
 
 	/*
@@ -1000,8 +1014,8 @@ void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	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);
+	entry &= ~((u64)avic_host_physical_id_mask);
+	entry |= h_physical_id;
 	entry |= AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK;
 
 	WRITE_ONCE(*(svm->avic_physical_id_cache), entry);
@@ -1076,6 +1090,7 @@ bool avic_hardware_setup(struct kvm_x86_ops *x86_ops)
 	x86_ops->vcpu_unblocking = avic_vcpu_unblocking,
 
 	pr_info("AVIC enabled\n");
+	avic_init_host_physical_apicid_mask();
 	amd_iommu_register_ga_log_notifier(&avic_ga_log_notifier);
 	return true;
 }
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index f2507d11a31a..70c55f20c0f1 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -565,7 +565,6 @@ extern struct kvm_x86_nested_ops svm_nested_ops;
 #define AVIC_LOGICAL_ID_ENTRY_VALID_BIT			31
 #define AVIC_LOGICAL_ID_ENTRY_VALID_MASK		(1 << 31)
 
-#define AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK	(0xFFULL)
 #define AVIC_PHYSICAL_ID_ENTRY_BACKING_PAGE_MASK	(0xFFFFFFFFFFULL << 12)
 #define AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK		(1ULL << 62)
 #define AVIC_PHYSICAL_ID_ENTRY_VALID_MASK		(1ULL << 63)
-- 
2.25.1


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

* Re: [PATCH v4 1/3] KVM: SVM: Only call vcpu_(un)blocking when AVIC is enabled.
  2022-02-02  4:11 ` [PATCH v4 1/3] KVM: SVM: Only call vcpu_(un)blocking when AVIC is enabled Suravee Suthikulpanit
@ 2022-02-02  6:26   ` Suthikulpanit, Suravee
  0 siblings, 0 replies; 6+ messages in thread
From: Suthikulpanit, Suravee @ 2022-02-02  6:26 UTC (permalink / raw)
  To: linux-kernel, kvm, x86
  Cc: seanjc, mlevitsk, pbonzini, joro, tglx, mingo, bp, peterz, hpa,
	jon.grimm



On 2/2/2022 11:11 AM, Suravee Suthikulpanit wrote:
> The kvm_x86_ops.vcpu_(un)blocking are needed by AVIC only.
> Therefore, set the ops only when AVIC is enabled.
> 
> Also, refactor AVIC hardware setup logic into helper function
> To prepare for upcoming AVIC changes.
> 
> Suggested-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
>   arch/x86/kvm/svm/avic.c | 17 +++++++++++++++--
>   arch/x86/kvm/svm/svm.c  | 10 ++--------
>   arch/x86/kvm/svm/svm.h  |  3 +--
>   3 files changed, 18 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index 90364d02f22a..f5c6cab42d74 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -1027,7 +1027,7 @@ void avic_vcpu_put(struct kvm_vcpu *vcpu)
>   	WRITE_ONCE(*(svm->avic_physical_id_cache), entry);
>   }
>   
> -void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
> +static void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
>   {
>   	if (!kvm_vcpu_apicv_active(vcpu))
>   		return;
> @@ -1052,7 +1052,7 @@ void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
>   	preempt_enable();
>   }
>   
> -void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
> +static void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
>   {
>   	int cpu;
>   
> @@ -1066,3 +1066,16 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
>   
>   	put_cpu();
>   }
> +
> +bool avic_hardware_setup(struct kvm_x86_ops *x86_ops)
> +{
> +	if (!npt_enabled || !boot_cpu_has(X86_FEATURE_AVIC))
> +		return false;
> +
> +	x86_ops->vcpu_blocking = avic_vcpu_blocking,
> +	x86_ops->vcpu_unblocking = avic_vcpu_unblocking,

Sorry for confusion, I made a mistake during patch re basing. I'll send out V5.

Suravee

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

* Re: [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255
  2022-02-02  4:11 [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255 Suravee Suthikulpanit
                   ` (2 preceding siblings ...)
  2022-02-02  4:11 ` [PATCH v4 3/3] KVM: SVM: Add support for 12-bit host " Suravee Suthikulpanit
@ 2022-02-02 15:58 ` Sean Christopherson
  3 siblings, 0 replies; 6+ messages in thread
From: Sean Christopherson @ 2022-02-02 15:58 UTC (permalink / raw)
  To: Suravee Suthikulpanit
  Cc: linux-kernel, kvm, x86, mlevitsk, pbonzini, joro, tglx, mingo,
	bp, peterz, hpa, jon.grimm

On Tue, Feb 01, 2022, Suravee Suthikulpanit wrote:
> Originally, AMD SVM AVIC supports 8-bit host physical APIC ID.
> However, newer AMD systems can have physical APIC ID larger than 255,
> and AVIC hardware has been extended to support upto 12-bit host
> physical APIC ID.
> 
> This series introduces a helper function in the APIC subsystem to get
> the maximum physical APIC ID allowing the SVM AVIC driver to calculate
> the proper size to program the host physical APIC ID in the AVIC
> physical APIC ID table entry.

NAK to this version.  Please wait until discussion on the previous versions comes
to a stop.  If a reviewer is non-responsive then that's one thing, but we were
literally just discussing this yesterday.

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

end of thread, other threads:[~2022-02-02 15:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-02  4:11 [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255 Suravee Suthikulpanit
2022-02-02  4:11 ` [PATCH v4 1/3] KVM: SVM: Only call vcpu_(un)blocking when AVIC is enabled Suravee Suthikulpanit
2022-02-02  6:26   ` Suthikulpanit, Suravee
2022-02-02  4:11 ` [PATCH v4 2/3] x86/apic: Add helper function to get maximum physical APIC ID Suravee Suthikulpanit
2022-02-02  4:11 ` [PATCH v4 3/3] KVM: SVM: Add support for 12-bit host " Suravee Suthikulpanit
2022-02-02 15:58 ` [PATCH v4 0/3] svm: avic: Allow AVIC support on system w/ physical APIC ID > 255 Sean Christopherson

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.