@@ -163,6 +163,21 @@ struct vcpu *get_ever_run_vcpu(uint16_t pcpu_id)
163
163
return per_cpu (ever_run_vcpu , pcpu_id );
164
164
}
165
165
166
+ static void set_vcpu_mode (struct vcpu * vcpu , uint32_t cs_attr , uint64_t ia32_efer ,
167
+ uint64_t cr0 )
168
+ {
169
+ if (ia32_efer & MSR_IA32_EFER_LMA_BIT ) {
170
+ if (cs_attr & 0x2000 ) /* CS.L = 1 */
171
+ vcpu -> arch_vcpu .cpu_mode = CPU_MODE_64BIT ;
172
+ else
173
+ vcpu -> arch_vcpu .cpu_mode = CPU_MODE_COMPATIBILITY ;
174
+ } else if (cr0 & CR0_PE ) {
175
+ vcpu -> arch_vcpu .cpu_mode = CPU_MODE_PROTECTED ;
176
+ } else {
177
+ vcpu -> arch_vcpu .cpu_mode = CPU_MODE_REAL ;
178
+ }
179
+ }
180
+
166
181
void set_vcpu_regs (struct vcpu * vcpu , struct acrn_vcpu_regs * vcpu_regs )
167
182
{
168
183
struct ext_context * ectx ;
@@ -239,6 +254,9 @@ void set_vcpu_regs(struct vcpu *vcpu, struct acrn_vcpu_regs *vcpu_regs)
239
254
ctx -> cr0 = vcpu_regs -> cr0 ;
240
255
ectx -> cr3 = vcpu_regs -> cr3 ;
241
256
ctx -> cr4 = vcpu_regs -> cr4 ;
257
+
258
+ set_vcpu_mode (vcpu , vcpu_regs -> cs_ar , vcpu_regs -> ia32_efer ,
259
+ vcpu_regs -> cr0 );
242
260
}
243
261
244
262
static struct acrn_vcpu_regs realmode_init_regs = {
@@ -411,24 +429,10 @@ int create_vcpu(uint16_t pcpu_id, struct vm *vm, struct vcpu **rtn_vcpu_handle)
411
429
return 0 ;
412
430
}
413
431
414
- static void set_vcpu_mode (struct vcpu * vcpu , uint32_t cs_attr )
415
- {
416
- if (is_long_mode (vcpu )) {
417
- if (cs_attr & 0x2000 ) /* CS.L = 1 */
418
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_64BIT ;
419
- else
420
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_COMPATIBILITY ;
421
- } else if (vcpu_get_cr0 (vcpu ) & CR0_PE ) {
422
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_PROTECTED ;
423
- } else {
424
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_REAL ;
425
- }
426
- }
427
-
428
432
int run_vcpu (struct vcpu * vcpu )
429
433
{
430
- uint32_t instlen ;
431
- uint64_t rip ;
434
+ uint32_t instlen , cs_attr ;
435
+ uint64_t rip , ia32_efer , cr0 ;
432
436
struct run_context * ctx =
433
437
& vcpu -> arch_vcpu .contexts [vcpu -> arch_vcpu .cur_context ].run_ctx ;
434
438
int64_t status = 0 ;
@@ -494,7 +498,10 @@ int run_vcpu(struct vcpu *vcpu)
494
498
495
499
vcpu -> reg_cached = 0UL ;
496
500
497
- set_vcpu_mode (vcpu , exec_vmread32 (VMX_GUEST_CS_ATTR ));
501
+ cs_attr = exec_vmread32 (VMX_GUEST_CS_ATTR );
502
+ ia32_efer = vcpu_get_efer (vcpu );
503
+ cr0 = vcpu_get_cr0 (vcpu );
504
+ set_vcpu_mode (vcpu , cs_attr , ia32_efer , cr0 );
498
505
499
506
/* Obtain current VCPU instruction length */
500
507
vcpu -> arch_vcpu .inst_len = exec_vmread32 (VMX_EXIT_INSTR_LEN );
@@ -642,41 +649,15 @@ int prepare_vcpu(struct vm *vm, uint16_t pcpu_id)
642
649
ret = create_vcpu (pcpu_id , vm , & vcpu );
643
650
ASSERT (ret == 0 , "vcpu create failed" );
644
651
645
- if (is_vcpu_bsp (vcpu )) {
646
- /* Load VM SW */
647
- if (!vm_sw_loader )
648
- vm_sw_loader = general_sw_loader ;
649
- #ifdef CONFIG_PARTITION_MODE
650
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_PROTECTED ;
651
- #else
652
- if (is_vm0 (vcpu -> vm )) {
653
- struct acrn_vcpu_regs * vm0_init_ctx = & vm0_boot_context ;
654
- /* VM0 bsp start mode is decided by the boot context
655
- * setup by bootloader / bios */
656
- if ((vm0_init_ctx -> ia32_efer & MSR_IA32_EFER_LMA_BIT ) &&
657
- (vm0_init_ctx -> cs_ar & 0x2000 )) {
658
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_64BIT ;
659
- } else if (vm0_init_ctx -> cr0 & CR0_PE ) {
660
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_PROTECTED ;
661
- } else {
662
- return - EINVAL ;
663
- }
664
- vm_sw_loader (vm );
665
- } else {
666
- #ifdef CONFIG_EFI_STUB
667
- /* currently non-vm0 will boot kernel directly */
668
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_PROTECTED ;
669
- #else
670
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_REAL ;
671
- #endif
672
- }
673
- #endif //CONFIG_PARTITION_MODE
674
- } else {
675
- vcpu -> arch_vcpu .cpu_mode = CPU_MODE_REAL ;
652
+ if (!vm_sw_loader ) {
653
+ vm_sw_loader = general_sw_loader ;
676
654
}
677
655
678
- /* init_vmcs is delayed to vcpu vmcs launch first time */
656
+ if (is_vm0 (vm )) {
657
+ vm_sw_loader (vm );
658
+ }
679
659
660
+ /* init_vmcs is delayed to vcpu vmcs launch first time */
680
661
/* initialize the vcpu tsc aux */
681
662
vcpu -> msr_tsc_aux_guest = vcpu -> vcpu_id ;
682
663
0 commit comments