diff --git a/hypervisor/Makefile b/hypervisor/Makefile index ce8e31935..b0da1d744 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -287,6 +287,9 @@ VP_BASE_C_SRCS += common/hv_main.c VP_BASE_C_SRCS += common/vm_load.c VP_BASE_C_SRCS += arch/x86/configs/pci_dev.c VP_BASE_C_SRCS += arch/x86/configs/vacpi.c +ifeq ($(CONFIG_SECURITY_VM_FIXUP),y) +VP_BASE_C_SRCS += quirks/security_vm_fixup.c +endif # virtual platform device model VP_DM_C_SRCS += dm/vpic.c diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 6d8068cd7..45a617ddf 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -39,6 +39,9 @@ #include #include #include +#ifdef CONFIG_SECURITY_VM_FIXUP +#include +#endif /* Local variables */ @@ -898,6 +901,9 @@ void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config) int32_t err = 0; struct acrn_vm *vm = NULL; +#ifdef CONFIG_SECURITY_VM_FIXUP + security_vm_fixup(vm_id); +#endif /* SOS and pre-launched VMs launch on all pCPUs defined in vm_config->cpu_affinity */ err = create_vm(vm_id, vm_config->cpu_affinity, vm_config, &vm); diff --git a/hypervisor/boot/guest/vboot_info.c b/hypervisor/boot/guest/vboot_info.c index 6784a770b..abf726200 100644 --- a/hypervisor/boot/guest/vboot_info.c +++ b/hypervisor/boot/guest/vboot_info.c @@ -124,7 +124,7 @@ static void init_vm_bootargs_info(struct acrn_vm *vm, const struct acrn_boot_inf /* @pre abi != NULL && tag != NULL */ -static struct abi_module *get_mod_by_tag(const struct acrn_boot_info *abi, const char *tag) +struct abi_module *get_mod_by_tag(const struct acrn_boot_info *abi, const char *tag) { uint8_t i; struct abi_module *mod = NULL; diff --git a/hypervisor/boot/include/acpi.h b/hypervisor/boot/include/acpi.h index 7fdefe358..f2b6f6677 100644 --- a/hypervisor/boot/include/acpi.h +++ b/hypervisor/boot/include/acpi.h @@ -235,6 +235,11 @@ struct acpi_table_tpm2 { uint16_t reserved; uint64_t control_address; uint32_t start_method; +#ifdef CONFIG_SECURITY_VM_FIXUP + uint8_t start_method_spec_para[12]; + uint32_t laml; + uint64_t lasa; +#endif } __packed; void init_acpi(void); diff --git a/hypervisor/boot/include/boot.h b/hypervisor/boot/include/boot.h index 1a0652c49..259ae7660 100644 --- a/hypervisor/boot/include/boot.h +++ b/hypervisor/boot/include/boot.h @@ -73,4 +73,5 @@ void init_acrn_boot_info(uint32_t *registers); int32_t sanitize_acrn_boot_info(struct acrn_boot_info *abi); struct acrn_boot_info *get_acrn_boot_info(void); +struct abi_module *get_mod_by_tag(const struct acrn_boot_info *abi, const char *tag); #endif /* BOOT_H */ diff --git a/hypervisor/include/public/acrn_common.h b/hypervisor/include/public/acrn_common.h index f1c60f31b..ee4e3436f 100644 --- a/hypervisor/include/public/acrn_common.h +++ b/hypervisor/include/public/acrn_common.h @@ -56,6 +56,7 @@ #define GUEST_FLAG_HIDE_MTRR (1UL << 3U) /* Whether hide MTRR from VM */ #define GUEST_FLAG_RT (1UL << 4U) /* Whether the vm is RT-VM */ #define GUEST_FLAG_NVMX_ENABLED (1UL << 5U) /* Whether this VM supports nested virtualization */ +#define GUEST_FLAG_TPM2_FIXUP (1UL << 6U) /* Whether this VM needs to do TPM2 fixup */ /* TODO: We may need to get this addr from guest ACPI instead of hardcode here */ #define VIRTUAL_SLEEP_CTL_ADDR 0x400U /* Pre-launched VM uses ACPI reduced HW mode and sleep control register */ diff --git a/hypervisor/quirks/security_vm_fixup.c b/hypervisor/quirks/security_vm_fixup.c new file mode 100644 index 000000000..04ca79279 --- /dev/null +++ b/hypervisor/quirks/security_vm_fixup.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include + +static void *get_acpi_mod_entry(const char *signature, void *acpi) +{ + struct acpi_table_xsdt *xsdt; + uint32_t i, entry_cnt = 0U; + struct acpi_table_header *header = NULL, *find = NULL; + + xsdt = acpi + VIRT_XSDT_ADDR - VIRT_ACPI_DATA_ADDR; + entry_cnt = (xsdt->header.length - sizeof(xsdt->header)) / (sizeof(xsdt->table_offset_entry[0])); + + for (i = 0; i < entry_cnt; i++) { + header = acpi + xsdt->table_offset_entry[i] - VIRT_ACPI_DATA_ADDR; + if (strncmp(header->signature, signature, ACPI_NAME_SIZE) == 0) { + find = header; + break; + } + } + + return find; +} + +static void tpm2_fixup(uint16_t vm_id) +{ + struct acpi_table_tpm2 *vtpm2 = NULL, *tpm2 = NULL; + struct acrn_vm_config *config = get_vm_config(vm_id); + uint8_t checksum, i; + struct acrn_boot_info *abi = get_acrn_boot_info(); + struct acrn_mmiodev *dev = NULL; + + struct abi_module *mod = get_mod_by_tag(abi, config->acpi_config.acpi_mod_tag); + if (mod != NULL) { + vtpm2 = get_acpi_mod_entry(ACPI_SIG_TPM2, mod->start); + tpm2 = get_acpi_tbl(ACPI_SIG_TPM2); + + if (config->pt_tpm2 && (vtpm2 != NULL) && (tpm2 != NULL)) { + for (i = 0U; i < MAX_MMIO_DEV_NUM; i++) { + if (strncmp(config->mmiodevs[i].name, "tpm2", 4) == 0) { + dev = &config->mmiodevs[i]; + break; + } + } + + if (dev != NULL) { + vtpm2->start_method = tpm2->start_method; + memcpy_s(&vtpm2->start_method_spec_para, sizeof(tpm2->start_method_spec_para), + &tpm2->start_method_spec_para, sizeof(tpm2->start_method_spec_para)); + + /* tpm2 has event log */ + if (tpm2->laml != 0U) { + vtpm2->header.length = tpm2->header.length; + vtpm2->header.revision = tpm2->header.revision; + vtpm2->laml = tpm2->laml; + vtpm2->lasa = dev->res[1].user_vm_pa; + + /* update log buffer length/HPA in vm_config */ + dev->res[1].size = tpm2->laml; + dev->res[1].host_pa = tpm2->lasa; + } + + /* update checksum */ + vtpm2->header.checksum = 0; + checksum = calculate_checksum8(vtpm2, sizeof(struct acpi_table_tpm2)); + vtpm2->header.checksum = checksum; + } else { + pr_err("%s, no TPM2 in acrn_vm_config", __func__); + } + } + } +} + +void security_vm_fixup(uint16_t vm_id) +{ + struct acrn_vm_config *vm_config = get_vm_config(vm_id); + + if ((vm_config->guest_flags & GUEST_FLAG_TPM2_FIXUP) != 0UL) { + stac(); + tpm2_fixup(vm_id); + clac(); + } +} + diff --git a/hypervisor/quirks/security_vm_fixup.h b/hypervisor/quirks/security_vm_fixup.h new file mode 100644 index 000000000..3af8a9b7d --- /dev/null +++ b/hypervisor/quirks/security_vm_fixup.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _SECURITY_VM_FIXUP_H_ +#define _SECURITY_VM_FIXUP_H_ + +void security_vm_fixup(uint16_t vm_id); + +#endif /* _SECURITY_VM_FIXUP_H_ */ diff --git a/misc/config_tools/library/common.py b/misc/config_tools/library/common.py index 2bbd89089..aaa055f54 100644 --- a/misc/config_tools/library/common.py +++ b/misc/config_tools/library/common.py @@ -23,7 +23,7 @@ DATACHECK_SCHEMA_FILE = SOURCE_ROOT_DIR + 'misc/config_tools/schema/datachecks.x PY_CACHES = ["__pycache__", "../board_config/__pycache__", "../scenario_config/__pycache__"] GUEST_FLAG = ["0", "0UL", "GUEST_FLAG_SECURE_WORLD_ENABLED", "GUEST_FLAG_LAPIC_PASSTHROUGH", "GUEST_FLAG_IO_COMPLETION_POLLING", "GUEST_FLAG_NVMX_ENABLED", "GUEST_FLAG_HIDE_MTRR", - "GUEST_FLAG_RT"] + "GUEST_FLAG_RT", "GUEST_FLAG_TPM2_FIXUP"] MULTI_ITEM = ["guest_flag", "pcpu_id", "vcpu_clos", "input", "block", "network", "pci_dev", "shm_region", "communication_vuart"] diff --git a/misc/config_tools/schema/VMtypes.xsd b/misc/config_tools/schema/VMtypes.xsd index 3cc93c613..be2720a55 100644 --- a/misc/config_tools/schema/VMtypes.xsd +++ b/misc/config_tools/schema/VMtypes.xsd @@ -37,7 +37,8 @@ IO polling to completion - ``GUEST_FLAG_HIDE_MTRR`` specify that MTRR is hidden from the VM - ``GUEST_FLAG_RT`` specify that the VM is an RT-VM (real-time) -- ``GUEST_FLAG_NVMX_ENABLED`` specify that the VM supports nested virtualization +- ``GUEST_FLAG_NVMX_ENABLED`` specify that the VM supports nested virtualization +- ``GUEST_FLAG_TPM2_FIXUP`` specify that the VM needs to do fixup for TPM2 passthrough @@ -49,6 +50,7 @@ + diff --git a/misc/config_tools/xforms/vm_configurations.h.xsl b/misc/config_tools/xforms/vm_configurations.h.xsl index 9fc1be214..0e70aeb46 100644 --- a/misc/config_tools/xforms/vm_configurations.h.xsl +++ b/misc/config_tools/xforms/vm_configurations.h.xsl @@ -50,7 +50,7 @@ - +