# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Node ID f8ffeb540ec168ac3461e3572ba2244cf53d23db
# Parent bb6cd7ba259b7552e2f46f986c1580350af10517
[HVM][SVM] Start moving SVM launch code to domain/vcpu initialisation.
This first patch is just enough to get SVM guests working again after
I broke SVM support earlier today.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/hvm/svm/svm.c | 9 ++
xen/arch/x86/hvm/svm/vmcb.c | 135 +++++++++++++++-----------------------------
2 files changed, 58 insertions(+), 86 deletions(-)
diff -r bb6cd7ba259b -r f8ffeb540ec1 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Mon Nov 06 17:32:00 2006 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c Mon Nov 06 18:57:33 2006 +0000
@@ -773,6 +773,15 @@ static int svm_vcpu_initialise(struct vc
v->arch.schedule_tail = arch_svm_do_launch;
v->arch.ctxt_switch_from = svm_ctxt_switch_from;
v->arch.ctxt_switch_to = svm_ctxt_switch_to;
+
+ if ( (v->arch.hvm_svm.vmcb = alloc_vmcb()) == NULL )
+ {
+ printk("Failed to create a new VMCB\n");
+ return -ENOMEM;
+ }
+
+ v->arch.hvm_svm.vmcb_pa = virt_to_maddr(v->arch.hvm_svm.vmcb);
+
return 0;
}
diff -r bb6cd7ba259b -r f8ffeb540ec1 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Mon Nov 06 17:32:00 2006 +0000
+++ b/xen/arch/x86/hvm/svm/vmcb.c Mon Nov 06 18:57:33 2006 +0000
@@ -38,71 +38,59 @@
#include <xen/keyhandler.h>
extern int svm_dbg_on;
-extern int asidpool_assign_next( struct vmcb_struct *vmcb, int retire_current,
- int oldcore, int newcore);
+extern int asidpool_assign_next(
+ struct vmcb_struct *vmcb, int retire_current, int oldcore, int newcore);
#define GUEST_SEGMENT_LIMIT 0xffffffff
#define IOPM_SIZE (12 * 1024)
#define MSRPM_SIZE (8 * 1024)
-/* VMCBs and HSAs are architecturally defined to be a 4K page each */
-#define VMCB_ORDER 0
-#define HSA_ORDER 0
-
-
struct vmcb_struct *alloc_vmcb(void)
{
- struct vmcb_struct *vmcb = alloc_xenheap_pages(VMCB_ORDER);
-
- if (!vmcb) {
- printk("Warning: failed to allocate vmcb.\n");
+ struct vmcb_struct *vmcb;
+
+ vmcb = alloc_xenheap_page();
+ if ( vmcb == NULL )
+ {
+ printk(XENLOG_WARNING "Warning: failed to allocate vmcb.\n");
return NULL;
}
- memset(vmcb, 0, (PAGE_SIZE << VMCB_ORDER));
+ memset(vmcb, 0, PAGE_SIZE);
return vmcb;
}
-
void free_vmcb(struct vmcb_struct *vmcb)
{
- ASSERT(vmcb);
- free_xenheap_pages(vmcb, VMCB_ORDER);
-}
-
+ free_xenheap_page(vmcb);
+}
struct host_save_area *alloc_host_save_area(void)
{
- struct host_save_area *hsa = alloc_xenheap_pages(HSA_ORDER);
-
- if (!hsa) {
- printk("Warning: failed to allocate vmcb.\n");
+ struct host_save_area *hsa;
+
+ hsa = alloc_xenheap_page();
+ if ( hsa == NULL )
+ {
+ printk(XENLOG_WARNING "Warning: failed to allocate vmcb.\n");
return NULL;
}
- memset(hsa, 0, (PAGE_SIZE << HSA_ORDER));
+ memset(hsa, 0, PAGE_SIZE);
return hsa;
}
-
void free_host_save_area(struct host_save_area *hsa)
{
- ASSERT(hsa);
- free_xenheap_pages(hsa, HSA_ORDER);
-}
-
+ free_xenheap_page(hsa);
+}
/* Set up intercepts to exit the guest into the hypervisor when we want it. */
static int construct_vmcb_controls(struct arch_svm_struct *arch_svm)
{
- struct vmcb_struct *vmcb;
- u32 *iopm;
- u32 *msrpm;
-
- vmcb = arch_svm->vmcb;
-
- ASSERT(vmcb);
+ struct vmcb_struct *vmcb = arch_svm->vmcb;
+ u32 *iopm, *msrpm;
/* mask off all general 1 intercepts except those listed here */
vmcb->general1_intercepts =
@@ -128,19 +116,19 @@ static int construct_vmcb_controls(struc
/* The following is for I/O and MSR permision map */
iopm = alloc_xenheap_pages(get_order_from_bytes(IOPM_SIZE));
- if (iopm)
+ if ( iopm != NULL )
{
memset(iopm, 0xff, IOPM_SIZE);
clear_bit(PC_DEBUG_PORT, iopm);
}
msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE));
- if (msrpm)
+ if ( msrpm != NULL )
memset(msrpm, 0xff, MSRPM_SIZE);
arch_svm->iopm = iopm;
arch_svm->msrpm = msrpm;
- if (! iopm || ! msrpm)
+ if ( !iopm || !msrpm )
return 1;
vmcb->iopm_base_pa = (u64) virt_to_maddr(iopm);
@@ -261,78 +249,53 @@ static int construct_init_vmcb_guest(str
return error;
}
-
-/*
- * destroy the vmcb.
- */
-
void destroy_vmcb(struct arch_svm_struct *arch_svm)
{
- if(arch_svm->vmcb != NULL)
+ if ( arch_svm->vmcb != NULL )
{
asidpool_retire(arch_svm->vmcb, arch_svm->asid_core);
- free_vmcb(arch_svm->vmcb);
- }
- if(arch_svm->iopm != NULL) {
+ free_vmcb(arch_svm->vmcb);
+ }
+
+ if ( arch_svm->iopm != NULL )
+ {
free_xenheap_pages(
arch_svm->iopm, get_order_from_bytes(IOPM_SIZE));
arch_svm->iopm = NULL;
}
- if(arch_svm->msrpm != NULL) {
+
+ if ( arch_svm->msrpm != NULL )
+ {
free_xenheap_pages(
arch_svm->msrpm, get_order_from_bytes(MSRPM_SIZE));
arch_svm->msrpm = NULL;
}
+
arch_svm->vmcb = NULL;
}
-
-
-/*
- * construct the vmcb.
- */
int construct_vmcb(struct arch_svm_struct *arch_svm,
struct cpu_user_regs *regs)
{
- int error;
- long rc=0;
-
- memset(arch_svm, 0, sizeof(struct arch_svm_struct));
-
- if (!(arch_svm->vmcb = alloc_vmcb())) {
- printk("Failed to create a new VMCB\n");
- rc = -ENOMEM;
- goto err_out;
- }
-
- arch_svm->vmcb_pa = (u64) virt_to_maddr(arch_svm->vmcb);
-
- if ((error = construct_vmcb_controls(arch_svm)))
+ if ( construct_vmcb_controls(arch_svm) != 0 )
{
printk("construct_vmcb: construct_vmcb_controls failed\n");
- rc = -EINVAL;
- goto err_out;
- }
-
- /* guest selectors */
- if ((error = construct_init_vmcb_guest(arch_svm, regs)))
+ return -EINVAL;
+ }
+
+ if ( construct_init_vmcb_guest(arch_svm, regs) != 0 )
{
printk("construct_vmcb: construct_vmcb_guest failed\n");
- rc = -EINVAL;
- goto err_out;
+ return -EINVAL;
}
arch_svm->vmcb->exception_intercepts = MONITOR_DEFAULT_EXCEPTION_BITMAP;
- if (regs->eflags & EF_TF)
+ if ( regs->eflags & EF_TF )
arch_svm->vmcb->exception_intercepts |= EXCEPTION_BITMAP_DB;
else
arch_svm->vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_DB;
return 0;
-
-err_out:
- destroy_vmcb(arch_svm);
- return rc;
}
@@ -340,7 +303,6 @@ void svm_do_launch(struct vcpu *v)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
int core = smp_processor_id();
- ASSERT(vmcb);
/* Update CR3, GDT, LDT, TR */
hvm_stts(v);
@@ -348,7 +310,7 @@ void svm_do_launch(struct vcpu *v)
/* current core is the one we intend to perform the VMRUN on */
v->arch.hvm_svm.launch_core = v->arch.hvm_svm.asid_core = core;
clear_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
- if ( !asidpool_assign_next( vmcb, 0, core, core ))
+ if ( !asidpool_assign_next(vmcb, 0, core, core) )
BUG();
vmcb->ldtr.sel = 0;
@@ -358,7 +320,7 @@ void svm_do_launch(struct vcpu *v)
vmcb->efer = EFER_SVME; /* Make sure VMRUN won't return with -1 */
- if (svm_dbg_on)
+ if ( svm_dbg_on )
{
unsigned long pt;
printk("%s: hw_cr3 = %llx\n", __func__,
@@ -372,13 +334,14 @@ void svm_do_launch(struct vcpu *v)
/* Set cr3 from hw_cr3 even when guest-visible paging is not enabled */
vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
- if (svm_dbg_on)
+ if ( svm_dbg_on )
{
printk("%s: cr3 = %lx ", __func__, (unsigned long)vmcb->cr3);
- printk("init_guest_table: guest_table = 0x%08x, monitor_table =
0x%08x,"
- " hw_cr3 = 0x%16llx\n", (int)v->arch.guest_table.pfn,
+ printk("init_guest_table: guest_table = 0x%08x, "
+ "monitor_table = 0x%08x, hw_cr3 = 0x%16llx\n",
+ (int)v->arch.guest_table.pfn,
(int)v->arch.monitor_table.pfn,
- (unsigned long long) v->arch.hvm_vcpu.hw_cr3);
+ (unsigned long long)v->arch.hvm_vcpu.hw_cr3);
}
v->arch.schedule_tail = arch_svm_do_resume;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|