From 363daf6aa2658ce2b0fe04ba4ebaa907b7264458 Mon Sep 17 00:00:00 2001 From: Victor Sun Date: Mon, 29 Jul 2019 13:38:39 +0800 Subject: [PATCH] HV: return extended info in vCPUID leaf 0x40000001 In some case, guest need to get more information under virtual environment, like guest capabilities. Basically this could be done by hypercalls, but hypercalls are designed for trusted VM/SOS VM, We need a machenism to report these information for normal VMs. In this patch, vCPUID leaf 0x40000001 will be used to satisfy this needs that report some extended information for guest by CPUID. Tracked-On: #3498 Signed-off-by: Victor Sun Reviewed-by: Zhao Yakui Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/vcpuid.c | 23 ++++++++++++++++++++++ hypervisor/include/arch/x86/guest/vcpuid.h | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/hypervisor/arch/x86/guest/vcpuid.c b/hypervisor/arch/x86/guest/vcpuid.c index 0a9590135..6c3caa84c 100644 --- a/hypervisor/arch/x86/guest/vcpuid.c +++ b/hypervisor/arch/x86/guest/vcpuid.c @@ -172,6 +172,20 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf, break; } + /* + * Leaf 0x40000001 - ACRN extended information. + * This leaf returns the extended information of ACRN hypervisor. + * + * EAX: Guest capability flags + * EBX, ECX, EDX: RESERVED (reserved fields are set to zero). + */ + case 0x40000001U: + entry->eax = 0U; + entry->ebx = 0U; + entry->ecx = 0U; + entry->edx = 0U; + break; + /* * Leaf 0x40000010 - Timing Information. * This leaf returns the current TSC frequency and @@ -243,6 +257,15 @@ static int32_t set_vcpuid_extended_function(struct acrn_vm *vm) init_vcpuid_entry(0x40000000U, 0U, 0U, &entry); result = set_vcpuid_entry(vm, &entry); + if (result == 0) { + init_vcpuid_entry(0x40000001U, 0U, 0U, &entry); + /* EAX: Guest capability flags (e.g. whether it is a privilege VM) */ + if (is_sos_vm(vm)) { + entry.eax |= GUEST_CAPS_PRIVILEGE_VM; + } + result = set_vcpuid_entry(vm, &entry); + } + if (result == 0) { init_vcpuid_entry(0x40000010U, 0U, 0U, &entry); result = set_vcpuid_entry(vm, &entry); diff --git a/hypervisor/include/arch/x86/guest/vcpuid.h b/hypervisor/include/arch/x86/guest/vcpuid.h index 6de1b89b1..2c93a7e16 100644 --- a/hypervisor/include/arch/x86/guest/vcpuid.h +++ b/hypervisor/include/arch/x86/guest/vcpuid.h @@ -9,6 +9,10 @@ #define CPUID_CHECK_SUBLEAF (1U << 0U) #define MAX_VM_VCPUID_ENTRIES 64U + +/* Guest capability flags reported by CPUID */ +#define GUEST_CAPS_PRIVILEGE_VM (1U << 0U) + struct vcpuid_entry { uint32_t eax; uint32_t ebx;