From ed286e32396eb3a44f2ea91b407084a5cb70bcc2 Mon Sep 17 00:00:00 2001 From: Kaige Fu Date: Wed, 27 Mar 2019 14:47:49 +0000 Subject: [PATCH] HV: Introduce a new API is_rt_vm This patch checks if the GUEST_FLAG_RT is set when GUEST_FLAG_LAPIC_PASSTHROUGH is set. If GUEST_FLAG_RT is not set while GUEST_FLAG_LAPIC_PASSTHROUGH is set, we will refuse to boot the VM. Meanwhile, this patch introduces a new API is_rt_vm. Tracked-On: #2865 Signed-off-by: Kaige Fu Acked-by: Eddie Dong --- .../x86/configs/dnv-cb2/partition_config.h | 6 +++-- hypervisor/arch/x86/configs/vm_config.c | 4 +++ hypervisor/arch/x86/guest/vm.c | 10 +++++++ hypervisor/common/hypercall.c | 27 ++++++++++++------- hypervisor/include/arch/x86/guest/vm.h | 1 + 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/hypervisor/arch/x86/configs/dnv-cb2/partition_config.h b/hypervisor/arch/x86/configs/dnv-cb2/partition_config.h index f91d0ffc6..a8947d2fb 100644 --- a/hypervisor/arch/x86/configs/dnv-cb2/partition_config.h +++ b/hypervisor/arch/x86/configs/dnv-cb2/partition_config.h @@ -12,7 +12,8 @@ #define VM0_CONFIG_NAME "PRE-LAUNCHED VM1 for DNV-CB2" #define VM0_CONFIG_TYPE PRE_LAUNCHED_VM #define VM0_CONFIG_PCPU_BITMAP (PLUG_CPU(0) | PLUG_CPU(2) | PLUG_CPU(4) | PLUG_CPU(6)) -#define VM0_CONFIG_FLAGS GUEST_FLAG_LAPIC_PASSTHROUGH | GUEST_FLAG_IO_COMPLETION_POLLING +#define VM0_CONFIG_FLAGS (GUEST_FLAG_LAPIC_PASSTHROUGH | GUEST_FLAG_IO_COMPLETION_POLLING | \ + GUEST_FLAG_RT) #define VM0_CONFIG_MEM_START_HPA 0x100000000UL #define VM0_CONFIG_MEM_SIZE 0x80000000UL @@ -26,7 +27,8 @@ #define VM1_CONFIG_NAME "PRE-LAUNCHED VM2 for DNV-CB2" #define VM1_CONFIG_TYPE PRE_LAUNCHED_VM #define VM1_CONFIG_PCPU_BITMAP (PLUG_CPU(1) | PLUG_CPU(3) | PLUG_CPU(5) | PLUG_CPU(7)) -#define VM1_CONFIG_FLAGS GUEST_FLAG_LAPIC_PASSTHROUGH | GUEST_FLAG_IO_COMPLETION_POLLING +#define VM1_CONFIG_FLAGS (GUEST_FLAG_LAPIC_PASSTHROUGH | GUEST_FLAG_IO_COMPLETION_POLLING | \ + GUEST_FLAG_RT) #define VM1_CONFIG_MEM_START_HPA 0x180000000UL #define VM1_CONFIG_MEM_SIZE 0x80000000UL diff --git a/hypervisor/arch/x86/configs/vm_config.c b/hypervisor/arch/x86/configs/vm_config.c index 07cb0fa1b..02ea82c37 100644 --- a/hypervisor/arch/x86/configs/vm_config.c +++ b/hypervisor/arch/x86/configs/vm_config.c @@ -101,6 +101,10 @@ int32_t sanitize_vm_config(void) case PRE_LAUNCHED_VM: if (vm_config->pcpu_bitmap == 0U) { ret = -EINVAL; + /* GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH set in guest_flags */ + } else if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U) + && ((vm_config->guest_flags & GUEST_FLAG_RT) == 0U)) { + ret = -EINVAL; } else { pre_launch_pcpu_bitmap |= vm_config->pcpu_bitmap; } diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 498143653..f63c8e065 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -72,6 +72,16 @@ bool is_lapic_pt(const struct acrn_vm *vm) return ((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U); } +/** + * @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM + */ +bool is_rt_vm(const struct acrn_vm *vm) +{ + struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id); + + return ((vm_config->guest_flags & GUEST_FLAG_RT) != 0U); +} + /** * @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM */ diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index ee0c50be8..cfff4b662 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -136,19 +136,26 @@ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param) vm_config->guest_flags |= cv.vm_flag; (void)memcpy_s(&vm_config->GUID[0], 16U, &cv.GUID[0], 16U); - ret = create_vm(vm_id, vm_config, &target_vm); - if (ret != 0) { - dev_dbg(ACRN_DBG_HYCALL, "HCALL: Create VM failed"); - cv.vmid = ACRN_INVALID_VMID; + /* GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH set in guest_flags */ + if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U) + && ((vm_config->guest_flags & GUEST_FLAG_RT) == 0U)) { + pr_err("Wrong guest flags 0x%llx\n", vm_config->guest_flags); ret = -1; } else { - cv.vmid = target_vm->vm_id; - ret = 0; - } + ret = create_vm(vm_id, vm_config, &target_vm); + if (ret != 0) { + dev_dbg(ACRN_DBG_HYCALL, "HCALL: Create VM failed"); + cv.vmid = ACRN_INVALID_VMID; + ret = -1; + } else { + cv.vmid = target_vm->vm_id; + ret = 0; + } - if (copy_to_gpa(vm, &cv.vmid, param, sizeof(cv.vmid)) != 0) { - pr_err("%s: Unable copy param to vm\n", __func__); - ret = -1; + if (copy_to_gpa(vm, &cv.vmid, param, sizeof(cv.vmid)) != 0) { + pr_err("%s: Unable copy param to vm\n", __func__); + ret = -1; + } } } } else { diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index f74b6272b..2003d1ae5 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -221,6 +221,7 @@ uint16_t get_vm_pcpu_nums(const struct acrn_vm_config *vm_config); void vrtc_init(struct acrn_vm *vm); bool is_lapic_pt(const struct acrn_vm *vm); +bool is_rt_vm(const struct acrn_vm *vm); bool vm_hide_mtrr(const struct acrn_vm *vm); #endif /* !ASSEMBLER */