Skip to content

Commit

Permalink
x86/apic: Add apic->eoi_write() callback
Browse files Browse the repository at this point in the history
Add eoi_write callback so that kvm can override
eoi accesses without touching the rest of the apic.
As a side-effect, this will enable a micro-optimization
for apics using msr.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: gleb@redhat.com
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: http://lkml.kernel.org/r/0df425d746c49ac2ecc405174df87752869629d2.1337184153.git.mst@redhat.com
[ tidied it up a bit ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Michael S. Tsirkin authored and Ingo Molnar committed May 18, 2012
1 parent 4ebcc24 commit 2a43195
Show file tree
Hide file tree
Showing 12 changed files with 28 additions and 1 deletion.
16 changes: 15 additions & 1 deletion arch/x86/include/asm/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,14 @@ struct apic {
/* apic ops */
u32 (*read)(u32 reg);
void (*write)(u32 reg, u32 v);
/*
* ->eoi_write() has the same signature as ->write().
*
* Drivers can support both ->eoi_write() and ->write() by passing the same
* callback value. Kernel can override ->eoi_write() and fall back
* on write for EOI.
*/
void (*eoi_write)(u32 reg, u32 v);
u64 (*icr_read)(void);
void (*icr_write)(u32 low, u32 high);
void (*wait_icr_idle)(void);
Expand Down Expand Up @@ -426,6 +434,11 @@ static inline void apic_write(u32 reg, u32 val)
apic->write(reg, val);
}

static inline void apic_eoi(void)
{
apic->eoi_write(APIC_EOI, APIC_EOI_ACK);
}

static inline u64 apic_icr_read(void)
{
return apic->icr_read();
Expand All @@ -450,6 +463,7 @@ static inline u32 safe_apic_wait_icr_idle(void)

static inline u32 apic_read(u32 reg) { return 0; }
static inline void apic_write(u32 reg, u32 val) { }
static inline void apic_eoi(void) { }
static inline u64 apic_icr_read(void) { return 0; }
static inline void apic_icr_write(u32 low, u32 high) { }
static inline void apic_wait_icr_idle(void) { }
Expand All @@ -463,7 +477,7 @@ static inline void ack_APIC_irq(void)
* ack_APIC_irq() actually gets compiled as a single instruction
* ... yummie.
*/
apic_write(APIC_EOI, APIC_EOI_ACK);
apic_eoi();
}

static inline unsigned default_get_apic_id(unsigned long x)
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/apic/apic_flat_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ static struct apic apic_flat = {

.read = native_apic_mem_read,
.write = native_apic_mem_write,
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
Expand Down Expand Up @@ -386,6 +387,7 @@ static struct apic apic_physflat = {

.read = native_apic_mem_read,
.write = native_apic_mem_write,
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/apic_noop.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ struct apic apic_noop = {

.read = noop_apic_read,
.write = noop_apic_write,
.eoi_write = noop_apic_write,
.icr_read = noop_apic_icr_read,
.icr_write = noop_apic_icr_write,
.wait_icr_idle = noop_apic_wait_icr_idle,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/apic_numachip.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ static struct apic apic_numachip __refconst = {

.read = native_apic_mem_read,
.write = native_apic_mem_write,
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/bigsmp_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ static struct apic apic_bigsmp = {

.read = native_apic_mem_read,
.write = native_apic_mem_write,
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/apic/es7000_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ static struct apic __refdata apic_es7000_cluster = {

.read = native_apic_mem_read,
.write = native_apic_mem_write,
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
Expand Down Expand Up @@ -742,6 +743,7 @@ static struct apic __refdata apic_es7000 = {

.read = native_apic_mem_read,
.write = native_apic_mem_write,
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/numaq_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ static struct apic __refdata apic_numaq = {

.read = native_apic_mem_read,
.write = native_apic_mem_write,
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/probe_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ static struct apic apic_default = {

.read = native_apic_mem_read,
.write = native_apic_mem_write,
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/summit_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ static struct apic apic_summit = {

.read = native_apic_mem_read,
.write = native_apic_mem_write,
.eoi_write = native_apic_mem_write,
.icr_read = native_apic_icr_read,
.icr_write = native_apic_icr_write,
.wait_icr_idle = native_apic_wait_icr_idle,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/x2apic_cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ static struct apic apic_x2apic_cluster = {

.read = native_apic_msr_read,
.write = native_apic_msr_write,
.eoi_write = native_apic_msr_write,
.icr_read = native_x2apic_icr_read,
.icr_write = native_x2apic_icr_write,
.wait_icr_idle = native_x2apic_wait_icr_idle,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/x2apic_phys.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static struct apic apic_x2apic_phys = {

.read = native_apic_msr_read,
.write = native_apic_msr_write,
.eoi_write = native_apic_msr_write,
.icr_read = native_x2apic_icr_read,
.icr_write = native_x2apic_icr_write,
.wait_icr_idle = native_x2apic_wait_icr_idle,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/x2apic_uv_x.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ static struct apic __refdata apic_x2apic_uv_x = {

.read = native_apic_msr_read,
.write = native_apic_msr_write,
.eoi_write = native_apic_msr_write,
.icr_read = native_x2apic_icr_read,
.icr_write = native_x2apic_icr_write,
.wait_icr_idle = native_x2apic_wait_icr_idle,
Expand Down

0 comments on commit 2a43195

Please sign in to comment.