From: Jack Lange Date: Thu, 26 May 2011 00:32:29 +0000 (-0500) Subject: updated SIPI behavior to be arch specific X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=ad78e7627af59b2ebbfebdd05b479a021174efe4 updated SIPI behavior to be arch specific --- diff --git a/palacios/include/palacios/svm.h b/palacios/include/palacios/svm.h index a0078ca..665b1c2 100644 --- a/palacios/include/palacios/svm.h +++ b/palacios/include/palacios/svm.h @@ -82,11 +82,16 @@ void v3_init_svm_cpu(int cpu_id); void v3_deinit_svm_cpu(int cpu_id); + int v3_init_svm_vmcb(struct guest_info * core, v3_vm_class_t vm_class); int v3_deinit_svm_vmcb(struct guest_info * core); int v3_svm_enter(struct guest_info * info); int v3_start_svm_guest(struct guest_info *info); +int v3_reset_svm_vm_core(struct guest_info * core, addr_t rip); + + + #endif diff --git a/palacios/include/palacios/vmm.h b/palacios/include/palacios/vmm.h index 71c9936..337226f 100644 --- a/palacios/include/palacios/vmm.h +++ b/palacios/include/palacios/vmm.h @@ -261,6 +261,7 @@ v3_cpu_arch_t v3_get_cpu_type(int cpu_id); int v3_vm_enter(struct guest_info * info); +int v3_reset_vm_core(struct guest_info * core, addr_t rip); #endif /*!__V3VEE__ */ diff --git a/palacios/include/palacios/vmx.h b/palacios/include/palacios/vmx.h index f008a4b..acadf22 100644 --- a/palacios/include/palacios/vmx.h +++ b/palacios/include/palacios/vmx.h @@ -219,6 +219,7 @@ void v3_init_vmx_cpu(int cpu_id); void v3_deinit_vmx_cpu(int cpu_id); int v3_start_vmx_guest(struct guest_info* info); +int v3_reset_vmx_vm_core(struct guest_info * core, addr_t rip); int v3_vmx_enter(struct guest_info * info); int v3_init_vmx_vmcs(struct guest_info * info, v3_vm_class_t vm_class); diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index 9bf7438..b2b7969 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -740,20 +740,7 @@ static int deliver_ipi(struct apic_state * src_apic, break; } - // Write the RIP, CS, and descriptor - // assume the rest is already good to go - // - // vector VV -> rip at 0 - // CS = VV00 - // This means we start executing at linear address VV000 - // - // So the selector needs to be VV00 - // and the base needs to be VV000 - // - dst_core->rip = 0; - dst_core->segments.cs.selector = vector << 8; - dst_core->segments.cs.limit = 0xffff; - dst_core->segments.cs.base = vector << 12; + v3_reset_vm_core(dst_core, vector); PrintDebug(" SIPI delivery (0x%x -> 0x%x:0x0) to core %u\n", vector, dst_core->segments.cs.selector, dst_core->vcpu_id); @@ -769,10 +756,18 @@ static int deliver_ipi(struct apic_state * src_apic, break; } + + case APIC_EXTINT_DELIVERY: // EXTINT + /* Two possible things to do here: + * 1. Ignore the IPI and assume the 8259a (PIC) will handle it + * 2. Add 32 to the vector and inject it... + * We probably just want to do 1 here, and assume the raise_irq() will hit the 8259a. + */ + return 0; + case APIC_SMI_DELIVERY: case APIC_RES1_DELIVERY: // reserved case APIC_NMI_DELIVERY: - case APIC_EXTINT_DELIVERY: // ExtInt default: PrintError("IPI %d delivery is unsupported\n", del_mode); return -1; diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index 4b5b0a9..dffbdb8 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -1,3 +1,4 @@ + /* * This file is part of the Palacios Virtual Machine Monitor developed * by the V3VEE Project with funding from the United States National @@ -668,11 +669,12 @@ int v3_start_svm_guest(struct guest_info * info) { - if ((info->num_exits % 5000) == 0) { +/* + if ((info->num_exits % 50000) == 0) { V3_Print("SVM Exit number %d\n", (uint32_t)info->num_exits); v3_print_guest_state(info); } - +*/ } @@ -684,6 +686,31 @@ int v3_start_svm_guest(struct guest_info * info) { +int v3_reset_svm_vm_core(struct guest_info * core, addr_t rip) { + // init vmcb_bios + + // Write the RIP, CS, and descriptor + // assume the rest is already good to go + // + // vector VV -> rip at 0 + // CS = VV00 + // This means we start executing at linear address VV000 + // + // So the selector needs to be VV00 + // and the base needs to be VV000 + // + core->rip = 0; + core->segments.cs.selector = rip << 8; + core->segments.cs.limit = 0xffff; + core->segments.cs.base = rip << 12; + + return 0; +} + + + + + /* Checks machine SVM capability */ /* Implemented from: AMD Arch Manual 3, sect 15.4 */ @@ -748,6 +775,7 @@ static int has_svm_nested_paging() { } + void v3_init_svm_cpu(int cpu_id) { reg_ex_t msr; extern v3_cpu_arch_t v3_cpu_types[]; diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index abdeeb6..d60e55a 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -40,6 +40,7 @@ int v3_dbg_enable = 0; + static void init_cpu(void * arg) { uint32_t cpu_id = (uint32_t)(addr_t)arg; @@ -192,6 +193,8 @@ struct v3_vm_info * v3_create_vm(void * cfg, void * priv_data, char * name) { } + + static int start_core(void * p) { struct guest_info * core = (struct guest_info *)p; @@ -343,6 +346,33 @@ int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) { } +int v3_reset_vm_core(struct guest_info * core, addr_t rip) { + + switch (v3_cpu_types[core->pcpu_id]) { +#ifdef V3_CONFIG_SVM + case V3_SVM_CPU: + case V3_SVM_REV3_CPU: + PrintDebug("Resetting SVM Guest CPU %d\n", core->vcpu_id); + return v3_reset_svm_vm_core(core, rip); +#endif +#ifdef V3_CONFIG_VMX + case V3_VMX_CPU: + case V3_VMX_EPT_CPU: + case V3_VMX_EPT_UG_CPU: + PrintDebug("Resetting VMX Guest CPU %d\n", core->vcpu_id); + return v3_reset_vmx_vm_core(core, rip); +#endif + case V3_INVALID_CPU: + default: + PrintError("CPU has no virtualization Extensions\n"); + break; + } + + return -1; +} + + + int v3_stop_vm(struct v3_vm_info * vm) { diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 123e23b..5aec9d5 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -970,7 +970,23 @@ int v3_is_vmx_capable() { } +int v3_reset_vmx_cpu(struct guest_info * core, addr_t rip) { + // init vmcs bios + + if ((core->shdw_pg_mode == NESTED_PAGING) && + (v3_cpu_types[core->pcpu_id] == V3_VMX_EPT_UG_CPU)) { + // easy + core->rip = 0; + core->segments.cs.selector = rip << 8; + core->segments.cs.limit = 0xffff; + core->segments.cs.base = rip << 12; + } else { + core->vm_regs.rdx = core->vcpu_id; + core->vm_regs.rbx = rip; + } + return 0; +}