All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, Sean Christopherson <seanjc@google.com>
Subject: [kvm-unit-tests PATCH 7/8] x86: apic: Track APIC ops on a per-cpu basis
Date: Fri, 21 Jan 2022 23:18:51 +0000	[thread overview]
Message-ID: <20220121231852.1439917-8-seanjc@google.com> (raw)
In-Reply-To: <20220121231852.1439917-1-seanjc@google.com>

Track the virtual function table to handle xAPIC vs. x2APIC on a per-cpu
basis.  Using a common global is racy as nothing in KUT synchronizes
CPUs when switching to/from x2APIC.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 lib/x86/apic.c | 20 ++++++++++++--------
 lib/x86/smp.h  |  2 ++
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/lib/x86/apic.c b/lib/x86/apic.c
index 44a6ad38..d7137b61 100644
--- a/lib/x86/apic.c
+++ b/lib/x86/apic.c
@@ -2,6 +2,7 @@
 #include "apic.h"
 #include "msr.h"
 #include "processor.h"
+#include "smp.h"
 #include "asm/barrier.h"
 
 void *g_apic = (void *)0xfee00000;
@@ -15,6 +16,11 @@ struct apic_ops {
 	u32 (*id)(void);
 };
 
+static struct apic_ops *get_apic_ops(void)
+{
+	return this_cpu_read_apic_ops();
+}
+
 static void outb(unsigned char data, unsigned short port)
 {
 	asm volatile ("out %0, %1" : : "a"(data), "d"(port));
@@ -60,8 +66,6 @@ static const struct apic_ops xapic_ops = {
 	.id = xapic_id,
 };
 
-static const struct apic_ops *apic_ops = &xapic_ops;
-
 static u32 x2apic_read(unsigned reg)
 {
 	unsigned a, d;
@@ -96,12 +100,12 @@ static const struct apic_ops x2apic_ops = {
 
 u32 apic_read(unsigned reg)
 {
-	return apic_ops->reg_read(reg);
+	return get_apic_ops()->reg_read(reg);
 }
 
 void apic_write(unsigned reg, u32 val)
 {
-	apic_ops->reg_write(reg, val);
+	get_apic_ops()->reg_write(reg, val);
 }
 
 bool apic_read_bit(unsigned reg, int n)
@@ -113,12 +117,12 @@ bool apic_read_bit(unsigned reg, int n)
 
 void apic_icr_write(u32 val, u32 dest)
 {
-	apic_ops->icr_write(val, dest);
+	get_apic_ops()->icr_write(val, dest);
 }
 
 uint32_t apic_id(void)
 {
-	return apic_ops->id();
+	return get_apic_ops()->id();
 }
 
 uint8_t apic_get_tpr(void)
@@ -152,7 +156,7 @@ int enable_x2apic(void)
 		asm ("rdmsr" : "=a"(a), "=d"(d) : "c"(MSR_IA32_APICBASE));
 		a |= 1 << 10;
 		asm ("wrmsr" : : "a"(a), "d"(d), "c"(MSR_IA32_APICBASE));
-		apic_ops = &x2apic_ops;
+		this_cpu_write_apic_ops((void *)&x2apic_ops);
 		return 1;
 	} else {
 		return 0;
@@ -162,7 +166,7 @@ int enable_x2apic(void)
 void disable_apic(void)
 {
 	wrmsr(MSR_IA32_APICBASE, rdmsr(MSR_IA32_APICBASE) & ~(APIC_EN | APIC_EXTD));
-	apic_ops = &xapic_ops;
+	this_cpu_write_apic_ops((void *)&xapic_ops);
 }
 
 void reset_apic(void)
diff --git a/lib/x86/smp.h b/lib/x86/smp.h
index eb037a46..bd303c28 100644
--- a/lib/x86/smp.h
+++ b/lib/x86/smp.h
@@ -15,6 +15,7 @@ struct percpu_data {
 		};
 		uint32_t exception_data;
 	};
+	void *apic_ops;
 };
 
 #define typeof_percpu(name) typeof(((struct percpu_data *)0)->name)
@@ -66,6 +67,7 @@ BUILD_PERCPU_OP(smp_id);
 BUILD_PERCPU_OP(exception_vector);
 BUILD_PERCPU_OP(exception_rflags_rf);
 BUILD_PERCPU_OP(exception_error_code);
+BUILD_PERCPU_OP(apic_ops);
 
 void smp_init(void);
 
-- 
2.35.0.rc0.227.g00780c9af4-goog


  parent reply	other threads:[~2022-01-21 23:19 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-21 23:18 [kvm-unit-tests PATCH 0/8] x86: APIC bug fix and cleanup Sean Christopherson
2022-01-21 23:18 ` [kvm-unit-tests PATCH 1/8] x86: Always use legacy xAPIC to get APIC ID during TSS setup Sean Christopherson
2022-01-22  1:18   ` David Matlack
2022-01-21 23:18 ` [kvm-unit-tests PATCH 2/8] x86: nVMX: Load actual GS.base for both guest and host Sean Christopherson
2022-01-21 23:18 ` [kvm-unit-tests PATCH 3/8] x86: smp: Replace spaces with tabs Sean Christopherson
2022-01-21 23:18 ` [kvm-unit-tests PATCH 4/8] x86: desc: " Sean Christopherson
2022-01-21 23:18 ` [kvm-unit-tests PATCH 5/8] x86: Add proper helpers for per-cpu reads/writes Sean Christopherson
2022-01-21 23:18 ` [kvm-unit-tests PATCH 6/8] x86: apic: Replace spaces with tabs Sean Christopherson
2022-01-21 23:18 ` Sean Christopherson [this message]
2022-01-21 23:18 ` [kvm-unit-tests PATCH 8/8] x86: apic: Make xAPIC and I/O APIC pointers static Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220121231852.1439917-8-seanjc@google.com \
    --to=seanjc@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.