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