mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
x86/ioemul: Account for ioemul_handle_quirk() in stub length check
The opcode potentially written into ctxt->io_emul_stub[] in the case that ioemul_handle_quirk() is overriding the default logic isnt accounted for in the build-time check that the stubs are large enough. Introduce IOEMUL_QUIRK_STUB_BYTES and use for both the main and quirk stub cases. As a slim optimisation, avoid writing out the default stub when we know we are going to overwrite it. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
d51baf310e
commit
b6c2c7f48a
3 files changed
+18
-10
No files matched your search
@@ -35,6 +35,8 @@ static void ioemul_handle_proliant_quirk(
|
||||
io_emul_stub[8] = 0x9d;
|
||||
/* ret */
|
||||
io_emul_stub[9] = 0xc3;
|
||||
|
||||
BUILD_BUG_ON(IOEMUL_QUIRK_STUB_BYTES < 10);
|
||||
}
|
||||
|
||||
static int __init proliant_quirk(struct dmi_system_id *d)
|
||||
|
||||
@@ -89,19 +89,24 @@ static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode,
|
||||
/* callq *%rcx */
|
||||
ctxt->io_emul_stub[10] = 0xff;
|
||||
ctxt->io_emul_stub[11] = 0xd1;
|
||||
/* data16 or nop */
|
||||
ctxt->io_emul_stub[12] = (bytes != 2) ? 0x90 : 0x66;
|
||||
/* <io-access opcode> */
|
||||
ctxt->io_emul_stub[13] = opcode;
|
||||
/* imm8 or nop */
|
||||
ctxt->io_emul_stub[14] = !(opcode & 8) ? port : 0x90;
|
||||
/* ret (jumps to guest_to_host_gpr_switch) */
|
||||
ctxt->io_emul_stub[15] = 0xc3;
|
||||
BUILD_BUG_ON(STUB_BUF_SIZE / 2 < 16);
|
||||
|
||||
if ( ioemul_handle_quirk )
|
||||
if ( likely(!ioemul_handle_quirk) )
|
||||
{
|
||||
/* data16 or nop */
|
||||
ctxt->io_emul_stub[12] = (bytes != 2) ? 0x90 : 0x66;
|
||||
/* <io-access opcode> */
|
||||
ctxt->io_emul_stub[13] = opcode;
|
||||
/* imm8 or nop */
|
||||
ctxt->io_emul_stub[14] = !(opcode & 8) ? port : 0x90;
|
||||
/* 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 */
|
||||
12 + IOEMUL_QUIRK_STUB_BYTES));
|
||||
|
||||
/* Handy function-typed pointer to the stub. */
|
||||
return (void *)(this_cpu(stubs.addr) + STUB_BUF_SIZE / 2);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ __OUT(l,,int)
|
||||
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)(
|
||||
u8 opcode, char *io_emul_stub, struct cpu_user_regs *regs);
|
||||
|
||||
|
||||