From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Joerg Roedel" Subject: Re: [PATCH try #2] kvm-12 userland guest reboot fix Date: Thu, 1 Feb 2007 17:39:43 +0100 Message-ID: <20070201163943.GB7115@amd.com> References: <20070131165830.GB8491@amd.com> <45C1A3F1.1070803@qumranet.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=X1bOJ3K7DJ5YkBrT Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org To: "Avi Kivity" Return-path: In-Reply-To: <45C1A3F1.1070803-atKUWr5tajBWk0Htik3J/w@public.gmane.org> Content-Disposition: inline List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Errors-To: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: kvm.vger.kernel.org --X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: 7bit On Thu, Feb 01, 2007 at 10:25:21AM +0200, Avi Kivity wrote: > Joerg Roedel wrote: > >From: Markus Rechberger > >From: Joerg Roedel > > > >This patch fixes the initialization of the segment registers which > >solves the triple fault and keyboard controller reset problems in > >kvm/qemu guests as well as the slow grub menu interaction. The patch > >should also work on Intel VMX now. > > diff -upr kvm-12/qemu/target-i386/helper2.c > >kvm-12-reboot-fixed/qemu/target-i386/helper2.c > >--- kvm-12/qemu/target-i386/helper2.c 2006-12-31 14:31:38.000000000 +0100 > >+++ kvm-12-reboot-fixed/qemu/target-i386/helper2.c 2007-01-23 20:24:42.265987000 +0100 > >@@ -151,6 +151,9 @@ CPUX86State *cpu_x86_init(void) > > void cpu_reset(CPUX86State *env) > > { > > int i; > >+ unsigned int flags = DESC_P_MASK | > >+ DESC_S_MASK | > >+ (2 << DESC_TYPE_SHIFT); > > memset(env, 0, offsetof(CPUX86State, breakpoints)); > > @@ -173,9 +176,9 @@ void cpu_reset(CPUX86State *env) > > env->tr.flags = DESC_P_MASK; > > cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, 0); - > >cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, 0); > >- cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, 0); > >- cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, 0); > >+ cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, flags); > >+ cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, flags); > >+ cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, flags); > > cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, 0); > > cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, 0); > > > > This changes core qemu code, which may make merging our code back to qemu more difficult. > It also means we need to test with -no-kvm. > > Can you try making load_regs() in qemu-kvm.c detect the case of flags == 0 (perhaps only if > cr0.pg == 0) and changing it only then? It should have the same effect. I tested the patch with -no-kvm too (with Linux guest) and it worked without problems. In my opinion it is cleaner to do it cpu_reset but YMMV. Anyway, here is a patch that implements this fixup in load_regs. You can choice which patch to apply :) Joerg -- Joerg Roedel Operating System Research Center AMD Saxony LLC & Co. KG --X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=kvm-12-reboot-fix3.patch Content-Transfer-Encoding: 7bit diff -upr kvm-12/kernel/vmx.c kvm-12-reboot-fixed/kernel/vmx.c --- kvm-12/kernel/vmx.c 2007-01-23 11:40:46.000000000 +0100 +++ kvm-12-reboot-fixed/kernel/vmx.c 2007-01-29 15:09:02.620662000 +0100 @@ -781,6 +781,9 @@ static void vmx_set_cr0(struct kvm_vcpu */ static void vmx_set_cr0_no_modeswitch(struct kvm_vcpu *vcpu, unsigned long cr0) { + if (!vcpu->rmode.active && !(cr0 & CR0_PE_MASK)) + enter_rmode(vcpu); + vcpu->rmode.active = ((cr0 & CR0_PE_MASK) == 0); update_exception_bitmap(vcpu); vmcs_writel(CR0_READ_SHADOW, cr0); diff -upr kvm-12/qemu/qemu-kvm.c kvm-12-reboot-fixed/qemu/qemu-kvm.c --- kvm-12/qemu/qemu-kvm.c 2007-01-23 11:40:46.000000000 +0100 +++ kvm-12-reboot-fixed/qemu/qemu-kvm.c 2007-02-01 17:22:17.511590000 +0100 @@ -124,6 +124,15 @@ static void get_seg(SegmentCache *lhs, c | (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,12 @@ 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.ss); + } } set_seg(&sregs.tr, &env->tr); @@ -582,6 +597,12 @@ static int kvm_halt(void *opaque, int vc 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, @@ -601,6 +622,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, diff -upr kvm-12/qemu/vl.c kvm-12-reboot-fixed/qemu/vl.c --- kvm-12/qemu/vl.c 2007-01-07 13:58:54.000000000 +0100 +++ kvm-12-reboot-fixed/qemu/vl.c 2007-01-23 20:11:53.772182000 +0100 @@ -5281,6 +5281,10 @@ int main_loop(void) if (reset_requested) { reset_requested = 0; qemu_system_reset(); +#ifdef USE_KVM + if (kvm_allowed) + kvm_load_registers(env); +#endif ret = EXCP_INTERRUPT; } if (powerdown_requested) { diff -upr kvm-12/user/kvmctl.c kvm-12-reboot-fixed/user/kvmctl.c --- kvm-12/user/kvmctl.c 2006-12-31 14:31:38.000000000 +0100 +++ kvm-12-reboot-fixed/user/kvmctl.c 2007-01-23 19:48:18.111267000 +0100 @@ -522,6 +522,11 @@ static int handle_halt(kvm_context_t kvm return kvm->callbacks->halt(kvm->opaque, kvm_run->vcpu); } +static int handle_shutdown(kvm_context_t kvm, struct kvm_run *kvm_run) +{ + return kvm->callbacks->shutdown(kvm->opaque, kvm_run->vcpu); +} + int try_push_interrupts(kvm_context_t kvm) { return kvm->callbacks->try_push_interrupts(kvm->opaque); @@ -594,6 +599,9 @@ again: break; case KVM_EXIT_IRQ_WINDOW_OPEN: break; + case KVM_EXIT_SHUTDOWN: + r = handle_shutdown(kvm, &kvm_run); + break; default: fprintf(stderr, "unhandled vm exit: 0x%x\n", kvm_run.exit_reason); kvm_show_regs(kvm, vcpu); diff -upr kvm-12/user/kvmctl.h kvm-12-reboot-fixed/user/kvmctl.h --- kvm-12/user/kvmctl.h 2006-12-31 14:31:38.000000000 +0100 +++ kvm-12-reboot-fixed/user/kvmctl.h 2007-01-23 18:25:32.758594000 +0100 @@ -59,6 +59,7 @@ struct kvm_callbacks { * on the host CPU. */ int (*halt)(void *opaque, int vcpu); + int (*shutdown)(void *opaque, int vcpu); int (*io_window)(void *opaque); int (*try_push_interrupts)(void *opaque); void (*post_kvm_run)(void *opaque, struct kvm_run *kvm_run); --X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier. Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 --X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kvm-devel mailing list kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/kvm-devel --X1bOJ3K7DJ5YkBrT--