public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Support 32bit SVM host
@ 2006-12-08 20:34 Anthony Liguori
       [not found] ` <4579CC40.5080601-NZpS4cJIG2HvQtjrzfazuQ@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Anthony Liguori @ 2006-12-08 20:34 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Avi Kivity

[-- Attachment #1: Type: text/plain, Size: 429 bytes --]

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 <anthony-rdkfGonbjUSkNkDKm+mE6A@public.gmane.org>

[-- Attachment #2: svm-32bit.diff --]
[-- Type: text/x-patch, Size: 9024 bytes --]

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"

[-- Attachment #3: Type: text/plain, Size: 347 bytes --]

-------------------------------------------------------------------------
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

[-- Attachment #4: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Support 32bit SVM host
       [not found] ` <4579CC40.5080601-NZpS4cJIG2HvQtjrzfazuQ@public.gmane.org>
@ 2006-12-09  7:15   ` Avi Kivity
       [not found]     ` <457A62A3.9000708-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Avi Kivity @ 2006-12-09  7:15 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Anthony Liguori wrote:
> 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.

The way to avoid the ugliness is to send a separate patch to Andi that 
extracts the common definition into a new header file includable from 
both archs (see [1]).


> I've tested it only on an Ubuntu Edgy host (2.6.17) and with a Windows 
> 2000 guest.  It boots quite happily though.
>

Will merge asap.  Thanks for the good work.


[1] 
http://kernel.org/git/gitweb.cgi?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=249e83fe839a13b5dc94285daeeaf70f6e54d930

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Support 32bit SVM host
       [not found]     ` <457A62A3.9000708-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
@ 2006-12-09 16:24       ` Anthony Liguori
  0 siblings, 0 replies; 3+ messages in thread
From: Anthony Liguori @ 2006-12-09 16:24 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Avi Kivity wrote:
> Anthony Liguori wrote:
>> 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.
>
> The way to avoid the ugliness is to send a separate patch to Andi that 
> extracts the common definition into a new header file includable from 
> both archs (see [1]).

Very nice :-)

Regards,

Anthony Liguori

>
>> I've tested it only on an Ubuntu Edgy host (2.6.17) and with a 
>> Windows 2000 guest.  It boots quite happily though.
>>
>
> Will merge asap.  Thanks for the good work.
>
>
> [1] 
> http://kernel.org/git/gitweb.cgi?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=249e83fe839a13b5dc94285daeeaf70f6e54d930 
>
>


-------------------------------------------------------------------------
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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-12-09 16:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-08 20:34 [PATCH] Support 32bit SVM host Anthony Liguori
     [not found] ` <4579CC40.5080601-NZpS4cJIG2HvQtjrzfazuQ@public.gmane.org>
2006-12-09  7:15   ` Avi Kivity
     [not found]     ` <457A62A3.9000708-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-12-09 16:24       ` Anthony Liguori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox