From: Pekka Enberg Date: Sat, 27 Mar 2010 18:05:04 +0000 (+0200) Subject: kvm: Remove 'reset vector' hack X-Git-Tag: next-20110824~3^2~528^2~226 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=65266d7bd7d2c303b87c6d9c0d2ea3a6c4590be7;p=karo-tx-linux.git kvm: Remove 'reset vector' hack As explained by Avi Kivity, KVM on Intel requires segment 'base' to equal to 'selector * 16'. Fix that up and remove the 'reset vector' hack. Signed-off-by: Pekka Enberg --- diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c index af13a3120827..421467510791 100644 --- a/tools/kvm/kvm.c +++ b/tools/kvm/kvm.c @@ -153,27 +153,6 @@ static inline uint32_t segment_to_flat(uint16_t selector, uint16_t offset) return ((uint32_t)selector << 4) + (uint32_t) offset; } -/* - * HACK ALERT! KVM seems to be unable to run 16-bit real mode if 'cs' selector - * does not equal to 0xf000 at the beginning. To work around that, we need a - * 'reset vector' at 0xf000:0xfff0 that has an hard-coded jump to 0x000:0x7c000 - * where we also load the Linux kernel boot sector and setup code. - */ - -#define RESET_VECTOR_CS 0xf000 -#define RESET_VECTOR_IP 0xfff0 - -static unsigned char reset_vector_code[] = { 0xea, 0x00, 0x7c, 0x00, 0x00 }; - -static void load_reset_vector(struct kvm *self) -{ - void *p; - - p = guest_addr_to_host(self, segment_to_flat(RESET_VECTOR_CS, RESET_VECTOR_IP)); - - memcpy(p, reset_vector_code, ARRAY_SIZE(reset_vector_code)); -} - #define BOOT_LOADER_CS 0x0000 #define BOOT_LOADER_IP 0x7c00 @@ -284,13 +263,15 @@ static inline uint64_t ip_real_to_flat(struct kvm *self, uint64_t ip) void kvm__reset_vcpu(struct kvm *self) { - load_reset_vector(self); - self->sregs = (struct kvm_sregs) { .cr0 = 0x60000010ULL, .cs = (struct kvm_segment) { - .selector = RESET_VECTOR_CS, - .base = 0xffff0000UL, + /* + * KVM on Intel requires 'base' to be 'selector * 16' in + * real mode. + */ + .selector = BOOT_LOADER_CS, + .base = BOOT_LOADER_CS * 16, .limit = 0xffffU, .type = 0x0bU, .present = 1, @@ -354,7 +335,7 @@ void kvm__reset_vcpu(struct kvm *self) die_perror("KVM_SET_SREGS failed"); self->regs = (struct kvm_regs) { - .rip = RESET_VECTOR_IP, + .rip = BOOT_LOADER_IP, /* We start the guest in 16-bit real mode */ .rflags = 0x0000000000000002ULL, };