From 6496da7c56d2fc9d5d533843d12a81e545e5575a Mon Sep 17 00:00:00 2001 From: dongshen Date: Wed, 18 Mar 2020 15:41:50 -0700 Subject: [PATCH] hv: add function to check if using posted interrupt is possible for vm Add platform_caps.c to maintain platform related information Set platform_caps.pi to true if all iommus are posted interrupt capable, false otherwise If lapic passthru is not configured and platform_caps.pi is true, the vm may be able to use posted interrupt for a ptdev, if the ptdev's IRQ is single-destination Tracked-On: #4506 Signed-off-by: dongshen Reviewed-by: Eddie Dong --- hypervisor/Makefile | 1 + hypervisor/arch/x86/guest/vm.c | 15 +++++++++++++++ hypervisor/arch/x86/platform_caps.c | 10 ++++++++++ hypervisor/arch/x86/vtd.c | 6 ++++++ hypervisor/include/arch/x86/guest/vm.h | 1 + hypervisor/include/arch/x86/platform_caps.h | 17 +++++++++++++++++ 6 files changed, 50 insertions(+) create mode 100644 hypervisor/arch/x86/platform_caps.c create mode 100644 hypervisor/include/arch/x86/platform_caps.h diff --git a/hypervisor/Makefile b/hypervisor/Makefile index b876f54aa..18041ffba 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -233,6 +233,7 @@ HW_C_SRCS += arch/x86/ioapic.c HW_C_SRCS += arch/x86/lapic.c HW_C_SRCS += arch/x86/cpu.c HW_C_SRCS += arch/x86/cpu_caps.c +HW_C_SRCS += arch/x86/platform_caps.c HW_C_SRCS += arch/x86/security.c HW_C_SRCS += arch/x86/mmu.c HW_C_SRCS += arch/x86/e820.c diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index e0adbb852..2de4a4e0d 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -31,6 +31,7 @@ #include #include #include +#include vm_sw_loader_t vm_sw_loader; @@ -115,6 +116,20 @@ bool is_rt_vm(const struct acrn_vm *vm) return ((vm_config->guest_flags & GUEST_FLAG_RT) != 0U); } +/** + * @brief VT-d PI posted mode can possibly be used for PTDEVs assigned + * to this VM if platform supports VT-d PI AND lapic passthru is not configured + * for this VM. + * However, as we can only post single destination IRQ, so meeting these 2 conditions + * does not necessarily mean posted mode will be used for all PTDEVs belonging + * to the VM, unless the IRQ is single-destination for the specific PTDEV + * @pre vm != NULL + */ +bool is_pi_capable(const struct acrn_vm *vm) +{ + return (platform_caps.pi && (!is_lapic_pt_configured(vm))); +} + static struct acrn_vm *get_highest_severity_vm(void) { uint16_t vm_id, highest_vm_id = 0U; diff --git a/hypervisor/arch/x86/platform_caps.c b/hypervisor/arch/x86/platform_caps.c new file mode 100644 index 000000000..c5321608c --- /dev/null +++ b/hypervisor/arch/x86/platform_caps.c @@ -0,0 +1,10 @@ +/* + * Copyright (C) 2020 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +struct platform_caps_x86 platform_caps = {.pi = true}; diff --git a/hypervisor/arch/x86/vtd.c b/hypervisor/arch/x86/vtd.c index fd7b0686e..10ea0a013 100644 --- a/hypervisor/arch/x86/vtd.c +++ b/hypervisor/arch/x86/vtd.c @@ -22,6 +22,7 @@ #include #include #include +#include #define DBG_IOMMU 0 @@ -206,6 +207,7 @@ static inline uint16_t vmid_to_domainid(uint16_t vm_id) static int32_t dmar_register_hrhd(struct dmar_drhd_rt *dmar_unit); static struct dmar_drhd_rt *device_to_dmaru(uint8_t bus, uint8_t devfun); + static int32_t register_hrhd_units(void) { struct dmar_drhd_rt *drhd_rt; @@ -224,6 +226,10 @@ static int32_t register_hrhd_units(void) if (ret != 0) { break; } + + if ((iommu_cap_pi(drhd_rt->cap) == 0U) || (!is_apicv_advanced_feature_supported())) { + platform_caps.pi = false; + } } return ret; diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index 45f63fe01..07c2edb3a 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -263,6 +263,7 @@ void vrtc_init(struct acrn_vm *vm); bool is_lapic_pt_configured(const struct acrn_vm *vm); bool is_rt_vm(const struct acrn_vm *vm); +bool is_pi_capable(const struct acrn_vm *vm); bool has_rt_vm(void); bool is_highest_severity_vm(const struct acrn_vm *vm); bool vm_hide_mtrr(const struct acrn_vm *vm); diff --git a/hypervisor/include/arch/x86/platform_caps.h b/hypervisor/include/arch/x86/platform_caps.h new file mode 100644 index 000000000..aa7dd2e92 --- /dev/null +++ b/hypervisor/include/arch/x86/platform_caps.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2020 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_CAPS_H +#define PLATFORM_CAPS_H + +struct platform_caps_x86 { + /* true if posted interrupt is supported by all IOMMUs */ + bool pi; +}; + +extern struct platform_caps_x86 platform_caps; + +#endif /* PLATFORM_CAPS_H */