[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/boot: Fix boot following c/s b6c2c7f48a
c/s b6c2c7f48a unfortunately broke booting on affected systems. Most of the time, ioemul_handle_quirk() doesn't write a custom stub, and the redundant call was depending on the seemingly-pointless writing of the default stub. Alter the ioemul_handle_quirk() API to return a boolean if a custom stub was written, allowing its caller to know whether it should write a default stub instead. Finally, adjust the /* Regular stubs */ comment to make it clearer that the 16 refers to the length of the emul stub opcode. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> --- xen/arch/x86/ioport_emulate.c | 6 ++++-- xen/arch/x86/pv/emul-priv-op.c | 12 ++++++++---- xen/arch/x86/traps.c | 2 +- xen/include/asm-x86/io.h | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/ioport_emulate.c b/xen/arch/x86/ioport_emulate.c index 1f6f794..e80993a 100644 --- a/xen/arch/x86/ioport_emulate.c +++ b/xen/arch/x86/ioport_emulate.c @@ -8,14 +8,14 @@ #include <xen/sched.h> #include <xen/dmi.h> -static void ioemul_handle_proliant_quirk( +static bool ioemul_handle_proliant_quirk( u8 opcode, char *io_emul_stub, struct cpu_user_regs *regs) { uint16_t port = regs->dx; uint8_t value = regs->al; if ( (opcode != 0xee) || (port != 0xcd4) || !(value & 0x80) ) - return; + return false; /* pushf */ io_emul_stub[0] = 0x9c; @@ -37,6 +37,8 @@ static void ioemul_handle_proliant_quirk( io_emul_stub[9] = 0xc3; BUILD_BUG_ON(IOEMUL_QUIRK_STUB_BYTES < 10); + + return true; } static int __init proliant_quirk(struct dmi_system_id *d) diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c index 4087cf2..ebd6dc1 100644 --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -76,6 +76,8 @@ typedef void io_emul_stub_t(struct cpu_user_regs *); static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode, unsigned int port, unsigned int bytes) { + bool use_quirk_stub = false; + if ( !ctxt->io_emul_stub ) ctxt->io_emul_stub = map_domain_page(_mfn(this_cpu(stubs.mfn))) + (this_cpu(stubs.addr) & @@ -90,7 +92,11 @@ static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode, ctxt->io_emul_stub[10] = 0xff; ctxt->io_emul_stub[11] = 0xd1; - if ( likely(!ioemul_handle_quirk) ) + if ( unlikely(ioemul_handle_quirk) ) + use_quirk_stub = ioemul_handle_quirk(opcode, &ctxt->io_emul_stub[12], + ctxt->ctxt.regs); + + if ( !use_quirk_stub ) { /* data16 or nop */ ctxt->io_emul_stub[12] = (bytes != 2) ? 0x90 : 0x66; @@ -101,10 +107,8 @@ static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode, /* ret (jumps to guest_to_host_gpr_switch) */ ctxt->io_emul_stub[15] = 0xc3; } - else - ioemul_handle_quirk(opcode, &ctxt->io_emul_stub[12], ctxt->ctxt.regs); - BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX(16, /* Regular stubs */ + BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX(16, /* Default emul stub */ 12 + IOEMUL_QUIRK_STUB_BYTES)); /* Handy function-typed pointer to the stub. */ diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index db16a44..2509ea7 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -107,7 +107,7 @@ idt_entry_t idt_table[IDT_ENTRIES]; /* Pointer to the IDT of every CPU. */ idt_entry_t *idt_tables[NR_CPUS] __read_mostly; -void (*ioemul_handle_quirk)( +bool (*ioemul_handle_quirk)( u8 opcode, char *io_emul_stub, struct cpu_user_regs *regs); static int debug_stack_lines = 20; diff --git a/xen/include/asm-x86/io.h b/xen/include/asm-x86/io.h index e6bb20c..4d2064e 100644 --- a/xen/include/asm-x86/io.h +++ b/xen/include/asm-x86/io.h @@ -52,7 +52,7 @@ extern void (*pv_post_outb_hook)(unsigned int port, u8 value); /* Function pointer used to handle platform specific I/O port emulation. */ #define IOEMUL_QUIRK_STUB_BYTES 10 -extern void (*ioemul_handle_quirk)( +extern bool (*ioemul_handle_quirk)( u8 opcode, char *io_emul_stub, struct cpu_user_regs *regs); #endif -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |