Skip to content
This repository was archived by the owner on Jan 28, 2023. It is now read-only.

Commit 3a0654a

Browse files
committed
Change cpuid 1, 4 and 0x80000008 returned values according to number
of virtual CPUs Signed-off-by: Alexey Romko <[email protected]>
1 parent 7f3aaab commit 3a0654a

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

core/vcpu.c

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2610,6 +2610,16 @@ static void handle_cpuid_virtual(struct vcpu_t *vcpu, uint32_t a, uint32_t c)
26102610
uint32_t reserved2 : 4;
26112611
};
26122612
} cpuid_eax;
2613+
struct vm_t *vm = vcpu->vm;
2614+
hax_list_head *list;
2615+
int vcpu_count = 0;
2616+
2617+
hax_mutex_lock(vm->vm_lock);
2618+
hax_list_for_each(list, (hax_list_head *)(&vm->vcpu_list)) {
2619+
vcpu_count++;
2620+
}
2621+
hax_mutex_unlock(vm->vm_lock);
2622+
26132623
cpuid_eax.raw = state->_eax;
26142624

26152625
if (0xF != cpuid_eax.familyID)
@@ -2651,6 +2661,9 @@ static void handle_cpuid_virtual(struct vcpu_t *vcpu, uint32_t a, uint32_t c)
26512661
// (see IA SDM Vol. 3A 3.2, Table 3-14)
26522662
0x00;
26532663

2664+
if (vcpu_count > 1)
2665+
state->_ebx |= (vcpu_count) << 16;
2666+
26542667
// Report only the features specified, excluding any features not
26552668
// supported by the host CPU, but including "hypervisor", which is
26562669
// desirable for VMMs.
@@ -2673,8 +2686,23 @@ static void handle_cpuid_virtual(struct vcpu_t *vcpu, uint32_t a, uint32_t c)
26732686
return;
26742687
}
26752688
case 4: { // Deterministic Cache Parameters
2676-
// [31:26] cores per package - 1
2677-
// Use host cache values.
2689+
// Use host cache values, but change maximum number of addresable
2690+
// IDs according to the number of virtual CPUs (bits [31:26]).
2691+
state->_eax &= ~0xFC000000;
2692+
if (state->_eax & 31) {
2693+
struct vm_t *vm = vcpu->vm;
2694+
hax_list_head *list;
2695+
int vcpu_count = 0;
2696+
2697+
hax_mutex_lock(vm->vm_lock);
2698+
hax_list_for_each(list, (hax_list_head *)(&vm->vcpu_list)) {
2699+
vcpu_count++;
2700+
}
2701+
hax_mutex_unlock(vm->vm_lock);
2702+
2703+
if (vcpu_count > 1)
2704+
state->_eax |= (vcpu_count - 1) << 26;
2705+
}
26782706
return;
26792707
}
26802708
case 5: // MONITOR/MWAIT
@@ -2772,13 +2800,26 @@ static void handle_cpuid_virtual(struct vcpu_t *vcpu, uint32_t a, uint32_t c)
27722800
return;
27732801
}
27742802
case 0x80000008: { // Virtual/Physical Address Size
2803+
struct vm_t *vm = vcpu->vm;
2804+
hax_list_head *list;
2805+
int vcpu_count = 0;
2806+
2807+
hax_mutex_lock(vm->vm_lock);
2808+
hax_list_for_each(list, (hax_list_head *)(&vm->vcpu_list)) {
2809+
vcpu_count++;
2810+
}
2811+
hax_mutex_unlock(vm->vm_lock);
2812+
27752813
// Bit mask to identify the reserved bits in paging structure high
27762814
// order address field
27772815
physical_address_size = (uint8_t)state->_eax & 0xff;
27782816
pw_reserved_bits_high_mask =
27792817
~((1 << (physical_address_size - 32)) - 1);
27802818

27812819
state->_ebx = state->_ecx = state->_edx = 0;
2820+
2821+
if (vcpu_count > 1)
2822+
state->_ecx |= vcpu_count - 1;
27822823
return;
27832824
}
27842825
}

0 commit comments

Comments
 (0)