From eb21f205e459423ea9c6dac16e2cc867e4cd31cf Mon Sep 17 00:00:00 2001 From: "Li, Fei1" Date: Fri, 2 Aug 2019 08:17:02 +0800 Subject: [PATCH] hv: vm_config: build pci device configure for SOS Align SOS pci device configure with pre-launched VM and filter pre-launched VM's PCI PT device from SOS pci device configure. Tracked-On: #3475 Signed-off-by: Li, Fei1 --- hypervisor/Makefile | 1 + .../arch/x86/configs/apl-mrb/pci_devices.h | 2 - .../arch/x86/configs/dnv-cb2/pci_devices.h | 1 - .../arch/x86/configs/nuc7i7dnb/pci_devices.h | 4 +- hypervisor/arch/x86/configs/pci_dev.c | 73 +++++++++++++++++++ hypervisor/arch/x86/guest/vm.c | 4 +- hypervisor/hw/pci.c | 3 + hypervisor/include/arch/x86/pci_dev.h | 17 +++++ hypervisor/include/arch/x86/vm_config.h | 6 ++ hypervisor/include/hw/pci.h | 2 + .../scenarios/logical_partition/pt_dev.c | 8 +- 11 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 hypervisor/arch/x86/configs/pci_dev.c create mode 100644 hypervisor/include/arch/x86/pci_dev.h diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 84b63d63c..5f6a3ef3e 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -247,6 +247,7 @@ VP_BASE_C_SRCS += boot/guest/vboot_info.c VP_BASE_C_SRCS += common/hv_main.c VP_BASE_C_SRCS += common/vm_load.c VP_BASE_C_SRCS += arch/x86/configs/vmptable.c +VP_BASE_C_SRCS += arch/x86/configs/pci_dev.c VP_BASE_C_SRCS += arch/x86/configs/$(CONFIG_BOARD)/ve820.c # virtual platform device model diff --git a/hypervisor/arch/x86/configs/apl-mrb/pci_devices.h b/hypervisor/arch/x86/configs/apl-mrb/pci_devices.h index fc9114769..5b6e3f42e 100644 --- a/hypervisor/arch/x86/configs/apl-mrb/pci_devices.h +++ b/hypervisor/arch/x86/configs/apl-mrb/pci_devices.h @@ -7,8 +7,6 @@ #ifndef PCI_DEVICES_H_ #define PCI_DEVICES_H_ -#define HOST_BRIDGE .pbdf.bits = {.b = 0x00U, .d = 0x00U, .f = 0x00U} - #define SATA_CONTROLLER_0 .pbdf.bits = {.b = 0x00U, .d = 0x12U, .f = 0x00U}, \ .vbar_base[0] = 0xb3f10000UL, \ .vbar_base[1] = 0xb3f53000UL, \ diff --git a/hypervisor/arch/x86/configs/dnv-cb2/pci_devices.h b/hypervisor/arch/x86/configs/dnv-cb2/pci_devices.h index d831e7ac1..cf987a2c1 100644 --- a/hypervisor/arch/x86/configs/dnv-cb2/pci_devices.h +++ b/hypervisor/arch/x86/configs/dnv-cb2/pci_devices.h @@ -7,7 +7,6 @@ #ifndef PCI_DEVICES_H_ #define PCI_DEVICES_H_ -#define HOST_BRIDGE .pbdf.bits = {.b = 0x00U, .d = 0x00U, .f = 0x00U} #define SATA_CONTROLLER_0 .pbdf.bits = {.b = 0x00U, .d = 0x14U, .f = 0x00U} #define USB_CONTROLLER_0 .pbdf.bits = {.b = 0x00U, .d = 0x15U, .f = 0x00U} #define ETHERNET_CONTROLLER_0 .pbdf.bits = {.b = 0x03U, .d = 0x00U, .f = 0x00U} diff --git a/hypervisor/arch/x86/configs/nuc7i7dnb/pci_devices.h b/hypervisor/arch/x86/configs/nuc7i7dnb/pci_devices.h index 105a3e459..0123b5f89 100644 --- a/hypervisor/arch/x86/configs/nuc7i7dnb/pci_devices.h +++ b/hypervisor/arch/x86/configs/nuc7i7dnb/pci_devices.h @@ -7,8 +7,6 @@ #ifndef PCI_DEVICES_H_ #define PCI_DEVICES_H_ -#define HOST_BRIDGE .pbdf.bits = {.b = 0x00U, .d = 0x00U, .f = 0x00U} - #define SATA_CONTROLLER_0 .pbdf.bits = {.b = 0x00U, .d = 0x17U, .f = 0x00U}, \ .vbar_base[0] = 0xdf248000UL, \ .vbar_base[1] = 0xdf24c000UL, \ @@ -20,7 +18,7 @@ #define ETHERNET_CONTROLLER_0 .pbdf.bits = {.b = 0x00U, .d = 0x1fU, .f = 0x06U}, \ .vbar_base[0] = 0xdf200000UL -#define NETWORK_CONTROLLER_0 .pbdf.bits = {.b = 0x10U, .d = 0x00U, .f = 0x00U}, \ +#define NETWORK_CONTROLLER_0 .pbdf.bits = {.b = 0x01U, .d = 0x00U, .f = 0x00U}, \ .vbar_base[0] = 0xdf100000UL #endif /* PCI_DEVICES_H_ */ diff --git a/hypervisor/arch/x86/configs/pci_dev.c b/hypervisor/arch/x86/configs/pci_dev.c new file mode 100644 index 000000000..1db2e390c --- /dev/null +++ b/hypervisor/arch/x86/configs/pci_dev.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +static uint16_t pcidev_config_num = 0U; +static struct acrn_vm_pci_dev_config pcidev_config[CONFIG_MAX_PCI_DEV_NUM] = {}; + +/* + * @pre pdev != NULL; + */ +static bool is_allocated_to_prelaunched_vm(struct pci_pdev *pdev) +{ + bool found = false; + uint16_t vmid; + uint32_t pci_idx; + struct acrn_vm_config *vm_config; + struct acrn_vm_pci_dev_config *dev_config; + + for (vmid = 0U; vmid < CONFIG_MAX_VM_NUM; vmid++) { + vm_config = get_vm_config(vmid); + if (vm_config->load_order != PRE_LAUNCHED_VM) { + continue; + } + + for (pci_idx = 0U; pci_idx < vm_config->pci_dev_num; pci_idx++) { + dev_config = &vm_config->pci_devs[pci_idx]; + if ((dev_config->emu_type == PCI_DEV_TYPE_PTDEV) && + bdf_is_equal(&dev_config->pbdf, &pdev->bdf)) { + dev_config->pdev = pdev; + found = true; + break; + } + } + + if (found) { + break; + } + } + + return found; +} + + +/* + * @pre: pdev != NULL + */ +void fill_pci_dev_config(struct pci_pdev *pdev) +{ + struct acrn_vm_pci_dev_config *dev_config; + + if (!is_allocated_to_prelaunched_vm(pdev)) { + dev_config = &pcidev_config[pcidev_config_num]; + dev_config->emu_type = (pdev->bdf.value != HOST_BRIDGE_BDF) ? PCI_DEV_TYPE_PTDEV : PCI_DEV_TYPE_HVEMUL; + dev_config->vbdf.value = pdev->bdf.value; + dev_config->pbdf.value = pdev->bdf.value; + dev_config->pdev = pdev; + pcidev_config_num++; + } +} + +/* + * @pre vm_config != NULL + */ +void initialize_sos_pci_dev_config(struct acrn_vm_config *vm_config) +{ + vm_config->pci_dev_num = pcidev_config_num; + vm_config->pci_devs = pcidev_config; +} diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 6b215a67f..897aa8b8e 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -27,6 +27,7 @@ #include #include #include +#include vm_sw_loader_t vm_sw_loader; @@ -447,8 +448,9 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_ status = init_vm_boot_info(vm); if (status != 0) { need_cleanup = true; + } else { + initialize_sos_pci_dev_config(vm_config); } - } else { /* For PRE_LAUNCHED_VM and POST_LAUNCHED_VM */ if ((vm_config->guest_flags & GUEST_FLAG_SECURE_WORLD_ENABLED) != 0U) { diff --git a/hypervisor/hw/pci.c b/hypervisor/hw/pci.c index f6dc5b61b..6bf6a8ba2 100644 --- a/hypervisor/hw/pci.c +++ b/hypervisor/hw/pci.c @@ -34,6 +34,7 @@ #include #include #include +#include static spinlock_t pci_device_lock; uint32_t num_pci_pdev; @@ -414,6 +415,8 @@ static void fill_pdev(uint16_t pbdf, struct pci_pdev *pdev) if ((pci_pdev_read_cfg(pdev->bdf, PCIR_STATUS, 2U) & PCIM_STATUS_CAPPRESENT) != 0U) { pci_read_cap(pdev, hdr_type); } + + fill_pci_dev_config(pdev); } static void init_pdev(uint16_t pbdf) diff --git a/hypervisor/include/arch/x86/pci_dev.h b/hypervisor/include/arch/x86/pci_dev.h new file mode 100644 index 000000000..c303c6fda --- /dev/null +++ b/hypervisor/include/arch/x86/pci_dev.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PCI_DEV_H_ +#define PCI_DEV_H_ + +#include + +struct acrn_vm_config; + +void fill_pci_dev_config(struct pci_pdev *pdev); +void initialize_sos_pci_dev_config(struct acrn_vm_config *vm_config); + +#endif /* PCI_DEV_H_ */ diff --git a/hypervisor/include/arch/x86/vm_config.h b/hypervisor/include/arch/x86/vm_config.h index 2ba878d54..62e41b18f 100644 --- a/hypervisor/include/arch/x86/vm_config.h +++ b/hypervisor/include/arch/x86/vm_config.h @@ -20,6 +20,10 @@ #define MAX_VM_OS_NAME_LEN 32U #define MAX_MOD_TAG_LEN 32U +#define PCI_DEV_TYPE_PTDEV (1U << 0U) +#define PCI_DEV_TYPE_HVEMUL (1U << 1U) +#define PCI_DEV_TYPE_SOSEMUL (1U << 2U) + /* * PRE_LAUNCHED_VM is launched by ACRN hypervisor, with LAPIC_PT; * SOS_VM is launched by ACRN hypervisor, without LAPIC_PT; @@ -79,9 +83,11 @@ struct acrn_vm_os_config { } __aligned(8); struct acrn_vm_pci_dev_config { + uint32_t emu_type; /* the type how the device is emulated. */ union pci_bdf vbdf; /* virtual BDF of PCI device */ union pci_bdf pbdf; /* physical BDF of PCI device */ uint64_t vbar_base[PCI_BAR_COUNT]; /* vbar base address of PCI device */ + struct pci_pdev *pdev; /* the physical PCI device if it's a PT device */ } __aligned(8); struct acrn_vm_config { diff --git a/hypervisor/include/hw/pci.h b/hypervisor/include/hw/pci.h index 7d6601b84..60518a844 100644 --- a/hypervisor/include/hw/pci.h +++ b/hypervisor/include/hw/pci.h @@ -130,6 +130,8 @@ #define MSIX_CAPLEN 12U #define MSIX_TABLE_ENTRY_SIZE 16U +#define HOST_BRIDGE_BDF 0U + union pci_bdf { uint16_t value; struct { diff --git a/hypervisor/scenarios/logical_partition/pt_dev.c b/hypervisor/scenarios/logical_partition/pt_dev.c index 3a2603806..0c0bfe344 100644 --- a/hypervisor/scenarios/logical_partition/pt_dev.c +++ b/hypervisor/scenarios/logical_partition/pt_dev.c @@ -14,14 +14,16 @@ struct acrn_vm_pci_dev_config vm0_pci_devs[VM0_CONFIG_PCI_PTDEV_NUM] = { { + .emu_type = PCI_DEV_TYPE_HVEMUL, .vbdf.bits = {.b = 0x00U, .d = 0x00U, .f = 0x00U}, - HOST_BRIDGE }, { + .emu_type = PCI_DEV_TYPE_PTDEV, .vbdf.bits = {.b = 0x00U, .d = 0x01U, .f = 0x00U}, VM0_STORAGE_CONTROLLER }, { + .emu_type = PCI_DEV_TYPE_PTDEV, .vbdf.bits = {.b = 0x00U, .d = 0x02U, .f = 0x00U}, VM0_NETWORK_CONTROLLER }, @@ -29,15 +31,17 @@ struct acrn_vm_pci_dev_config vm0_pci_devs[VM0_CONFIG_PCI_PTDEV_NUM] = { struct acrn_vm_pci_dev_config vm1_pci_devs[VM1_CONFIG_PCI_PTDEV_NUM] = { { + .emu_type = PCI_DEV_TYPE_HVEMUL, .vbdf.bits = {.b = 0x00U, .d = 0x00U, .f = 0x00U}, - HOST_BRIDGE }, { + .emu_type = PCI_DEV_TYPE_PTDEV, .vbdf.bits = {.b = 0x00U, .d = 0x01U, .f = 0x00U}, VM1_STORAGE_CONTROLLER }, #if defined(VM1_NETWORK_CONTROLLER) { + .emu_type = PCI_DEV_TYPE_PTDEV, .vbdf.bits = {.b = 0x00U, .d = 0x02U, .f = 0x00U}, VM1_NETWORK_CONTROLLER },