Skip to content

Commit 2df7b96

Browse files
binbinwu1lijinxia
authored andcommitted
hv: make control register handling functions to public
Move from vmexit.c to vmx.c Declare the functions in vmx.h Rename the functions' name with prefix vmx_. Signed-off-by: Binbin Wu <binbin.wu@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
1 parent 80a79fe commit 2df7b96

File tree

3 files changed

+101
-96
lines changed

3 files changed

+101
-96
lines changed

hypervisor/arch/x86/vmexit.c

Lines changed: 4 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -241,98 +241,6 @@ static int unhandled_vmexit_handler(__unused struct vcpu *vcpu)
241241
return 0;
242242
}
243243

244-
static int write_cr0(struct vcpu *vcpu, uint64_t value)
245-
{
246-
uint32_t value32;
247-
uint64_t value64;
248-
249-
pr_dbg("VMM: Guest trying to write 0x%08x to CR0", value);
250-
251-
/* Read host mask value */
252-
value64 = exec_vmread(VMX_CR0_MASK);
253-
254-
/* Clear all bits being written by guest that are owned by host */
255-
value &= ~value64;
256-
257-
/* Update CR0 in guest state */
258-
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr0 |= value;
259-
exec_vmwrite(VMX_GUEST_CR0,
260-
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr0);
261-
pr_dbg("VMM: Guest allowed to write 0x%08x to CR0",
262-
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr0);
263-
264-
/* If guest is trying to transition vcpu from unpaged real mode to page
265-
* protected mode make necessary changes to VMCS structure to reflect
266-
* transition from real mode to paged-protected mode
267-
*/
268-
if (!is_vcpu_bsp(vcpu) &&
269-
(vcpu->arch_vcpu.cpu_mode == CPU_MODE_REAL) &&
270-
(value & CR0_PG) && (value & CR0_PE)) {
271-
/* Enable protected mode */
272-
value32 = exec_vmread(VMX_ENTRY_CONTROLS);
273-
value32 |= (VMX_ENTRY_CTLS_IA32E_MODE |
274-
VMX_ENTRY_CTLS_LOAD_PAT |
275-
VMX_ENTRY_CTLS_LOAD_EFER);
276-
exec_vmwrite(VMX_ENTRY_CONTROLS, value32);
277-
pr_dbg("VMX_ENTRY_CONTROLS: 0x%x ", value32);
278-
279-
/* Set up EFER */
280-
value64 = exec_vmread64(VMX_GUEST_IA32_EFER_FULL);
281-
value64 |= (MSR_IA32_EFER_SCE_BIT |
282-
MSR_IA32_EFER_LME_BIT |
283-
MSR_IA32_EFER_LMA_BIT | MSR_IA32_EFER_NXE_BIT);
284-
exec_vmwrite64(VMX_GUEST_IA32_EFER_FULL, value64);
285-
pr_dbg("VMX_GUEST_IA32_EFER: 0x%016llx ", value64);
286-
}
287-
288-
return 0;
289-
}
290-
291-
static int write_cr3(struct vcpu *vcpu, uint64_t value)
292-
{
293-
/* Write to guest's CR3 */
294-
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr3 = value;
295-
296-
/* Commit new value to VMCS */
297-
exec_vmwrite(VMX_GUEST_CR3,
298-
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr3);
299-
300-
return 0;
301-
}
302-
303-
static int write_cr4(struct vcpu *vcpu, uint64_t value)
304-
{
305-
uint64_t temp64;
306-
307-
pr_dbg("VMM: Guest trying to write 0x%08x to CR4", value);
308-
309-
/* Read host mask value */
310-
temp64 = exec_vmread(VMX_CR4_MASK);
311-
312-
/* Clear all bits being written by guest that are owned by host */
313-
value &= ~temp64;
314-
315-
/* Write updated CR4 (bitwise OR of allowed guest bits and CR4 host
316-
* value)
317-
*/
318-
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr4 |= value;
319-
exec_vmwrite(VMX_GUEST_CR4,
320-
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr4);
321-
pr_dbg("VMM: Guest allowed to write 0x%08x to CR4",
322-
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr4);
323-
324-
return 0;
325-
}
326-
327-
static int read_cr3(struct vcpu *vcpu, uint64_t *value)
328-
{
329-
*value = vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr3;
330-
331-
pr_dbg("VMM: reading 0x%08x from CR3", *value);
332-
333-
return 0;
334-
}
335-
336244
int cpuid_vmexit_handler(struct vcpu *vcpu)
337245
{
338246
struct run_context *cur_context =
@@ -382,22 +290,22 @@ int cr_access_vmexit_handler(struct vcpu *vcpu)
382290
VM_EXIT_CR_ACCESS_CR_NUM(vcpu->arch_vcpu.exit_qualification)) {
383291
case 0x00:
384292
/* mov to cr0 */
385-
write_cr0(vcpu, *regptr);
293+
vmx_write_cr0(vcpu, *regptr);
386294
break;
387295

388296
case 0x03:
389297
/* mov to cr3 */
390-
write_cr3(vcpu, *regptr);
298+
vmx_write_cr3(vcpu, *regptr);
391299
break;
392300

393301
case 0x04:
394302
/* mov to cr4 */
395-
write_cr4(vcpu, *regptr);
303+
vmx_write_cr4(vcpu, *regptr);
396304
break;
397305

398306
case 0x13:
399307
/* mov from cr3 */
400-
read_cr3(vcpu, regptr);
308+
vmx_read_cr3(vcpu, regptr);
401309
break;
402310
#if 0
403311
case 0x14:

hypervisor/arch/x86/vmx.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,98 @@ uint32_t get_cs_access_rights(void)
240240
return usable_ar;
241241
}
242242

243+
int vmx_write_cr0(struct vcpu *vcpu, uint64_t value)
244+
{
245+
uint32_t value32;
246+
uint64_t value64;
247+
248+
pr_dbg("VMM: Guest trying to write 0x%08x to CR0", value);
249+
250+
/* Read host mask value */
251+
value64 = exec_vmread(VMX_CR0_MASK);
252+
253+
/* Clear all bits being written by guest that are owned by host */
254+
value &= ~value64;
255+
256+
/* Update CR0 in guest state */
257+
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr0 |= value;
258+
exec_vmwrite(VMX_GUEST_CR0,
259+
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr0);
260+
pr_dbg("VMM: Guest allowed to write 0x%08x to CR0",
261+
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr0);
262+
263+
/* If guest is trying to transition vcpu from unpaged real mode to page
264+
* protected mode make necessary changes to VMCS structure to reflect
265+
* transition from real mode to paged-protected mode
266+
*/
267+
if (!is_vcpu_bsp(vcpu) &&
268+
(vcpu->arch_vcpu.cpu_mode == CPU_MODE_REAL) &&
269+
(value & CR0_PG) && (value & CR0_PE)) {
270+
/* Enable protected mode */
271+
value32 = exec_vmread(VMX_ENTRY_CONTROLS);
272+
value32 |= (VMX_ENTRY_CTLS_IA32E_MODE |
273+
VMX_ENTRY_CTLS_LOAD_PAT |
274+
VMX_ENTRY_CTLS_LOAD_EFER);
275+
exec_vmwrite(VMX_ENTRY_CONTROLS, value32);
276+
pr_dbg("VMX_ENTRY_CONTROLS: 0x%x ", value32);
277+
278+
/* Set up EFER */
279+
value64 = exec_vmread64(VMX_GUEST_IA32_EFER_FULL);
280+
value64 |= (MSR_IA32_EFER_SCE_BIT |
281+
MSR_IA32_EFER_LME_BIT |
282+
MSR_IA32_EFER_LMA_BIT | MSR_IA32_EFER_NXE_BIT);
283+
exec_vmwrite64(VMX_GUEST_IA32_EFER_FULL, value64);
284+
pr_dbg("VMX_GUEST_IA32_EFER: 0x%016llx ", value64);
285+
}
286+
287+
return 0;
288+
}
289+
290+
int vmx_read_cr3(struct vcpu *vcpu, uint64_t *value)
291+
{
292+
*value = vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr3;
293+
294+
pr_dbg("VMM: reading 0x%08x from CR3", *value);
295+
296+
return 0;
297+
}
298+
299+
int vmx_write_cr3(struct vcpu *vcpu, uint64_t value)
300+
{
301+
/* Write to guest's CR3 */
302+
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr3 = value;
303+
304+
/* Commit new value to VMCS */
305+
exec_vmwrite(VMX_GUEST_CR3,
306+
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr3);
307+
308+
return 0;
309+
}
310+
311+
int vmx_write_cr4(struct vcpu *vcpu, uint64_t value)
312+
{
313+
uint64_t temp64;
314+
315+
pr_dbg("VMM: Guest trying to write 0x%08x to CR4", value);
316+
317+
/* Read host mask value */
318+
temp64 = exec_vmread(VMX_CR4_MASK);
319+
320+
/* Clear all bits being written by guest that are owned by host */
321+
value &= ~temp64;
322+
323+
/* Write updated CR4 (bitwise OR of allowed guest bits and CR4 host
324+
* value)
325+
*/
326+
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr4 |= value;
327+
exec_vmwrite(VMX_GUEST_CR4,
328+
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr4);
329+
pr_dbg("VMM: Guest allowed to write 0x%08x to CR4",
330+
vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr4);
331+
332+
return 0;
333+
}
334+
243335
static void init_guest_state(struct vcpu *vcpu)
244336
{
245337
uint64_t field;

hypervisor/include/arch/x86/vmx.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,11 @@ int init_vmcs(struct vcpu *vcpu);
464464
int exec_vmclear(void *addr);
465465
int exec_vmptrld(void *addr);
466466

467+
int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0);
468+
int vmx_read_cr3(struct vcpu *vcpu, uint64_t *cr3);
469+
int vmx_write_cr3(struct vcpu *vcpu, uint64_t cr3);
470+
int vmx_write_cr4(struct vcpu *vcpu, uint64_t cr4);
471+
467472
static inline uint8_t get_vcpu_mode(struct vcpu *vcpu)
468473
{
469474
return vcpu->arch_vcpu.cpu_mode;

0 commit comments

Comments
 (0)