github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/vmexit/vmexit_sipi.c (about) 1 /* 2 * Copyright (c) 2013 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 #include "vmm_defs.h" 16 #include "hw_utils.h" 17 #include "vmcs_api.h" 18 #include "guest_cpu.h" 19 #include "ipc.h" 20 #include "vmm_events_data.h" 21 #include "vmx_trace.h" 22 #include "pat_manager.h" 23 #include "hw_interlocked.h" 24 #ifdef JLMDEBUG 25 #include "jlmdebug.h" 26 #endif 27 28 UINT32 g_guest_num_of_cpus=1; //BSP Core 29 extern UINT32 g_s3_resume_flag; 30 31 32 // FUNCTION : vmexit_sipi_event() 33 // PURPOSE : Configure VMCS register-state with CPU Real Mode state. 34 // : and launch emulator. 35 // ARGUMENTS: GUEST_CPU_HANDLE gcpu 36 // RETURNS : void 37 // NOTE : The hard-coded values used for VMCS-registers initialization 38 // : are the values CPU sets its registers with after RESET. 39 // : See Intel® 64 and IA-32 Architectures Software Developer’s Manual 40 // : Volume 3A: System Programming Guide, Part 1 41 // : Table 9-1. IA-32 Processor States Following Power-up, Reset, or INIT 42 VMEXIT_HANDLING_STATUS vmexit_sipi_event(GUEST_CPU_HANDLE gcpu) 43 { 44 VMCS_OBJECT *vmcs = gcpu_get_vmcs(gcpu); 45 IA32_VMX_EXIT_QUALIFICATION qualification; 46 UINT16 real_mode_segment; 47 VMEXIT_HANDLING_STATUS ret_status = VMEXIT_NOT_HANDLED; 48 49 #ifdef JLMDEBUG1 50 bprint("vmexit_sipi_event(%p)\n", gcpu); 51 #endif 52 do { // single-execution loop 53 // Check if this is IPC SIPI signal. 54 if (ipc_sipi_vmexit_handler(gcpu)) { 55 // We're already in Wait for SIPI state. Nothing to do 56 ret_status = VMEXIT_HANDLED; 57 break; 58 } 59 60 #ifdef SIPI_LAYERED_IS_SUPPORTED 61 if (gcpu_is_vmcs_layered(gcpu)) { 62 break; // level-1 must handle 63 } 64 #endif 65 // AP currently is in Wait for SIPI state, 66 // gets guest SIPI(vector not 0xff) and activates the AP 67 #ifdef ENABLE_PM_S3 68 if (g_s3_resume_flag==0) { 69 #else 70 { 71 #endif 72 // No S3 resume, count guest AP cores 73 hw_interlocked_increment((INT32*)&(g_guest_num_of_cpus)); 74 } 75 76 VMM_LOG(mask_anonymous, level_trace, 77 "CPU-%d Leave SIPI State: Guest Core Count is %d.\n", hw_cpu_id(), 78 g_guest_num_of_cpus); 79 VMM_DEBUG_CODE(vmm_trace(gcpu, "[sipi] Leave SIPI State\n")); 80 #ifdef JLMDEBUG1 81 bprint("%D guest cpus\n", g_guest_num_of_cpus); 82 #endif 83 84 // emulator configures guest with host state, and setup emulator 85 // context to real mode, 86 // thus we have to configure the guest with the values of Real Mode, i.e. 87 // those values, CPU sets to registers after RESET, 88 // though we never launch guest in that way 89 gcpu_set_guest_visible_control_reg(gcpu, IA32_CTRL_CR0, 0x60000010); 90 gcpu_set_control_reg(gcpu, IA32_CTRL_CR0, 0x60000010); 91 gcpu_set_guest_visible_control_reg(gcpu, IA32_CTRL_CR3, 0); 92 gcpu_set_control_reg(gcpu, IA32_CTRL_CR3, 0); 93 gcpu_set_guest_visible_control_reg(gcpu, IA32_CTRL_CR4, 0); 94 gcpu_set_control_reg(gcpu, IA32_CTRL_CR4, 0); 95 gcpu_set_control_reg(gcpu, IA32_CTRL_CR2, 0); 96 gcpu_set_control_reg(gcpu, IA32_CTRL_CR8, 0); 97 qualification.Uint64 = vmcs_read(vmcs, VMCS_EXIT_INFO_QUALIFICATION); 98 real_mode_segment = (UINT16) qualification.Sipi.Vector << 8; 99 gcpu_set_segment_reg(gcpu, IA32_SEG_CS, real_mode_segment, 100 real_mode_segment << 4, 0xFFFF, 0x9B); 101 // Attribute set bits: Present, R/W, Accessed 102 gcpu_set_segment_reg(gcpu, IA32_SEG_DS, 0, 0, 0xFFFF, 0x93); 103 gcpu_set_segment_reg(gcpu, IA32_SEG_ES, 0, 0, 0xFFFF, 0x93); 104 gcpu_set_segment_reg(gcpu, IA32_SEG_FS, 0, 0, 0xFFFF, 0x93); 105 gcpu_set_segment_reg(gcpu, IA32_SEG_GS, 0, 0, 0xFFFF, 0x93); 106 gcpu_set_segment_reg(gcpu, IA32_SEG_SS, 0, 0, 0xFFFF, 0x93); 107 /* IA Manual 3B: 23.3.1.2 108 For TR Bits 3:0 (Type). 109 — If the guest will not be IA-32e mode, the Type must be 3 or 11 110 — If the guest will be IA-32e mode, the Type must be 11 111 Using Type 11 here 112 */ 113 gcpu_set_segment_reg(gcpu, IA32_SEG_TR , 0, 0, 0xFFFF, 0x8B); // CIRT uses 8Bh 114 gcpu_set_segment_reg(gcpu, IA32_SEG_LDTR, 0, 0, 0xFFFF, 0x82); // CIRT uses 10082h 115 gcpu_set_gdt_reg(gcpu, 0, 0xFFFF); 116 gcpu_set_idt_reg(gcpu, 0, 0xFFFF); 117 gcpu_set_debug_reg(gcpu, IA32_REG_DR0, 0); 118 gcpu_set_debug_reg(gcpu, IA32_REG_DR1, 0); 119 gcpu_set_debug_reg(gcpu, IA32_REG_DR2, 0); 120 gcpu_set_debug_reg(gcpu, IA32_REG_DR3, 0); 121 gcpu_set_debug_reg(gcpu, IA32_REG_DR6, 0xFFFF0FF0); 122 gcpu_set_debug_reg(gcpu, IA32_REG_DR7, 0x00000400); 123 gcpu_set_gp_reg(gcpu, IA32_REG_RAX, 0); 124 gcpu_set_gp_reg(gcpu, IA32_REG_RBX, 0); 125 gcpu_set_gp_reg(gcpu, IA32_REG_RCX, 0); 126 gcpu_set_gp_reg(gcpu, IA32_REG_RDX, 0xF00); 127 gcpu_set_gp_reg(gcpu, IA32_REG_RDI, 0); 128 gcpu_set_gp_reg(gcpu, IA32_REG_RSI, 0); 129 gcpu_set_gp_reg(gcpu, IA32_REG_RBP, 0); 130 gcpu_set_gp_reg(gcpu, IA32_REG_RSP, 0); // CIRT uses FFFCh ?? 131 gcpu_set_gp_reg(gcpu, IA32_REG_RIP, 0); 132 gcpu_set_gp_reg(gcpu, IA32_REG_RFLAGS, 2); // CIRT uses 46h ?? 133 gcpu_set_msr_reg(gcpu, IA32_VMM_MSR_EFER, 0); 134 gcpu_set_activity_state(gcpu, Ia32VmxVmcsGuestSleepStateActive); 135 // set state in vmenter control fields 136 gcpu_set_vmenter_control( gcpu ); 137 ret_status = VMEXIT_HANDLED; 138 } while (0); 139 return ret_status; 140 } 141 142 143