From 2034e060f55432ac13b2ea77b8d4cd107bdba98a Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 11 Jul 2011 01:52:53 +0400 Subject: [PATCH] kvm tools, bios: Make sure IRQ handlers segment is properly set The mini bios is copied at predefined place and should have constant segment address. Without this patch cs value varies depending on which code is compiled and how big bios is, it's kinda flowing error which is not triggered yet by a pure luck. Signed-off-by: Cyrill Gorcunov Signed-off-by: Pekka Enberg --- tools/kvm/bios.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tools/kvm/bios.c b/tools/kvm/bios.c index 94e914cc1740..6aefd1bdc19b 100644 --- a/tools/kvm/bios.c +++ b/tools/kvm/bios.c @@ -16,14 +16,14 @@ struct irq_handler { size_t size; }; -#define BIOS_IRQ_ADDR(name) (MB_BIOS_BEGIN + BIOS_OFFSET__##name) -#define BIOS_IRQ_FUNC(name) ((char *)&bios_rom[BIOS_OFFSET__##name]) -#define BIOS_IRQ_SIZE(name) (BIOS_ENTRY_SIZE(BIOS_OFFSET__##name)) +#define BIOS_IRQ_PA_ADDR(name) (MB_BIOS_BEGIN + BIOS_OFFSET__##name) +#define BIOS_IRQ_FUNC(name) ((char *)&bios_rom[BIOS_OFFSET__##name]) +#define BIOS_IRQ_SIZE(name) (BIOS_ENTRY_SIZE(BIOS_OFFSET__##name)) #define DEFINE_BIOS_IRQ_HANDLER(_irq, _handler) \ { \ .irq = _irq, \ - .address = BIOS_IRQ_ADDR(_handler), \ + .address = BIOS_IRQ_PA_ADDR(_handler), \ .handler = BIOS_IRQ_FUNC(_handler), \ .size = BIOS_IRQ_SIZE(_handler), \ } @@ -42,10 +42,12 @@ static void setup_irq_handler(struct kvm *kvm, struct irq_handler *handler) memcpy(p, handler->handler, handler->size); intr_desc = (struct real_intr_desc) { - .segment = REAL_SEGMENT(handler->address), - .offset = REAL_OFFSET(handler->address), + .segment = REAL_SEGMENT(MB_BIOS_BEGIN), + .offset = handler->address - MB_BIOS_BEGIN, }; + DIE_IF((handler->address - MB_BIOS_BEGIN) > (unsigned long)0xffff); + interrupt_table__set(&kvm->interrupt_table, &intr_desc, handler->irq); } @@ -139,10 +141,10 @@ void setup_bios(struct kvm *kvm) * Setup a *fake* real mode vector table, it has only * one real hadler which does just iret */ - address = BIOS_IRQ_ADDR(bios_intfake); + address = BIOS_IRQ_PA_ADDR(bios_intfake); intr_desc = (struct real_intr_desc) { - .segment = REAL_SEGMENT(address), - .offset = REAL_OFFSET(address), + .segment = REAL_SEGMENT(MB_BIOS_BEGIN), + .offset = address - MB_BIOS_BEGIN, }; interrupt_table__setup(&kvm->interrupt_table, &intr_desc); -- 2.39.5