Skip to content

Commit

Permalink
add MicroV support and move to 5.4
Browse files Browse the repository at this point in the history
  • Loading branch information
rianquinn committed Jul 14, 2020
1 parent aab9627 commit a564a15
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 38 deletions.
2 changes: 1 addition & 1 deletion arch/x86/boxy/Makefile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
obj-y := init.o virq.o vclock.o vmcall.o quirk.o
obj-y := init.o virq.o vclock.o intrinsics.o quirk.o
33 changes: 3 additions & 30 deletions arch/x86/boxy/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,12 @@

static uint32_t __init boxy_detect(void)
{
uint32_t eax;
uint32_t ignore[3];

if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
return 0;

cpuid(CPUID_BAREFLANK_SYN, &eax, &ignore[0], &ignore[1], &ignore[2]);

/**
* TODO:
*
* We need to add a Boxy specific CPUID leaf at 0x40000000 that acks like
* VMWare and HyperV so that we play nice with nested virtualization.
* More importantly, right now we are acking with Bareflank and not
* Boxy, so this code could end up detecting someone elses hypervisor.
*/

/**
* TODO:
*
* We need to implement versioning to ensure that we are using a guest
* that actually knows how to talk to the hypervisor.
*/

if (eax == CPUID_BAREFLANK_ACK)
return 1;

return 0;
return mv_present(MV_SPEC_ID1_VAL);
}

static void __init boxy_init_platform(void)
{
pv_info.name = "Boxy Hypervisor";
pv_info.name = "MicroV Hypervisor";

boxy_virq_init();
boxy_vclock_init();
Expand All @@ -76,7 +49,7 @@ static bool __init boxy_x2apic_available(void)
{ return true; }

const __initconst struct hypervisor_x86 x86_hyper_boxy = {
.name = "Boxy Hypervisor",
.name = "MicroV Hypervisor",
.detect = boxy_detect,
.type = X86_HYPER_BOXY,
.init.init_platform = boxy_init_platform,
Expand Down
34 changes: 34 additions & 0 deletions arch/x86/boxy/vmcall.S → arch/x86/boxy/intrinsics.S
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,35 @@
.code64
.intel_syntax noprefix

/* -------------------------------------------------------------------------- */
/* _mv_cpuid */
/* -------------------------------------------------------------------------- */

.globl _mv_cpuid
.type _mv_cpuid, @function
_mv_cpuid:
push rbx

mov r10, rdx
mov r11, rcx

mov eax, [rdi]
cpuid

mov [rdi], eax
mov [rsi], ebx
mov [r10], ecx
mov [r11], edx

pop rbx
ret
.size _mv_cpuid, .-_mv_cpuid


/* -------------------------------------------------------------------------- */
/* !!! WARNBING DEPRECATED !!! */
/* -------------------------------------------------------------------------- */

.globl asm_vmcall
.type asm_vmcall, @function
asm_vmcall:
Expand All @@ -37,6 +66,7 @@ asm_vmcall:

pop rbx
ret
.size asm_vmcall, .-asm_vmcall

.globl asm_vmcall1
.type asm_vmcall1, @function
Expand All @@ -57,6 +87,7 @@ asm_vmcall1:

pop rbx
ret
.size asm_vmcall1, .-asm_vmcall1

.globl asm_vmcall2
.type asm_vmcall2, @function
Expand All @@ -79,6 +110,7 @@ asm_vmcall2:

pop rbx
ret
.size asm_vmcall2, .-asm_vmcall2

.globl asm_vmcall3
.type asm_vmcall3, @function
Expand All @@ -103,6 +135,7 @@ asm_vmcall3:

pop rbx
ret
.size asm_vmcall3, .-asm_vmcall3

.globl asm_vmcall4
.type asm_vmcall4, @function
Expand All @@ -129,3 +162,4 @@ asm_vmcall4:

pop rbx
ret
.size asm_vmcall4, .-asm_vmcall4
144 changes: 137 additions & 7 deletions arch/x86/include/asm/boxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,143 @@
#include <asm/msr.h>
#include <asm/processor.h>

// -----------------------------------------------------------------------------
// Prototypes
// -----------------------------------------------------------------------------

void
_mv_cpuid(
uint32_t *eax,
uint32_t *ebx,
uint32_t *ecx,
uint32_t *edx);

// -----------------------------------------------------------------------------
// Scalar Types
// -----------------------------------------------------------------------------

#define mv_status_t uint64_t
#define mv_uint8_t uint8_t
#define mv_uint16_t uint16_t
#define mv_uint32_t uint32_t
#define mv_uint64_t uint64_t

// -----------------------------------------------------------------------------
// Specification IDs
// -----------------------------------------------------------------------------

#define MV_SPEC_ID1_VAL ((mv_uint32_t)0x3123764D)

// -----------------------------------------------------------------------------
// Hypervisor Discovery
// -----------------------------------------------------------------------------

#define MV_CPUID_HYPERVISOR_PRESENT (((mv_uint32_t)1) << 31)
#define MV_CPUID_SPEC_ID1 (((mv_uint32_t)1) << 0)

#define MV_CPUID_MIN_LEAF_VAL ((mv_uint32_t)0x40000202)
#define MV_CPUID_MAX_LEAF_VAL ((mv_uint32_t)0x4000FFFF)
#define MV_CPUID_INIT_VAL ((mv_uint32_t)0x40000200)
#define MV_CPUID_INC_VAL ((mv_uint32_t)0x100)
#define MV_CPUID_VENDOR_ID1_VAL ((mv_uint32_t)0x694D6642)
#define MV_CPUID_VENDOR_ID2_VAL ((mv_uint32_t)0x566F7263)

static inline mv_uint32_t
mv_present(mv_uint32_t spec_id)
{
mv_uint32_t eax;
mv_uint32_t ebx;
mv_uint32_t ecx;
mv_uint32_t edx;
mv_uint32_t max_leaf;
mv_uint32_t leaf;

/**
* First check to see if software is running on a hypervisor. Although not
* officially documented by Intel/AMD, bit 31 of the feature identifiers is
* reserved for hypervisors, and any hypervisor that conforms (at least in
* part) to the Hypervisor Top Level Functional Specification will set this.
*/

eax = 0x00000001;
_mv_cpuid(&eax, &ebx, &ecx, &edx);

if ((ecx & MV_CPUID_HYPERVISOR_PRESENT) == 0) {
return 0;
}

/**
* Now that we know that we are running on a hypervisor, the next step is
* determine how many hypervisor specific CPUID leaves are supported. This
* is done as follows. Note that the MicroV spec defines the min/max values
* for the return of this query, which we can also use to determine if this
* is MicroV.
*/

eax = 0x40000000;
_mv_cpuid(&eax, &ebx, &ecx, &edx);

max_leaf = eax;
if (max_leaf < MV_CPUID_MIN_LEAF_VAL || max_leaf > MV_CPUID_MAX_LEAF_VAL) {
return 0;
}

/**
* Now that we know how many CPUID leaves to parse, we can scan the CPUID
* leaves for MicroV. Since MicroV also supports the HyperV and Xen
* interfaces, we start at 0x40000200, and increment by 0x100 until we
* find MicroV's signature. Normally, the first leaf should be MicroV, but
* we need to scan just incase future MicroV specs add additional ABIs.
*/

for (leaf = MV_CPUID_INIT_VAL; leaf < max_leaf; leaf += MV_CPUID_INC_VAL) {
eax = leaf;
_mv_cpuid(&eax, &ebx, &ecx, &edx);

if (ebx == MV_CPUID_VENDOR_ID1_VAL && ecx == MV_CPUID_VENDOR_ID2_VAL) {
break;
}
}

if (leaf >= max_leaf) {
return 0;
}

/**
* Finally, we need to verify which version of the spec software speaks and
* verifying that MicroV also speaks this same spec.
*/

eax = leaf + 0x00000001U;
_mv_cpuid(&eax, &ebx, &ecx, &edx);

switch (spec_id) {
case MV_SPEC_ID1_VAL: {
if ((eax & MV_CPUID_SPEC_ID1) == 0) {
return 0;
}

break;
}

default:
return 0;
}

/**
* If we got this far, it means that software is running on MicroV, and
* both MicroV and software speak the same specification, which means
* software may proceed with communicating with MicroV. The next step is
* to open an handle and use it for additional hypercalls.
*/

return 1;
}

/* -------------------------------------------------------------------------- */
/* !!! WARNING DEPRECATED !!! */
/* -------------------------------------------------------------------------- */

#define SUCCESS 0
#define FAILURE 0xFFFFFFFFFFFFFFFF
#define SUSPEND 0xFFFFFFFFFFFFFFFE
Expand All @@ -27,13 +164,6 @@ uint64_t asm_vmcall2(void *r1, void *r2);
uint64_t asm_vmcall3(void *r1, void *r2, void *r3);
uint64_t asm_vmcall4(void *r1, void *r2, void *r3, void *r4);

/* -------------------------------------------------------------------------- */
/* CPUID */
/* -------------------------------------------------------------------------- */

#define CPUID_BAREFLANK_SYN 0x4BF00000
#define CPUID_BAREFLANK_ACK 0x4BF00001

/* -------------------------------------------------------------------------- */
/* Virtual IRQs */
/* -------------------------------------------------------------------------- */
Expand Down

0 comments on commit a564a15

Please sign in to comment.