From mboxrd@z Thu Jan 1 00:00:00 1970 From: Anthony Liguori Subject: [PATCH] Support 32bit SVM host Date: Fri, 08 Dec 2006 14:34:08 -0600 Message-ID: <4579CC40.5080601@cs.utexas.edu> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------060007060300090702010403" Return-path: To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org, Avi Kivity 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 This is a multi-part message in MIME format. --------------060007060300090702010403 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Howdy, This is a pretty basic patch to enable KVM on 32bit SVM capable hosts. It introduces a bit of ugliness with #ifdefs and redefining some things that are only present in the 64bit Linux headers. I've tested it only on an Ubuntu Edgy host (2.6.17) and with a Windows 2000 guest. It boots quite happily though. Regards, Anthony Liguori Signed-off-by: Anthony Liguori --------------060007060300090702010403 Content-Type: text/x-patch; name="svm-32bit.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="svm-32bit.diff" diff -r c70bb2219917 kernel/Kbuild --- a/kernel/Kbuild Fri Dec 08 11:55:31 2006 -0600 +++ b/kernel/Kbuild Fri Dec 08 14:02:33 2006 -0600 @@ -1,6 +1,5 @@ EXTRA_CFLAGS := -I$(src)/include EXTRA_CFLAGS := -I$(src)/include -obj-64-$(CONFIG_X86_64) := kvm-amd.o -obj-m := kvm.o kvm-intel.o $(obj-64-y) +obj-m := kvm.o kvm-intel.o kvm-amd.o kvm-objs := kvm_main.o mmu.o x86_emulate.o debug.o kvm-intel-objs := vmx.o kvm-amd-objs := svm.o diff -r c70bb2219917 kernel/kvm_svm.h --- a/kernel/kvm_svm.h Fri Dec 08 11:55:31 2006 -0600 +++ b/kernel/kvm_svm.h Fri Dec 08 13:39:40 2006 -0600 @@ -9,11 +9,13 @@ #include "kvm.h" static const u32 host_save_msrs[] = { +#ifdef __x86_64__ MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE, + MSR_FS_BASE, MSR_GS_BASE, +#endif MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, MSR_IA32_DEBUGCTLMSR, /*MSR_IA32_LASTBRANCHFROMIP, MSR_IA32_LASTBRANCHTOIP, MSR_IA32_LASTINTFROMIP,MSR_IA32_LASTINTTOIP,*/ - MSR_FS_BASE, MSR_GS_BASE, }; #define NR_HOST_SAVE_MSRS (sizeof(host_save_msrs) / sizeof(*host_save_msrs)) diff -r c70bb2219917 kernel/svm.c --- a/kernel/svm.c Fri Dec 08 11:55:31 2006 -0600 +++ b/kernel/svm.c Fri Dec 08 14:27:28 2006 -0600 @@ -39,8 +39,20 @@ MODULE_LICENSE("GPL"); #define SEG_TYPE_LDT 2 #define SEG_TYPE_BUSY_TSS16 3 +#define KVM_EFER_LMA (1 << 10) +#define KVM_EFER_LME (1 << 8) + unsigned long iopm_base; unsigned long msrpm_base; + +struct kvm_ldttss_desc { + u16 limit0; + u16 base0; + unsigned base1 : 8, type : 5, dpl : 2, p : 1; + unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; + u32 base3; + u32 zero1; +} __attribute__((packed)); struct svm_cpu_data { int cpu; @@ -48,7 +60,7 @@ struct svm_cpu_data { uint64_t asid_generation; uint32_t max_asid; uint32_t next_asid; - struct ldttss_desc *tss_desc; + struct kvm_ldttss_desc *tss_desc; struct page *save_area; }; @@ -156,7 +168,7 @@ static inline void write_dr7(unsigned lo static inline int svm_is_long_mode(struct kvm_vcpu *vcpu) { - return vcpu->svm->vmcb->save.efer & EFER_LMA; + return vcpu->svm->vmcb->save.efer & KVM_EFER_LMA; } static inline void force_new_asid(struct kvm_vcpu *vcpu) @@ -171,8 +183,8 @@ static inline void flush_guest_tlb(struc static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) { - if (!(efer & EFER_LMA)) - efer &= ~EFER_LME; + if (!(efer & KVM_EFER_LMA)) + efer &= ~KVM_EFER_LME; vcpu->svm->vmcb->save.efer = efer | MSR_EFER_SVME_MASK; vcpu->shadow_efer = efer; @@ -275,7 +287,11 @@ static void svm_hardware_enable(void *ga struct svm_cpu_data *svm_data; uint64_t efer; +#ifdef __x86_64__ struct desc_ptr gdt_descr; +#else + struct Xgt_desc_struct gdt_descr; +#endif struct desc_struct *gdt; int me = raw_smp_processor_id(); @@ -297,7 +313,7 @@ static void svm_hardware_enable(void *ga asm volatile ( "sgdt %0" : "=m"(gdt_descr) ); gdt = (struct desc_struct *)gdt_descr.address; - svm_data->tss_desc = (struct ldttss_desc *)(gdt + GDT_ENTRY_TSS); + svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); rdmsrl(MSR_EFER, efer); wrmsrl(MSR_EFER, efer | MSR_EFER_SVME_MASK); @@ -381,6 +397,7 @@ static __init int svm_hardware_setup(voi memset(msrpm_va, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER)); msrpm_base = page_to_pfn(msrpm_pages) << PAGE_SHIFT; +#ifdef __x86_64__ set_msr_interception(msrpm_va, MSR_GS_BASE, 1, 1); set_msr_interception(msrpm_va, MSR_FS_BASE, 1, 1); set_msr_interception(msrpm_va, MSR_KERNEL_GS_BASE, 1, 1); @@ -388,6 +405,7 @@ static __init int svm_hardware_setup(voi set_msr_interception(msrpm_va, MSR_LSTAR, 1, 1); set_msr_interception(msrpm_va, MSR_CSTAR, 1, 1); set_msr_interception(msrpm_va, MSR_SYSCALL_MASK, 1, 1); +#endif set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_CS, 1, 1); set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_ESP, 1, 1); set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_EIP, 1, 1); @@ -687,15 +705,15 @@ static void svm_set_cr0(struct kvm_vcpu static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) { #ifdef __x86_64__ - if (vcpu->shadow_efer & EFER_LME) { + if (vcpu->shadow_efer & KVM_EFER_LME) { if (!is_paging(vcpu) && (cr0 & CR0_PG_MASK)) { - vcpu->shadow_efer |= EFER_LMA; - vcpu->svm->vmcb->save.efer |= EFER_LMA | EFER_LME; + vcpu->shadow_efer |= KVM_EFER_LMA; + vcpu->svm->vmcb->save.efer |= KVM_EFER_LMA | KVM_EFER_LME; } if (is_paging(vcpu) && !(cr0 & CR0_PG_MASK) ) { - vcpu->shadow_efer &= ~EFER_LMA; - vcpu->svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); + vcpu->shadow_efer &= ~KVM_EFER_LMA; + vcpu->svm->vmcb->save.efer &= ~(KVM_EFER_LMA | KVM_EFER_LME); } } #endif @@ -1079,6 +1097,7 @@ static int svm_get_msr(struct kvm_vcpu * case MSR_IA32_APICBASE: *data = vcpu->apic_base; break; +#ifdef __x86_64__ case MSR_STAR: *data = vcpu->svm->vmcb->save.star; break; @@ -1088,6 +1107,13 @@ static int svm_get_msr(struct kvm_vcpu * case MSR_CSTAR: *data = vcpu->svm->vmcb->save.cstar; break; + case MSR_KERNEL_GS_BASE: + *data = vcpu->svm->vmcb->save.kernel_gs_base; + break; + case MSR_SYSCALL_MASK: + *data = vcpu->svm->vmcb->save.sfmask; + break; +#endif case MSR_IA32_SYSENTER_CS: *data = vcpu->svm->vmcb->save.sysenter_cs; break; @@ -1096,12 +1122,6 @@ static int svm_get_msr(struct kvm_vcpu * break; case MSR_IA32_SYSENTER_ESP: *data = vcpu->svm->vmcb->save.sysenter_esp; - break; - case MSR_KERNEL_GS_BASE: - *data = vcpu->svm->vmcb->save.kernel_gs_base; - break; - case MSR_SYSCALL_MASK: - *data = vcpu->svm->vmcb->save.sfmask; break; default: printk(KERN_ERR "kvm: unhandled rdmsr: 0x%x\n", ecx); @@ -1152,6 +1172,7 @@ static int svm_set_msr(struct kvm_vcpu * case MSR_IA32_APICBASE: vcpu->apic_base = data; break; +#ifdef __x86_64___ case MSR_STAR: vcpu->svm->vmcb->save.star = data; break; @@ -1161,6 +1182,13 @@ static int svm_set_msr(struct kvm_vcpu * case MSR_CSTAR: vcpu->svm->vmcb->save.cstar = data; break; + case MSR_KERNEL_GS_BASE: + vcpu->svm->vmcb->save.kernel_gs_base = data; + break; + case MSR_SYSCALL_MASK: + vcpu->svm->vmcb->save.sfmask = data; + break; +#endif case MSR_IA32_SYSENTER_CS: vcpu->svm->vmcb->save.sysenter_cs = data; break; @@ -1169,12 +1197,6 @@ static int svm_set_msr(struct kvm_vcpu * break; case MSR_IA32_SYSENTER_ESP: vcpu->svm->vmcb->save.sysenter_esp = data; - break; - case MSR_KERNEL_GS_BASE: - vcpu->svm->vmcb->save.kernel_gs_base = data; - break; - case MSR_SYSCALL_MASK: - vcpu->svm->vmcb->save.sfmask = data; break; default: printk(KERN_ERR "kvm: unhandled wrmsr: %x\n", ecx); @@ -1323,6 +1345,7 @@ static void kvm_reput_irq(struct kvm_vcp static void save_db_regs(unsigned long *db_regs) { +#ifdef __x86_64__ asm ("mov %%dr0, %%rax \n\t" "mov %%rax, %[dr0] \n\t" "mov %%dr1, %%rax \n\t" @@ -1336,6 +1359,21 @@ static void save_db_regs(unsigned long * [dr2] "=m"(db_regs[2]), [dr3] "=m"(db_regs[3]) : : "rax"); +#else + asm ("mov %%dr0, %%eax \n\t" + "mov %%eax, %[dr0] \n\t" + "mov %%dr1, %%eax \n\t" + "mov %%eax, %[dr1] \n\t" + "mov %%dr2, %%eax \n\t" + "mov %%eax, %[dr2] \n\t" + "mov %%dr3, %%eax \n\t" + "mov %%eax, %[dr3] \n\t" + : [dr0] "=m"(db_regs[0]), + [dr1] "=m"(db_regs[1]), + [dr2] "=m"(db_regs[2]), + [dr3] "=m"(db_regs[3]) + : : "eax"); +#endif } static void load_db_regs(unsigned long *db_regs) @@ -1349,7 +1387,11 @@ static void load_db_regs(unsigned long * [dr1] "r"(db_regs[1]), [dr2] "r"(db_regs[2]), [dr3] "r"(db_regs[3]) +#ifdef __x86_64__ : "rax"); +#else + : "eax"); +#endif } static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) @@ -1414,6 +1456,7 @@ again: "mov %c[rbp](%[vcpu]), %%ebp \n\t" #endif +#ifdef __x86_64__ /* Enter guest mode */ "push %%rax \n\t" "mov %c[svm](%[vcpu]), %%rax \n\t" @@ -1422,6 +1465,16 @@ again: SVM_VMRUN "\n\t" SVM_VMSAVE "\n\t" "pop %%rax \n\t" +#else + /* Enter guest mode */ + "push %%eax \n\t" + "mov %c[svm](%[vcpu]), %%eax \n\t" + "mov %c[vmcb](%%eax), %%eax \n\t" + SVM_VMLOAD "\n\t" + SVM_VMRUN "\n\t" + SVM_VMSAVE "\n\t" + "pop %%eax \n\t" +#endif /* Save guest registers, load host registers */ #ifdef __x86_64__ @@ -1445,12 +1498,12 @@ again: "pop %%rbp; pop %%rdi; pop %%rsi;" "pop %%rdx; pop %%rcx; pop %%rbx; \n\t" #else - "mov %%ebx, %c[rbx](%3) \n\t" - "mov %%ecx, %c[rcx](%3) \n\t" - "mov %%edx, %c[rdx](%3) \n\t" - "mov %%esi, %c[rsi](%3) \n\t" - "mov %%edi, %c[rdi](%3) \n\t" - "mov %%ebp, %c[rbp](%3) \n\t" + "mov %%ebx, %c[rbx](%[vcpu]) \n\t" + "mov %%ecx, %c[rcx](%[vcpu]) \n\t" + "mov %%edx, %c[rdx](%[vcpu]) \n\t" + "mov %%esi, %c[rsi](%[vcpu]) \n\t" + "mov %%edi, %c[rdi](%[vcpu]) \n\t" + "mov %%ebp, %c[rbp](%[vcpu]) \n\t" "pop %%ebp; pop %%edi; pop %%esi;" "pop %%edx; pop %%ecx; pop %%ebx; \n\t" --------------060007060300090702010403 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV --------------060007060300090702010403 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 --------------060007060300090702010403--