aboutsummaryrefslogtreecommitdiff
path: root/qemu-kvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu-kvm.c')
-rw-r--r--qemu-kvm.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 1a0f6e04d..401c7e12c 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -124,6 +124,15 @@ static void get_seg(SegmentCache *lhs, const struct kvm_segment *rhs)
| (rhs->avl * DESC_AVL_MASK);
}
+/* the reset values of qemu are not compatible to SVM
+ * this function is used to fix the segment descriptor values */
+static void fix_realmode_dataseg(struct kvm_segment *seg)
+{
+ seg->type = 0x02;
+ seg->present = 1;
+ seg->s = 1;
+}
+
static void load_regs(CPUState *env)
{
struct kvm_regs regs;
@@ -182,6 +191,14 @@ static void load_regs(CPUState *env)
(sregs.cs.selector & 3);
sregs.ss.dpl = sregs.ss.selector & 3;
}
+
+ if (!(env->cr[0] & CR0_PG_MASK)) {
+ fix_realmode_dataseg(&sregs.ds);
+ fix_realmode_dataseg(&sregs.es);
+ fix_realmode_dataseg(&sregs.fs);
+ fix_realmode_dataseg(&sregs.gs);
+ fix_realmode_dataseg(&sregs.ss);
+ }
}
set_seg(&sregs.tr, &env->tr);
@@ -408,6 +425,7 @@ void kvm_save_registers(CPUState *env)
int kvm_cpu_exec(CPUState *env)
{
+ int r;
int pending = (!env->ready_for_interrupt_injection ||
((env->interrupt_request & CPU_INTERRUPT_HARD) &&
(env->eflags & IF_MASK)));
@@ -422,7 +440,11 @@ int kvm_cpu_exec(CPUState *env)
if (!saved_env[0])
saved_env[0] = env;
- kvm_run(kvm_context, 0);
+ r = kvm_run(kvm_context, 0);
+ if (r < 0) {
+ printf("kvm_run returned %d\n", r);
+ exit(1);
+ }
return 0;
}
@@ -587,6 +609,12 @@ static int kvm_halt(void *opaque, int vcpu)
return 1;
}
+
+static int kvm_shutdown(void *opaque, int vcpu)
+{
+ qemu_system_reset_request();
+ return 1;
+}
static struct kvm_callbacks qemu_kvm_ops = {
.cpuid = kvm_cpuid,
@@ -606,6 +634,7 @@ static struct kvm_callbacks qemu_kvm_ops = {
.writel = kvm_writel,
.writeq = kvm_writeq,
.halt = kvm_halt,
+ .shutdown = kvm_shutdown,
.io_window = kvm_io_window,
.try_push_interrupts = try_push_interrupts,
.post_kvm_run = post_kvm_run,