kvm: Setup fake IVT table

Setup fake interrupt handlers for real mode, it consists of iret opcode only.

Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
This commit is contained in:
Cyrill Gorcunov
2015-06-01 16:39:38 +01:00
committed by Will Deacon
parent b1b71cd91a
commit ea68482839
3 changed files with 26 additions and 1 deletions
+8
View File
@@ -36,3 +36,11 @@ void ivt_set_entry(struct ivt_entry e, unsigned int n)
if (n < IVT_VECTORS)
ivt_table[n] = e;
}
void ivt_set_all(struct ivt_entry e)
{
unsigned int i;
for (i = 0; i < IVT_VECTORS; i++)
ivt_table[i] = e;
}
+2 -1
View File
@@ -5,11 +5,12 @@
#define IVT_VECTORS 256
struct ivt_entry {
uint16_t segment;
uint16_t offset;
uint16_t segment;
} __attribute__((packed));
void ivt_reset(void);
void ivt_copy_table(void *dst, unsigned int size);
struct ivt_entry * const ivt_get_entry(unsigned int n);
void ivt_set_entry(struct ivt_entry e, unsigned int n);
void ivt_set_all(struct ivt_entry e);
+16
View File
@@ -16,6 +16,7 @@
#include <stdio.h>
#include <fcntl.h>
#include "ivt.h"
#include "util.h"
/*
@@ -198,6 +199,7 @@ static bool load_bzimage(struct kvm *self, int fd, const char *kernel_cmdline)
{
unsigned long setup_sects;
struct boot_params boot;
struct ivt_entry real_mode_irq;
ssize_t setup_size;
void *p;
int nr;
@@ -241,6 +243,20 @@ static bool load_bzimage(struct kvm *self, int fd, const char *kernel_cmdline)
self->boot_ip = BOOT_LOADER_IP + 0x200;
self->boot_sp = BOOT_LOADER_SP;
/*
* Setup a *fake* real mode IVT, it has only one real
* hadler which does just iret
*/
real_mode_irq = (struct ivt_entry) {
.segment = 0,
.offset = 0x400 + 1,
};
ivt_set_all(real_mode_irq);
p = guest_flat_to_host(self, 0);
ivt_copy_table(p, IVT_VECTORS * sizeof(real_mode_irq));
p += IVT_VECTORS * sizeof(real_mode_irq) + 1;
*(char *)p = 0xcf; /* iret here */
return true;
}