add data structure in vm for enable trusty feature

add key info structure
add sworld_eptp in vm structure, and rename ept->nworld_eptp
add secure world control structure

Change-Id:
Tracked-On:220921
Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com>
This commit is contained in:
Mingqiang Chi 2018-03-05 15:09:30 +08:00 committed by Jack Ren
parent e91b6aa31a
commit cc1d532131
9 changed files with 166 additions and 19 deletions

View File

@ -134,7 +134,7 @@ void free_ept_mem(void *pml4_addr)
void destroy_ept(struct vm *vm)
{
free_ept_mem(vm->arch_vm.ept);
free_ept_mem(vm->arch_vm.nworld_eptp);
free_ept_mem(vm->arch_vm.m2p);
}
@ -147,7 +147,7 @@ uint64_t gpa2hpa_check(struct vm *vm, uint64_t gpa,
struct map_params map_params;
map_params.page_table_type = PT_EPT;
map_params.pml4_base = vm->arch_vm.ept;
map_params.pml4_base = vm->arch_vm.nworld_eptp;
map_params.pml4_inverted = vm->arch_vm.m2p;
obtain_last_page_table_entry(&map_params, &entry,
(void *)gpa, true);
@ -186,7 +186,7 @@ uint64_t hpa2gpa(struct vm *vm, uint64_t hpa)
struct map_params map_params;
map_params.page_table_type = PT_EPT;
map_params.pml4_base = vm->arch_vm.ept;
map_params.pml4_base = vm->arch_vm.nworld_eptp;
map_params.pml4_inverted = vm->arch_vm.m2p;
obtain_last_page_table_entry(&map_params, &entry,
@ -536,13 +536,13 @@ int ept_mmap(struct vm *vm, uint64_t hpa,
/* Setup memory map parameters */
map_params.page_table_type = PT_EPT;
if (vm->arch_vm.ept) {
map_params.pml4_base = vm->arch_vm.ept;
if (vm->arch_vm.nworld_eptp) {
map_params.pml4_base = vm->arch_vm.nworld_eptp;
map_params.pml4_inverted = vm->arch_vm.m2p;
} else {
map_params.pml4_base =
alloc_paging_struct();
vm->arch_vm.ept = map_params.pml4_base;
vm->arch_vm.nworld_eptp = map_params.pml4_base;
map_params.pml4_inverted = alloc_paging_struct();
vm->arch_vm.m2p = map_params.pml4_inverted;
}

View File

@ -132,8 +132,8 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
#endif
} else {
/* populate UOS vm fields according to vm_desc */
vm->secure_world_enabled =
vm_desc->secure_world_enabled;
vm->sworld_control.sworld_enabled =
vm_desc->sworld_enabled;
memcpy_s(&vm->GUID[0], sizeof(vm->GUID),
&vm_desc->GUID[0],
sizeof(vm_desc->GUID));

View File

@ -137,7 +137,8 @@ void mmu_invept(struct vcpu *vcpu)
struct invept_desc desc = {0};
if (check_invept_single_support()) {
desc.eptp = (uint64_t) vcpu->vm->arch_vm.ept | (3 << 3) | 6;
desc.eptp = (uint64_t) vcpu->vm->arch_vm.nworld_eptp
| (3 << 3) | 6;
_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc);
} else if (check_invept_global_support())
_invept(INVEPT_TYPE_ALL_CONTEXTS, desc);

View File

@ -983,7 +983,7 @@ static void init_exec_ctrl(struct vcpu *vcpu)
* TODO: introduce API to make this data driven based
* on VMX_EPT_VPID_CAP
*/
value64 = ((uint64_t) vm->arch_vm.ept) | (3 << 3) | 6;
value64 = ((uint64_t) vm->arch_vm.nworld_eptp) | (3 << 3) | 6;
exec_vmwrite64(VMX_EPT_POINTER_FULL, value64);
pr_dbg("VMX_EPT_POINTER: 0x%016llx ", value64);

View File

@ -159,7 +159,8 @@ int64_t hcall_create_vm(struct vm *vm, uint64_t param)
}
memset(&vm_desc, 0, sizeof(vm_desc));
vm_desc.secure_world_enabled = cv.secure_world_enabled;
vm_desc.sworld_enabled =
(!!(cv.vm_flag & (SECURE_WORLD_ENABLED)));
memcpy_s(&vm_desc.GUID[0], 16, &cv.GUID[0], 16);
ret = create_vm(&vm_desc, &target_vm);
@ -541,10 +542,10 @@ int64_t hcall_assign_ptdev(struct vm *vm, uint64_t vmid, uint64_t param)
/* create a iommu domain for target VM if not created */
if (!target_vm->iommu_domain) {
ASSERT(target_vm->arch_vm.ept, "EPT of VM not set!");
ASSERT(target_vm->arch_vm.nworld_eptp, "EPT of VM not set!");
/* TODO: how to get vm's address width? */
target_vm->iommu_domain = create_iommu_domain(vmid,
target_vm->arch_vm.ept, 48);
target_vm->arch_vm.nworld_eptp, 48);
ASSERT(target_vm->iommu_domain,
"failed to created iommu domain!");
}

View File

@ -109,7 +109,13 @@ struct vm_state_info {
struct vm_arch {
void *guest_pml4; /* Guest pml4 */
void *ept; /* EPT hierarchy */
/* EPT hierarchy for Normal World */
void *nworld_eptp;
/* EPT hierarchy for Secure World
* Secure world can access Normal World's memory,
* but Normal World can not access Secure World's memory.
*/
void *sworld_eptp;
void *m2p; /* machine address to guest physical address */
void *tmp_pg_array; /* Page array for tmp guest paging struct */
void *iobitmap[2];/* IO bitmap page array base address for this VM */
@ -160,7 +166,7 @@ struct vm {
spinlock_t ptdev_lock;
unsigned char GUID[16];
unsigned int secure_world_enabled;
struct secure_world_control sworld_control;
};
struct vm_description {
@ -178,7 +184,8 @@ struct vm_description {
bool vm_created;
/* Index indicating VM's privilege level */
unsigned int vm_state_info_privilege;
unsigned int secure_world_enabled; /* secure_world enabled? */
/* Whether secure world is enabled for current VM. */
bool sworld_enabled;
};
struct vm_description_array {

View File

@ -40,6 +40,7 @@
#include <msr.h>
#include <io.h>
#include <vcpu.h>
#include <trusty.h>
#include <vm.h>
#include <cpuid.h>
#include <mmu.h>

View File

@ -0,0 +1,132 @@
/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TRUSTY_H_
#define TRUSTY_H_
#define BOOTLOADER_SEED_MAX_ENTRIES 10
#define RPMB_MAX_PARTITION_NUMBER 6
#define MMC_PROD_NAME_WITH_PSN_LEN 15
#define BUP_MKHI_BOOTLOADER_SEED_LEN 64
/* Structure of seed info */
struct seed_info {
uint8_t cse_svn;
uint8_t bios_svn;
uint8_t padding[2];
uint8_t seed[BUP_MKHI_BOOTLOADER_SEED_LEN];
};
/* Structure of key info */
struct key_info {
uint32_t size_of_this_struct;
/* version info:
0: baseline structure
1: add ** new field
*/
uint32_t version;
/* platform:
0: Dummy (fake secret)
1: APL (APL + ABL)
2: ICL (ICL + SBL)
3: CWP (APL|ICL + SBL + CWP)
4: Brillo (Android Things)
*/
uint32_t platform;
/* flags info:
Bit 0: manufacturing state (0:manufacturing done;
1:in manufacturing mode)
Bit 1: secure boot state (0:disabled; 1: enabled)
Bit 2: test seeds (ICL only - 0:production seeds; 1: test seeds)
other bits all reserved as 0
*/
uint32_t flags;
/* Keep 64-bit align */
uint32_t pad1;
/* Seed list, include useeds(user seeds) and dseed(device seeds) */
uint32_t num_seeds;
struct seed_info useed_list[BOOTLOADER_SEED_MAX_ENTRIES];
struct seed_info dseed_list[BOOTLOADER_SEED_MAX_ENTRIES];
/* For ICL+ */
/* rpmb keys, Currently HMAC-SHA256 is used in RPMB spec
* and 256-bit (32byte) is enough. Hence only lower 32 bytes will be
* used for now for each entry. But keep higher 32 bytes for future
* extension. Note that, RPMB keys are already tied to storage device
* serial number.If there are multiple RPMB partitions, then we will
* get multiple available RPMB keys. And if rpmb_key[n][64] == 0,
* then the n-th RPMB key is unavailable (Either because of no such
* RPMB partition, or because OSloader doesn't want to share
* the n-th RPMB key with Trusty)
*/
uint8_t rpmb_key[RPMB_MAX_PARTITION_NUMBER][64];
/* 256-bit AES encryption key to encrypt/decrypt attestation keybox,
this key should be derived from a fixed key which is RPMB seed.
RPMB key (HMAC key) and this encryption key (AES key) are both
derived from the same RPMB seed.
*/
uint8_t attkb_enc_key[32];
/* For APL only */
/* RPMB key is derived with dseed together with this serial number,
* for ICL +, CSE directly provides the rpmb_key which is already
* tied to serial number. Concatenation of emmc product name
* with a string representation of PSN
*/
char serial[MMC_PROD_NAME_WITH_PSN_LEN];
char pad2;
};
struct secure_world_memory {
/* The secure world base address of GPA in SOS */
uint64_t base_gpa;
/* The secure world base address of HPA */
uint64_t base_hpa;
/* Secure world runtime memory size */
uint64_t length;
};
struct secure_world_control {
/* Whether secure world is enabled for current VM */
bool sworld_enabled;
/* key info structure */
struct key_info key_info;
/* Secure world memory structure */
struct secure_world_memory sworld_memory;
};
#endif /* TRUSTY_H_ */

View File

@ -63,6 +63,9 @@
#define REQUEST_READ 0
#define REQUEST_WRITE 1
/* Generic VM flags from guest OS */
#define SECURE_WORLD_ENABLED (1<<0) /* Whether secure world is enabled */
/**
* @brief Hypercall
*
@ -148,11 +151,13 @@ struct acrn_create_vm {
/** the GUID of this VM */
uint8_t GUID[16];
/** whether Secure World is enabled for this VM */
uint8_t secure_world_enabled;
/* VM flag bits from Guest OS, now used
* SECURE_WORLD_ENABLED (1<<0)
*/
uint64_t vm_flag;
/** Reserved for future use*/
uint8_t reserved[31];
uint8_t reserved[24];
} __aligned(8);
/**