From 22489bb09961e51be8d191afea101a43112ba267 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 30 Mar 2010 23:26:29 +0400 Subject: [PATCH] kvm: Put fake bios interrupt handlers into known memory area Instead of hacking boot protocol header better to place interrupt handlers into BDA. Signed-off-by: Cyrill Gorcunov Signed-off-by: Pekka Enberg --- include/kvm/interrupt.h | 7 +++++++ kvm.c | 27 ++++++++++++--------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/include/kvm/interrupt.h b/include/kvm/interrupt.h index c34772a..f6c1949 100644 --- a/include/kvm/interrupt.h +++ b/include/kvm/interrupt.h @@ -3,6 +3,13 @@ #include +/* + * BIOS data area + */ +#define BDA_START 0xf0000 +#define BDA_END 0xfffff +#define BDA_SIZE (BDA_END - BDA_START) + #define REAL_INTR_BASE 0x0000 #define REAL_INTR_VECTORS 256 diff --git a/kvm.c b/kvm.c index 4973e3e..a9df1fe 100644 --- a/kvm.c +++ b/kvm.c @@ -192,16 +192,17 @@ static int load_flat_binary(struct kvm *self, int fd) #define BZ_KERNEL_START 0x100000UL static const char *BZIMAGE_MAGIC = "HdrS"; +static const char fakebios_vector[] = { 0xcf }; #define BZ_DEFAULT_SETUP_SECTS 4 static bool load_bzimage(struct kvm *self, int fd, const char *kernel_cmdline) { struct real_intr_desc intr; - struct boot_params boot, *t; + struct boot_params boot; unsigned long setup_sects; ssize_t setup_size; - void *p, *v; + void *p; int nr; /* @@ -244,21 +245,17 @@ static bool load_bzimage(struct kvm *self, int fd, const char *kernel_cmdline) self->boot_sp = BOOT_LOADER_SP; /* - * Setup a *fake* real mode IVT, it has only one real - * hadler which does just iret + * Setup a *fake* real mode vector table, it has only + * one real hadler which does just iret + * + * we need a place for 1 byte so lets put + * it where the BIOS lives -- BDA area */ - /* - * we need a place for 2 bytes so lets do - * a hack and use spare place in bootparams - */ - t = guest_real_to_host(self, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP); - v = guest_flat_to_host(self, 0); - t->hdr._pad2[0] = 0xfb; /* sti */ - t->hdr._pad2[1] = 0xcf; /* iret */ - nr = (void *)&t->hdr._pad2[0] - v; + p = guest_flat_to_host(self, BDA_START); + memcpy(p, fakebios_vector, sizeof(fakebios_vector)); intr = (struct real_intr_desc) { - .segment = nr >> 4, - .offset = (nr - (nr & ~0xf)), + .segment = BDA_START >> 4, + .offset = 0, }; p = guest_flat_to_host(self, 0); interrupt_table__setup(&self->interrupt_table, &intr);