From: Anthony Liguori <aliguori-NZpS4cJIG2HvQtjrzfazuQ@public.gmane.org>
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Subject: [PATCH] Support 32bit SVM host
Date: Fri, 08 Dec 2006 14:34:08 -0600 [thread overview]
Message-ID: <4579CC40.5080601@cs.utexas.edu> (raw)
[-- 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
next reply other threads:[~2006-12-08 20:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-08 20:34 Anthony Liguori [this message]
[not found] ` <4579CC40.5080601-NZpS4cJIG2HvQtjrzfazuQ@public.gmane.org>
2006-12-09 7:15 ` [PATCH] Support 32bit SVM host Avi Kivity
[not found] ` <457A62A3.9000708-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-12-09 16:24 ` Anthony Liguori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4579CC40.5080601@cs.utexas.edu \
--to=aliguori-nzps4cjig2hvqtjrzfazuq@public.gmane.org \
--cc=avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.