Skip to content

Commit a564a15

Browse files
committed
add MicroV support and move to 5.4
1 parent aab9627 commit a564a15

File tree

4 files changed

+175
-38
lines changed

4 files changed

+175
-38
lines changed

arch/x86/boxy/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
obj-y := init.o virq.o vclock.o vmcall.o quirk.o
1+
obj-y := init.o virq.o vclock.o intrinsics.o quirk.o

arch/x86/boxy/init.c

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,39 +21,12 @@
2121

2222
static uint32_t __init boxy_detect(void)
2323
{
24-
uint32_t eax;
25-
uint32_t ignore[3];
26-
27-
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
28-
return 0;
29-
30-
cpuid(CPUID_BAREFLANK_SYN, &eax, &ignore[0], &ignore[1], &ignore[2]);
31-
32-
/**
33-
* TODO:
34-
*
35-
* We need to add a Boxy specific CPUID leaf at 0x40000000 that acks like
36-
* VMWare and HyperV so that we play nice with nested virtualization.
37-
* More importantly, right now we are acking with Bareflank and not
38-
* Boxy, so this code could end up detecting someone elses hypervisor.
39-
*/
40-
41-
/**
42-
* TODO:
43-
*
44-
* We need to implement versioning to ensure that we are using a guest
45-
* that actually knows how to talk to the hypervisor.
46-
*/
47-
48-
if (eax == CPUID_BAREFLANK_ACK)
49-
return 1;
50-
51-
return 0;
24+
return mv_present(MV_SPEC_ID1_VAL);
5225
}
5326

5427
static void __init boxy_init_platform(void)
5528
{
56-
pv_info.name = "Boxy Hypervisor";
29+
pv_info.name = "MicroV Hypervisor";
5730

5831
boxy_virq_init();
5932
boxy_vclock_init();
@@ -76,7 +49,7 @@ static bool __init boxy_x2apic_available(void)
7649
{ return true; }
7750

7851
const __initconst struct hypervisor_x86 x86_hyper_boxy = {
79-
.name = "Boxy Hypervisor",
52+
.name = "MicroV Hypervisor",
8053
.detect = boxy_detect,
8154
.type = X86_HYPER_BOXY,
8255
.init.init_platform = boxy_init_platform,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,35 @@
1919
.code64
2020
.intel_syntax noprefix
2121

22+
/* -------------------------------------------------------------------------- */
23+
/* _mv_cpuid */
24+
/* -------------------------------------------------------------------------- */
25+
26+
.globl _mv_cpuid
27+
.type _mv_cpuid, @function
28+
_mv_cpuid:
29+
push rbx
30+
31+
mov r10, rdx
32+
mov r11, rcx
33+
34+
mov eax, [rdi]
35+
cpuid
36+
37+
mov [rdi], eax
38+
mov [rsi], ebx
39+
mov [r10], ecx
40+
mov [r11], edx
41+
42+
pop rbx
43+
ret
44+
.size _mv_cpuid, .-_mv_cpuid
45+
46+
47+
/* -------------------------------------------------------------------------- */
48+
/* !!! WARNBING DEPRECATED !!! */
49+
/* -------------------------------------------------------------------------- */
50+
2251
.globl asm_vmcall
2352
.type asm_vmcall, @function
2453
asm_vmcall:
@@ -37,6 +66,7 @@ asm_vmcall:
3766

3867
pop rbx
3968
ret
69+
.size asm_vmcall, .-asm_vmcall
4070

4171
.globl asm_vmcall1
4272
.type asm_vmcall1, @function
@@ -57,6 +87,7 @@ asm_vmcall1:
5787

5888
pop rbx
5989
ret
90+
.size asm_vmcall1, .-asm_vmcall1
6091

6192
.globl asm_vmcall2
6293
.type asm_vmcall2, @function
@@ -79,6 +110,7 @@ asm_vmcall2:
79110

80111
pop rbx
81112
ret
113+
.size asm_vmcall2, .-asm_vmcall2
82114

83115
.globl asm_vmcall3
84116
.type asm_vmcall3, @function
@@ -103,6 +135,7 @@ asm_vmcall3:
103135

104136
pop rbx
105137
ret
138+
.size asm_vmcall3, .-asm_vmcall3
106139

107140
.globl asm_vmcall4
108141
.type asm_vmcall4, @function
@@ -129,3 +162,4 @@ asm_vmcall4:
129162

130163
pop rbx
131164
ret
165+
.size asm_vmcall4, .-asm_vmcall4

arch/x86/include/asm/boxy.h

Lines changed: 137 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,143 @@
1111
#include <asm/msr.h>
1212
#include <asm/processor.h>
1313

14+
// -----------------------------------------------------------------------------
15+
// Prototypes
16+
// -----------------------------------------------------------------------------
17+
18+
void
19+
_mv_cpuid(
20+
uint32_t *eax,
21+
uint32_t *ebx,
22+
uint32_t *ecx,
23+
uint32_t *edx);
24+
25+
// -----------------------------------------------------------------------------
26+
// Scalar Types
27+
// -----------------------------------------------------------------------------
28+
29+
#define mv_status_t uint64_t
30+
#define mv_uint8_t uint8_t
31+
#define mv_uint16_t uint16_t
32+
#define mv_uint32_t uint32_t
33+
#define mv_uint64_t uint64_t
34+
35+
// -----------------------------------------------------------------------------
36+
// Specification IDs
37+
// -----------------------------------------------------------------------------
38+
39+
#define MV_SPEC_ID1_VAL ((mv_uint32_t)0x3123764D)
40+
41+
// -----------------------------------------------------------------------------
42+
// Hypervisor Discovery
43+
// -----------------------------------------------------------------------------
44+
45+
#define MV_CPUID_HYPERVISOR_PRESENT (((mv_uint32_t)1) << 31)
46+
#define MV_CPUID_SPEC_ID1 (((mv_uint32_t)1) << 0)
47+
48+
#define MV_CPUID_MIN_LEAF_VAL ((mv_uint32_t)0x40000202)
49+
#define MV_CPUID_MAX_LEAF_VAL ((mv_uint32_t)0x4000FFFF)
50+
#define MV_CPUID_INIT_VAL ((mv_uint32_t)0x40000200)
51+
#define MV_CPUID_INC_VAL ((mv_uint32_t)0x100)
52+
#define MV_CPUID_VENDOR_ID1_VAL ((mv_uint32_t)0x694D6642)
53+
#define MV_CPUID_VENDOR_ID2_VAL ((mv_uint32_t)0x566F7263)
54+
55+
static inline mv_uint32_t
56+
mv_present(mv_uint32_t spec_id)
57+
{
58+
mv_uint32_t eax;
59+
mv_uint32_t ebx;
60+
mv_uint32_t ecx;
61+
mv_uint32_t edx;
62+
mv_uint32_t max_leaf;
63+
mv_uint32_t leaf;
64+
65+
/**
66+
* First check to see if software is running on a hypervisor. Although not
67+
* officially documented by Intel/AMD, bit 31 of the feature identifiers is
68+
* reserved for hypervisors, and any hypervisor that conforms (at least in
69+
* part) to the Hypervisor Top Level Functional Specification will set this.
70+
*/
71+
72+
eax = 0x00000001;
73+
_mv_cpuid(&eax, &ebx, &ecx, &edx);
74+
75+
if ((ecx & MV_CPUID_HYPERVISOR_PRESENT) == 0) {
76+
return 0;
77+
}
78+
79+
/**
80+
* Now that we know that we are running on a hypervisor, the next step is
81+
* determine how many hypervisor specific CPUID leaves are supported. This
82+
* is done as follows. Note that the MicroV spec defines the min/max values
83+
* for the return of this query, which we can also use to determine if this
84+
* is MicroV.
85+
*/
86+
87+
eax = 0x40000000;
88+
_mv_cpuid(&eax, &ebx, &ecx, &edx);
89+
90+
max_leaf = eax;
91+
if (max_leaf < MV_CPUID_MIN_LEAF_VAL || max_leaf > MV_CPUID_MAX_LEAF_VAL) {
92+
return 0;
93+
}
94+
95+
/**
96+
* Now that we know how many CPUID leaves to parse, we can scan the CPUID
97+
* leaves for MicroV. Since MicroV also supports the HyperV and Xen
98+
* interfaces, we start at 0x40000200, and increment by 0x100 until we
99+
* find MicroV's signature. Normally, the first leaf should be MicroV, but
100+
* we need to scan just incase future MicroV specs add additional ABIs.
101+
*/
102+
103+
for (leaf = MV_CPUID_INIT_VAL; leaf < max_leaf; leaf += MV_CPUID_INC_VAL) {
104+
eax = leaf;
105+
_mv_cpuid(&eax, &ebx, &ecx, &edx);
106+
107+
if (ebx == MV_CPUID_VENDOR_ID1_VAL && ecx == MV_CPUID_VENDOR_ID2_VAL) {
108+
break;
109+
}
110+
}
111+
112+
if (leaf >= max_leaf) {
113+
return 0;
114+
}
115+
116+
/**
117+
* Finally, we need to verify which version of the spec software speaks and
118+
* verifying that MicroV also speaks this same spec.
119+
*/
120+
121+
eax = leaf + 0x00000001U;
122+
_mv_cpuid(&eax, &ebx, &ecx, &edx);
123+
124+
switch (spec_id) {
125+
case MV_SPEC_ID1_VAL: {
126+
if ((eax & MV_CPUID_SPEC_ID1) == 0) {
127+
return 0;
128+
}
129+
130+
break;
131+
}
132+
133+
default:
134+
return 0;
135+
}
136+
137+
/**
138+
* If we got this far, it means that software is running on MicroV, and
139+
* both MicroV and software speak the same specification, which means
140+
* software may proceed with communicating with MicroV. The next step is
141+
* to open an handle and use it for additional hypercalls.
142+
*/
143+
144+
return 1;
145+
}
146+
147+
/* -------------------------------------------------------------------------- */
148+
/* !!! WARNING DEPRECATED !!! */
149+
/* -------------------------------------------------------------------------- */
150+
14151
#define SUCCESS 0
15152
#define FAILURE 0xFFFFFFFFFFFFFFFF
16153
#define SUSPEND 0xFFFFFFFFFFFFFFFE
@@ -27,13 +164,6 @@ uint64_t asm_vmcall2(void *r1, void *r2);
27164
uint64_t asm_vmcall3(void *r1, void *r2, void *r3);
28165
uint64_t asm_vmcall4(void *r1, void *r2, void *r3, void *r4);
29166

30-
/* -------------------------------------------------------------------------- */
31-
/* CPUID */
32-
/* -------------------------------------------------------------------------- */
33-
34-
#define CPUID_BAREFLANK_SYN 0x4BF00000
35-
#define CPUID_BAREFLANK_ACK 0x4BF00001
36-
37167
/* -------------------------------------------------------------------------- */
38168
/* Virtual IRQs */
39169
/* -------------------------------------------------------------------------- */

0 commit comments

Comments
 (0)