hv: vapci: add tpm2 support for pre-launched vm

On WHL platform, we need to pass through TPM to Secure pre-launched VM. In order
to do this, we need to add TPM2 ACPI Table and add TPM DSDT ACPI table to include
the _CRS.

Now we only support the TPM 2.0 device (TPM 1.2 device is not support). Besides,
the TPM must use Start Method 7 (Uses the Command Response Buffer Interface)
to notify the TPM 2.0 device that a command is available for processing.

Tracked-On: #5053
Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
Li Fei1 2020-07-09 11:26:58 +08:00 committed by wenlingz
parent 7971f34344
commit 1859727abc
6 changed files with 66 additions and 4 deletions

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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"

View File

@ -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,