diff --git a/hypervisor/arch/x86/configs/vacpi.c b/hypervisor/arch/x86/configs/vacpi.c index 05d7ca30b..08216acbb 100644 --- a/hypervisor/arch/x86/configs/vacpi.c +++ b/hypervisor/arch/x86/configs/vacpi.c @@ -94,6 +94,28 @@ static struct acpi_table_info acpi_table_template[CONFIG_MAX_VM_NUM] = { } }; +#ifdef VM0_PASSTHROUGH_TPM +static struct acpi_table_tpm2 tpm2 = { + .header = ACPI_TABLE_HEADER(ACPI_SIG_TPM2, sizeof(struct acpi_table_tpm2), 0x3U, ACPI_OEM_ID, + "ACRNTPM2", 0x1U, ACPI_ASL_COMPILER_ID, ACPI_ASL_COMPILER_VERSION), + .control_address = 0xFED40040UL, + .start_method = 0x7U, /* Uses the Command Response Buffer Interface */ +}; + +static uint8_t dsdt_data[45U] = { + // [.5TPM_ + 0x5B, 0x82, 0x35, 0x54, 0x50, 0x4D, 0x5F, + // ._HID.MSFT0101. + 0x08, 0x5F, 0x48, 0x49, 0x44, 0x0D, 0x4D, 0x53, 0x46, 0x54, 0x30, 0x31, 0x30, 0x31, 0x00, + // ._CRS + 0x08, 0x5F, 0x43, 0x52, 0x53, + 0x11, 0x11, 0x0A, 0x0E, 0x86, 0x09, 0x00, 0x01, 0x00, 0x00, 0xD4, 0xFE, 0x00, 0x50, 0x00, 0x00, + 0x79, 0x00 }; +#else +static struct acpi_table_tpm2 tpm2; +static uint8_t dsdt_data[0U]; +#endif + /** * @pre vm != NULL * @pre vm->vm_id < CONFIG_MAX_VM_NUM @@ -108,7 +130,8 @@ void build_vacpi(struct acrn_vm *vm) struct acpi_table_mcfg *mcfg; struct acpi_table_madt *madt; struct acpi_madt_local_apic *lapic; - uint16_t i; + uint16_t i, table_entry = 3U; + bool pt_tpm2_acpitable = get_vm_config(vm->vm_id)->pt_tpm2; rsdp = &acpi_table_template[vm->vm_id].rsdp; rsdp->checksum = calculate_checksum8(rsdp, ACPI_RSDP_CHECKSUM_LENGTH); @@ -124,8 +147,11 @@ void build_vacpi(struct acrn_vm *vm) xsdt->table_offset_entry[0] = ACPI_FADT_ADDR; xsdt->table_offset_entry[1] = ACPI_MCFG_ADDR; xsdt->table_offset_entry[2] = ACPI_MADT_ADDR; + if (pt_tpm2_acpitable) { + xsdt->table_offset_entry[table_entry++] = ACPI_TPM2_ADDR; + } /* Currently XSDT table only pointers to 3 ACPI table entry (FADT/MCFG/MADT) */ - xsdt->header.length = sizeof(struct acpi_table_header) + (3U * sizeof(uint64_t)); + xsdt->header.length = sizeof(struct acpi_table_header) + (table_entry * sizeof(uint64_t)); xsdt->header.checksum = calculate_checksum8(xsdt, xsdt->header.length); clac(); @@ -136,10 +162,19 @@ void build_vacpi(struct acrn_vm *vm) (void)copy_to_gpa(vm, fadp, ACPI_FADT_ADDR, fadp->header.length); dsdt = &acpi_table_template[vm->vm_id].dsdt; - dsdt->checksum = calculate_checksum8(dsdt, dsdt->length); /* Copy DSDT table and its subtables to guest physical memory */ (void)copy_to_gpa(vm, dsdt, ACPI_DSDT_ADDR, dsdt->length); + if (pt_tpm2_acpitable) { + (void)copy_to_gpa(vm, dsdt_data, ACPI_DSDT_ADDR + dsdt->length, sizeof(dsdt_data)); + } + dsdt = (struct acpi_table_header *)gpa2hva(vm, ACPI_DSDT_ADDR); + stac(); + if (pt_tpm2_acpitable) { + dsdt->length += sizeof(dsdt_data); + } + dsdt->checksum = calculate_checksum8(dsdt, dsdt->length); + clac(); mcfg = &acpi_table_template[vm->vm_id].mcfg; mcfg->header.length = sizeof(struct acpi_table_mcfg) @@ -164,4 +199,9 @@ void build_vacpi(struct acrn_vm *vm) /* Copy MADT table and its subtables to guest physical memory */ (void)copy_to_gpa(vm, madt, ACPI_MADT_ADDR, madt->header.length); + + if (pt_tpm2_acpitable) { + tpm2.header.checksum = calculate_checksum8(&tpm2, tpm2.header.length); + (void)copy_to_gpa(vm, &tpm2, ACPI_TPM2_ADDR, tpm2.header.length); + } } diff --git a/hypervisor/arch/x86/configs/whl-ipc-i5/misc_cfg.h b/hypervisor/arch/x86/configs/whl-ipc-i5/misc_cfg.h index f2af2dd4f..19cf1e9ea 100644 --- a/hypervisor/arch/x86/configs/whl-ipc-i5/misc_cfg.h +++ b/hypervisor/arch/x86/configs/whl-ipc-i5/misc_cfg.h @@ -33,5 +33,8 @@ #define HI_MMIO_START ~0UL #define HI_MMIO_END 0UL +#define VM0_PASSTHROUGH_TPM +#define VM0_TPM_BUFFER_BASE_ADDR 0xFED40000UL +#define VM0_TPM_BUFFER_SIZE 0x5000UL #endif /* MISC_CFG_H */ diff --git a/hypervisor/boot/include/acpi.h b/hypervisor/boot/include/acpi.h index 070d43a6a..f5e75f4d8 100644 --- a/hypervisor/boot/include/acpi.h +++ b/hypervisor/boot/include/acpi.h @@ -57,6 +57,7 @@ #define ACPI_SIG_DMAR "DMAR" #define ACPI_SIG_MCFG "MCFG" /* Memory Mapped Configuration table */ #define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */ +#define ACPI_SIG_TPM2 "TPM2" /* Trusted Platform Module hardware interface table */ struct packed_gas { uint8_t space_id; @@ -227,6 +228,14 @@ struct acpi_dmar_device_scope { uint8_t bus; } __packed; +struct acpi_table_tpm2 { + struct acpi_table_header header; + uint16_t platform_class; + uint16_t reserved; + uint64_t control_address; + uint32_t start_method; +} __packed; + void *get_acpi_tbl(const char *signature); struct ioapic_info; diff --git a/hypervisor/include/arch/x86/vm_config.h b/hypervisor/include/arch/x86/vm_config.h index 4f4f8df67..e3091c79e 100644 --- a/hypervisor/include/arch/x86/vm_config.h +++ b/hypervisor/include/arch/x86/vm_config.h @@ -178,6 +178,7 @@ struct acrn_vm_config { struct vuart_config vuart[MAX_VUART_NUM_PER_VM];/* vuart configuration for VM */ + bool pt_tpm2; struct acrn_mmiodev mmiodevs[MAX_MMIO_DEV_NUM]; } __aligned(8); diff --git a/hypervisor/include/dm/vacpi.h b/hypervisor/include/dm/vacpi.h index e0d7cfb79..646bee9df 100644 --- a/hypervisor/include/dm/vacpi.h +++ b/hypervisor/include/dm/vacpi.h @@ -47,6 +47,7 @@ #define ACPI_DSDT_ADDR (ACPI_BASE + 0x200U) #define ACPI_MCFG_ADDR (ACPI_BASE + 0x300U) #define ACPI_MADT_ADDR (ACPI_BASE + 0x340U) +#define ACPI_TPM2_ADDR (ACPI_BASE + 0x1000U) #define ACPI_OEM_ID "ACRN " #define ACPI_ASL_COMPILER_ID "INTL" diff --git a/hypervisor/scenarios/hybrid/vm_configurations.c b/hypervisor/scenarios/hybrid/vm_configurations.c index fbc0bda1e..322f9f986 100644 --- a/hypervisor/scenarios/hybrid/vm_configurations.c +++ b/hypervisor/scenarios/hybrid/vm_configurations.c @@ -37,7 +37,15 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = { .irq = COM2_IRQ, .t_vuart.vm_id = 1U, .t_vuart.vuart_id = 1U, - } + }, + #ifdef VM0_PASSTHROUGH_TPM + .pt_tpm2 = true, + .mmiodevs[0] = { + .base_gpa = VM0_TPM_BUFFER_BASE_ADDR, + .base_hpa = 0xFED40000UL, + .size = VM0_TPM_BUFFER_SIZE, + }, + #endif }, { /* VM1 */ CONFIG_SOS_VM,