mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-24 14:33:38 +00:00
hv: tpm2: do tpm2 fixup for security vm
ACRN used to prepare the vTPM2 ACPI Table for pre-launched VM at the build stage using config tools. This is OK if the TPM2 ACPI Table never changes. However, TPM2 ACPI Table may be changed in some conditions: change BIOS configuration or update BIOS. This patch do TPM2 fixup to update the vTPM2 ACPI Table and TPM2 MMIO resource configuration according to the physical TPM2 ACPI Table. Tracked-On: #6366 Signed-off-by: Tao Yuhong <yuhong.tao@intel.com> Signed-off-by: Fei Li <fei1.li@intel.com>
This commit is contained in:
parent
f81b39225c
commit
74e68e39d1
@ -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
|
||||
|
@ -39,6 +39,9 @@
|
||||
#include <asm/rtcm.h>
|
||||
#include <asm/irq.h>
|
||||
#include <uart16550.h>
|
||||
#ifdef CONFIG_SECURITY_VM_FIXUP
|
||||
#include <quirks/security_vm_fixup.h>
|
||||
#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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
91
hypervisor/quirks/security_vm_fixup.c
Normal file
91
hypervisor/quirks/security_vm_fixup.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <types.h>
|
||||
#include <asm/vm_config.h>
|
||||
#include <asm/guest/vm.h>
|
||||
#include <vacpi.h>
|
||||
#include <logmsg.h>
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
12
hypervisor/quirks/security_vm_fixup.h
Normal file
12
hypervisor/quirks/security_vm_fixup.h
Normal file
@ -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_ */
|
@ -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"]
|
||||
|
||||
|
@ -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</xs:documentation>
|
||||
- ``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</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="" />
|
||||
@ -49,6 +50,7 @@
|
||||
<xs:enumeration value="GUEST_FLAG_HIDE_MTRR" />
|
||||
<xs:enumeration value="GUEST_FLAG_RT" />
|
||||
<xs:enumeration value="GUEST_FLAG_NVMX_ENABLED" />
|
||||
<xs:enumeration value="GUEST_FLAG_TPM2_FIXUP" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
||||
<xsl:when test="count(vm[vm_type='SOS_VM'])">
|
||||
<xsl:value-of select="acrn:comment('Bitmask of guest flags that can be programmed by device model. Other bits are set by hypervisor only.')" />
|
||||
<xsl:value-of select="$newline" />
|
||||
<xsl:value-of select="acrn:define('DM_OWNED_GUEST_FLAG_MASK', '(GUEST_FLAG_SECURE_WORLD_ENABLED | GUEST_FLAG_LAPIC_PASSTHROUGH | GUEST_FLAG_RT | GUEST_FLAG_IO_COMPLETION_POLLING)', '')" />
|
||||
<xsl:value-of select="acrn:define('DM_OWNED_GUEST_FLAG_MASK', '(GUEST_FLAG_SECURE_WORLD_ENABLED | GUEST_FLAG_LAPIC_PASSTHROUGH | GUEST_FLAG_RT | GUEST_FLAG_IO_COMPLETION_POLLING | GUEST_FLAG_TPM2_FIXUP)', '')" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="acrn:define('DM_OWNED_GUEST_FLAG_MASK', '0', 'UL')" />
|
||||
|
Loading…
Reference in New Issue
Block a user