mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-09-04 20:51:28 +00:00
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:
committed by
Will Deacon
parent
b1b71cd91a
commit
ea68482839
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user