mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-25 23:13:26 +00:00
dm: remove the dependency on native RTCT for vRTCT init
virtual RTCT will be created on TCC driver interface, instead of pass-through native RTCT to ACRN user VMs. this patch removes dependency on native RTCT table: - rename build_vrtct() function to init_ssram() and minor changes inside. - drop function create_and_inject_vrtct() - add one API to get virtual RTCT table. - rename variable 'pt_rtct' to 'ssram' Tracked-On: #7010 Signed-off-by: Yonghua Huang <yonghua.huang@intel.com> Acked-by: Wang Yu1 <yu1.wang@intel.com>
This commit is contained in:
parent
d9fb8f3141
commit
a4490c2ffb
@ -93,7 +93,7 @@ bool stdio_in_use;
|
|||||||
bool lapic_pt;
|
bool lapic_pt;
|
||||||
bool is_rtvm;
|
bool is_rtvm;
|
||||||
bool pt_tpm2;
|
bool pt_tpm2;
|
||||||
bool pt_rtct;
|
bool ssram;
|
||||||
bool vtpm2;
|
bool vtpm2;
|
||||||
bool is_winvm;
|
bool is_winvm;
|
||||||
bool skip_pci_mem64bar_workaround = false;
|
bool skip_pci_mem64bar_workaround = false;
|
||||||
@ -937,7 +937,7 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case CMD_OPT_SOFTWARE_SRAM:
|
case CMD_OPT_SOFTWARE_SRAM:
|
||||||
/* TODO: we need to support parameter to specify Software SRAM size in the future */
|
/* TODO: we need to support parameter to specify Software SRAM size in the future */
|
||||||
pt_rtct = true;
|
ssram = true;
|
||||||
break;
|
break;
|
||||||
case CMD_OPT_ACPIDEV_PT:
|
case CMD_OPT_ACPIDEV_PT:
|
||||||
/* FIXME: check acpi TPM device rules in acpi device famework init functions */
|
/* FIXME: check acpi TPM device rules in acpi device famework init functions */
|
||||||
|
@ -189,7 +189,7 @@ basl_fwrite_rsdt(FILE *fp, struct vmctx *ctx)
|
|||||||
EFPRINTF(fp, "[0004]\t\tACPI Table Address %u : %08X\n", num++,
|
EFPRINTF(fp, "[0004]\t\tACPI Table Address %u : %08X\n", num++,
|
||||||
basl_acpi_base + TPM2_OFFSET);
|
basl_acpi_base + TPM2_OFFSET);
|
||||||
|
|
||||||
if (pt_rtct) {
|
if (ssram) {
|
||||||
EFPRINTF(fp, "[0004]\t\tACPI Table Address %u : %08X\n", num++,
|
EFPRINTF(fp, "[0004]\t\tACPI Table Address %u : %08X\n", num++,
|
||||||
basl_acpi_base + RTCT_OFFSET);
|
basl_acpi_base + RTCT_OFFSET);
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ basl_fwrite_xsdt(FILE *fp, struct vmctx *ctx)
|
|||||||
EFPRINTF(fp, "[0004]\t\tACPI Table Address %u : 00000000%08X\n", num++,
|
EFPRINTF(fp, "[0004]\t\tACPI Table Address %u : 00000000%08X\n", num++,
|
||||||
basl_acpi_base + TPM2_OFFSET);
|
basl_acpi_base + TPM2_OFFSET);
|
||||||
|
|
||||||
if (pt_rtct) {
|
if (ssram) {
|
||||||
EFPRINTF(fp, "[0004]\t\tACPI Table Address %u : 00000000%08X\n", num++,
|
EFPRINTF(fp, "[0004]\t\tACPI Table Address %u : 00000000%08X\n", num++,
|
||||||
basl_acpi_base + RTCT_OFFSET);
|
basl_acpi_base + RTCT_OFFSET);
|
||||||
}
|
}
|
||||||
@ -1097,76 +1097,6 @@ static struct {
|
|||||||
{ basl_fwrite_dsdt, DSDT_OFFSET, true }
|
{ basl_fwrite_dsdt, DSDT_OFFSET, true }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* So far, only support passthrough native Software SRAM to single post-launched VM.
|
|
||||||
*/
|
|
||||||
int create_and_inject_vrtct(struct vmctx *ctx)
|
|
||||||
{
|
|
||||||
#define RTCT_NATIVE_FILE_PATH_IN_SERVICE_VM "/sys/firmware/acpi/tables/PTCT"
|
|
||||||
#define RTCT_V2_NATIVE_FILE_PATH_IN_SERVICE_VM "/sys/firmware/acpi/tables/RTCT"
|
|
||||||
|
|
||||||
|
|
||||||
#define RTCT_BUF_LEN 0x200 /* Otherwise, need to modify DSDT_OFFSET corresponding */
|
|
||||||
int native_rtct_fd;
|
|
||||||
int rc;
|
|
||||||
size_t native_rtct_len;
|
|
||||||
size_t vrtct_len;
|
|
||||||
uint8_t *buf;
|
|
||||||
uint8_t *vrtct;
|
|
||||||
struct acrn_vm_memmap memmap = {
|
|
||||||
.type = ACRN_MEMMAP_MMIO,
|
|
||||||
/* HPA base and size of Software SRAM shall be parsed from vRTCT. */
|
|
||||||
.service_vm_pa = 0,
|
|
||||||
.len = 0,
|
|
||||||
.attr = ACRN_MEM_ACCESS_RWX
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Name of native RTCT table is "PTCT"(v1) or "RTCT"(v2) */
|
|
||||||
native_rtct_fd = open(RTCT_NATIVE_FILE_PATH_IN_SERVICE_VM, O_RDONLY);
|
|
||||||
if (native_rtct_fd < 0) {
|
|
||||||
native_rtct_fd = open(RTCT_V2_NATIVE_FILE_PATH_IN_SERVICE_VM, O_RDONLY);
|
|
||||||
if (native_rtct_fd < 0) {
|
|
||||||
pr_err("RTCT file is NOT detected.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
native_rtct_len = lseek(native_rtct_fd, 0, SEEK_END);
|
|
||||||
buf = malloc(native_rtct_len);
|
|
||||||
if (buf == NULL) {
|
|
||||||
pr_err("%s failed to allocate buffer, native_rtct_len = %d\n", __func__, native_rtct_len);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)lseek(native_rtct_fd, 0, SEEK_SET);
|
|
||||||
rc = read(native_rtct_fd, buf, native_rtct_len);
|
|
||||||
if (rc < native_rtct_len) {
|
|
||||||
pr_err("Native RTCT is not fully read into buf!!!");
|
|
||||||
free(buf);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
close(native_rtct_fd);
|
|
||||||
|
|
||||||
vrtct = build_vrtct(ctx, (void *)buf);
|
|
||||||
if (vrtct == NULL) {
|
|
||||||
free(buf);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
vrtct_len = ((struct acpi_table_hdr *)vrtct)->length;
|
|
||||||
if (vrtct_len > RTCT_BUF_LEN) {
|
|
||||||
pr_err("Warning: Size of vRTCT (%d bytes) overflows, pls update DSDT_OFFSET.\n", vrtct_len);
|
|
||||||
}
|
|
||||||
memcpy(vm_map_gpa(ctx, ACPI_BASE + RTCT_OFFSET, vrtct_len), vrtct, vrtct_len);
|
|
||||||
free(vrtct);
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
memmap.service_vm_pa = get_software_sram_base_hpa();
|
|
||||||
memmap.user_vm_pa = get_vssram_gpa_base();
|
|
||||||
memmap.len = get_vssram_size();
|
|
||||||
ioctl(ctx->fd, ACRN_IOCTL_UNSET_MEMSEG, &memmap);
|
|
||||||
return ioctl(ctx->fd, ACRN_IOCTL_SET_MEMSEG, &memmap);
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
void
|
||||||
acpi_table_enable(int num)
|
acpi_table_enable(int num)
|
||||||
{
|
{
|
||||||
@ -1199,8 +1129,11 @@ get_acpi_table_length(void)
|
|||||||
int
|
int
|
||||||
acpi_build(struct vmctx *ctx, int ncpu)
|
acpi_build(struct vmctx *ctx, int ncpu)
|
||||||
{
|
{
|
||||||
|
#define RTCT_BUF_LEN 0x200
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
|
size_t vrtct_len;
|
||||||
|
uint8_t *vrtct;
|
||||||
|
|
||||||
basl_ncpu = ncpu;
|
basl_ncpu = ncpu;
|
||||||
|
|
||||||
@ -1237,8 +1170,19 @@ acpi_build(struct vmctx *ctx, int ncpu)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pt_rtct) {
|
if (ssram) {
|
||||||
create_and_inject_vrtct(ctx);
|
vrtct = get_vssram_vrtct();
|
||||||
|
if (vrtct == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vrtct_len = ((struct acpi_table_hdr *)vrtct)->length;
|
||||||
|
if (vrtct_len > RTCT_BUF_LEN) {
|
||||||
|
/* need to modify DSDT_OFFSET corresponding */
|
||||||
|
pr_err("Error: Size of vRTCT (%d bytes) overflows.\n", vrtct_len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(vm_map_gpa(ctx, ACPI_BASE + RTCT_OFFSET, vrtct_len), vrtct, vrtct_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -27,11 +27,6 @@
|
|||||||
#define RTCT_V2 2
|
#define RTCT_V2 2
|
||||||
|
|
||||||
#define RTCT_ENTRY_HEADER_SIZE 8
|
#define RTCT_ENTRY_HEADER_SIZE 8
|
||||||
#define RTCT_SSRAM_HEADER_SIZE (RTCT_ENTRY_HEADER_SIZE + 20)
|
|
||||||
#define RTCT_MEM_HI_HEADER_SIZE (RTCT_ENTRY_HEADER_SIZE + 8)
|
|
||||||
|
|
||||||
#define BITMASK(nr) (1U << nr)
|
|
||||||
|
|
||||||
#define foreach_rtct_entry(rtct, e) \
|
#define foreach_rtct_entry(rtct, e) \
|
||||||
for (e = (void *)rtct + sizeof(struct acpi_table_hdr); \
|
for (e = (void *)rtct + sizeof(struct acpi_table_hdr); \
|
||||||
((uint64_t)e - (uint64_t)rtct) < rtct->length; \
|
((uint64_t)e - (uint64_t)rtct) < rtct->length; \
|
||||||
@ -42,11 +37,11 @@ static uint32_t guest_l2_cat_shift;
|
|||||||
static uint32_t guest_l3_cat_shift;
|
static uint32_t guest_l3_cat_shift;
|
||||||
static uint32_t guest_lapicid_tbl[ACRN_PLATFORM_LAPIC_IDS_MAX];
|
static uint32_t guest_lapicid_tbl[ACRN_PLATFORM_LAPIC_IDS_MAX];
|
||||||
|
|
||||||
static uint64_t software_sram_base_hpa;
|
|
||||||
static uint64_t vssram_size;
|
static uint64_t vssram_size;
|
||||||
static uint64_t vssram_gpa_base;
|
static uint64_t vssram_gpa_base;
|
||||||
|
static struct acpi_table_hdr *vrtct_table;
|
||||||
|
|
||||||
static uint8_t vrtct_checksum(uint8_t *vrtct, uint32_t length)
|
uint8_t vrtct_checksum(uint8_t *vrtct, uint32_t length)
|
||||||
{
|
{
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
@ -75,7 +70,7 @@ static inline void add_rtct_entry(struct acpi_table_hdr *rtct, struct rtct_entry
|
|||||||
*
|
*
|
||||||
* @return 0 on success and non-zero on fail.
|
* @return 0 on success and non-zero on fail.
|
||||||
*/
|
*/
|
||||||
static int vrtct_passthru_native_entry(struct acpi_table_hdr *vrtct, struct rtct_entry *entry)
|
int vrtct_add_native_entry(struct acpi_table_hdr *vrtct, struct rtct_entry *entry)
|
||||||
{
|
{
|
||||||
struct rtct_entry *rtct_entry;
|
struct rtct_entry *rtct_entry;
|
||||||
|
|
||||||
@ -86,320 +81,6 @@ static int vrtct_passthru_native_entry(struct acpi_table_hdr *vrtct, struct rtct
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Add a new Software SRAM region entry to virtual RTCT.
|
|
||||||
*
|
|
||||||
* @param vrtct Pointer to virtual RTCT.
|
|
||||||
* @param cache_level Cache level of Software SRAM region.
|
|
||||||
* @param base Base address of Software SRAM region.
|
|
||||||
* @param ways Cache ways of Software SRAM region.
|
|
||||||
* @param size Size of Software SRAM region.
|
|
||||||
* @param vlapic_ids vLAIC ID table base address.
|
|
||||||
* @param vlapicid_num Entry number of vLAPIC ID table.
|
|
||||||
*
|
|
||||||
* @return 0 on success and non-zero on fail.
|
|
||||||
*/
|
|
||||||
static int vrtct_add_ssram_entry(struct acpi_table_hdr *vrtct, uint32_t cache_level, uint64_t base, uint32_t ways,
|
|
||||||
uint32_t size, uint32_t *vlapic_ids, uint32_t vlapicid_num)
|
|
||||||
{
|
|
||||||
struct rtct_entry *rtct_entry;
|
|
||||||
struct rtct_entry_data_ssram *sw_sram;
|
|
||||||
|
|
||||||
rtct_entry = get_free_rtct_entry(vrtct);
|
|
||||||
rtct_entry->format_version = 1;
|
|
||||||
rtct_entry->type = RTCT_ENTRY_TYPE_SSRAM;
|
|
||||||
|
|
||||||
sw_sram = (struct rtct_entry_data_ssram *)rtct_entry->data;
|
|
||||||
sw_sram->cache_level = cache_level;
|
|
||||||
sw_sram->base = base;
|
|
||||||
sw_sram->ways = ways;
|
|
||||||
sw_sram->size = size;
|
|
||||||
|
|
||||||
memcpy(sw_sram->apic_id_tbl, vlapic_ids, vlapicid_num * sizeof(uint32_t));
|
|
||||||
|
|
||||||
rtct_entry->size = RTCT_SSRAM_HEADER_SIZE + (vlapicid_num * sizeof(uint32_t));
|
|
||||||
add_rtct_entry(vrtct, rtct_entry);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Add a memory hierarchy entry to virtual RTCT.
|
|
||||||
*
|
|
||||||
* @param vrtct Pointer to virtual RTCT.
|
|
||||||
* @param hierarchy Memory hierarchy(2: cache level-2, 3:cache level-3, 256: the last level)
|
|
||||||
* @param clock_cycles Latency value of memory 'hierarchy'.
|
|
||||||
* @param vcpu_num Number of guest vCPU.
|
|
||||||
*
|
|
||||||
* @return 0 on success and non-zero on fail.
|
|
||||||
*/
|
|
||||||
static int vrtct_add_mem_hierarchy_entry(struct acpi_table_hdr *vrtct, uint32_t hierarchy, uint32_t clock_cycles)
|
|
||||||
{
|
|
||||||
uint32_t lapicid_tbl_sz;
|
|
||||||
struct rtct_entry *rtct_entry;
|
|
||||||
struct rtct_entry_data_mem_hi_latency *mem_hi;
|
|
||||||
|
|
||||||
rtct_entry = get_free_rtct_entry(vrtct);
|
|
||||||
rtct_entry->format_version = 1;
|
|
||||||
rtct_entry->type = RTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY;
|
|
||||||
|
|
||||||
mem_hi = (struct rtct_entry_data_mem_hi_latency *)rtct_entry->data;
|
|
||||||
mem_hi->hierarchy = hierarchy;
|
|
||||||
mem_hi->clock_cycles = clock_cycles;
|
|
||||||
|
|
||||||
lapicid_tbl_sz = guest_vcpu_num * sizeof(uint32_t);
|
|
||||||
memcpy(mem_hi->apic_id_tbl, guest_lapicid_tbl, lapicid_tbl_sz);
|
|
||||||
|
|
||||||
rtct_entry->size = RTCT_MEM_HI_HEADER_SIZE + lapicid_tbl_sz;
|
|
||||||
|
|
||||||
add_rtct_entry(vrtct, rtct_entry);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update the base address of Software SRAM regions in vRTCT from
|
|
||||||
* host physical address(HPA) to guest physical address(GPA).
|
|
||||||
*
|
|
||||||
* @param vrtct Pointer to virtual RTCT.
|
|
||||||
* @param rtct_ver version of virtual RTCT.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
static void remap_software_sram_regions(struct acpi_table_hdr *vrtct, int rtct_ver)
|
|
||||||
{
|
|
||||||
struct rtct_entry *entry;
|
|
||||||
struct rtct_entry_data_ssram *ssram;
|
|
||||||
struct rtct_entry_data_ssram_v2 *ssram_v2;
|
|
||||||
uint64_t hpa_bottom, hpa_top;
|
|
||||||
|
|
||||||
hpa_bottom = (uint64_t)-1;
|
|
||||||
hpa_top = 0;
|
|
||||||
|
|
||||||
if (rtct_ver == RTCT_V1) {
|
|
||||||
foreach_rtct_entry(vrtct, entry) {
|
|
||||||
if (entry->type == RTCT_ENTRY_TYPE_SSRAM) {
|
|
||||||
ssram = (struct rtct_entry_data_ssram *)entry->data;
|
|
||||||
if (hpa_bottom > ssram->base) {
|
|
||||||
hpa_bottom = ssram->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hpa_top < ssram->base + ssram->size) {
|
|
||||||
hpa_top = ssram->base + ssram->size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (rtct_ver == RTCT_V2) {
|
|
||||||
foreach_rtct_entry(vrtct, entry) {
|
|
||||||
if (entry->type == RTCT_V2_SSRAM) {
|
|
||||||
ssram_v2 = (struct rtct_entry_data_ssram_v2 *)entry->data;
|
|
||||||
if (hpa_bottom > ssram_v2->base) {
|
|
||||||
hpa_bottom = ssram_v2->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hpa_top < ssram_v2->base + ssram_v2->size) {
|
|
||||||
hpa_top = ssram_v2->base + ssram_v2->size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pr_info("%s, hpa_bottom:%lx, hpa_top:%lx.\n", __func__, hpa_bottom, hpa_top);
|
|
||||||
|
|
||||||
if (((hpa_bottom & ~PAGE_MASK) != 0) || ((hpa_top & ~PAGE_MASK) != 0)) {
|
|
||||||
pr_warn("%s, Warning: hpa_bottom:%lx OR hpa_top:%lx is not page-aligned!\n",
|
|
||||||
__func__, hpa_bottom, hpa_top);
|
|
||||||
|
|
||||||
hpa_bottom &= PAGE_MASK;
|
|
||||||
hpa_top &= PAGE_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
software_sram_base_hpa = hpa_bottom;
|
|
||||||
vssram_size = hpa_top - hpa_bottom;
|
|
||||||
|
|
||||||
if (rtct_ver == RTCT_V1) {
|
|
||||||
foreach_rtct_entry(vrtct, entry) {
|
|
||||||
if (entry->type == RTCT_ENTRY_TYPE_SSRAM) {
|
|
||||||
ssram = (struct rtct_entry_data_ssram *)entry->data;
|
|
||||||
ssram->base = vssram_gpa_base + (ssram->base - hpa_bottom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (rtct_ver == RTCT_V2) {
|
|
||||||
foreach_rtct_entry(vrtct, entry) {
|
|
||||||
if (entry->type == RTCT_V2_SSRAM) {
|
|
||||||
ssram_v2 = (struct rtct_entry_data_ssram_v2 *)entry->data;
|
|
||||||
ssram_v2->base = vssram_gpa_base + (ssram_v2->base - hpa_bottom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if a given pCPU is assigned to current guest.
|
|
||||||
*
|
|
||||||
* @param lapicid Physical LAPIC ID of pCPU.
|
|
||||||
*
|
|
||||||
* @return true if given pCPU is assigned to current guest, else false.
|
|
||||||
*/
|
|
||||||
static bool is_pcpu_assigned_to_guest(uint32_t lapicid)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < guest_vcpu_num; i++) {
|
|
||||||
if (lapicid == guest_lapicid_tbl[i])
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if a given cache is accessible to current guest.
|
|
||||||
*
|
|
||||||
* @param cache_id Physical cache ID.
|
|
||||||
* @param cache_level Cache Level, 2 or 3.
|
|
||||||
*
|
|
||||||
* @return true if given cache is accessible to current guest, else false.
|
|
||||||
*/
|
|
||||||
static bool is_cache_accessible_to_guest(uint32_t cache_id, uint32_t cache_level)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint32_t shift[2];
|
|
||||||
|
|
||||||
if ((cache_level != 2) && (cache_level != 3))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
shift[0] = guest_l2_cat_shift;
|
|
||||||
shift[1] = guest_l3_cat_shift;
|
|
||||||
for (i = 0; i < guest_vcpu_num; i++) {
|
|
||||||
if ((guest_lapicid_tbl[i] >> shift[cache_level - 2]) == cache_id)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize Software SRAM and memory hierarchy entries in virtual RTCT,
|
|
||||||
* configurations of these entries are from native RTCT.
|
|
||||||
*
|
|
||||||
* @param vrtct Pointer to virtual RTCT.
|
|
||||||
* @param native_rtct Pointer to native RTCT.
|
|
||||||
*
|
|
||||||
* @return 0 on success and non-zero on fail.
|
|
||||||
*/
|
|
||||||
static int init_vrtct_v1(struct acpi_table_hdr *vrtct, struct acpi_table_hdr *native_rtct)
|
|
||||||
{
|
|
||||||
int i, plapic_num, vlapic_num, rc = 0;
|
|
||||||
struct rtct_entry *entry;
|
|
||||||
struct rtct_entry_data_ssram *ssram;
|
|
||||||
struct rtct_entry_data_mem_hi_latency *mem_hi;
|
|
||||||
uint32_t lapicids[ACRN_PLATFORM_LAPIC_IDS_MAX];
|
|
||||||
|
|
||||||
foreach_rtct_entry(native_rtct, entry) {
|
|
||||||
if (entry->type == RTCT_ENTRY_TYPE_SSRAM) {
|
|
||||||
/* Get native CPUs of Software SRAM region */
|
|
||||||
plapic_num = (entry->size - RTCT_SSRAM_HEADER_SIZE) / sizeof(uint32_t);
|
|
||||||
ssram = (struct rtct_entry_data_ssram *)entry->data;
|
|
||||||
|
|
||||||
memset(lapicids, 0, sizeof(lapicids[ACRN_PLATFORM_LAPIC_IDS_MAX]));
|
|
||||||
vlapic_num = 0;
|
|
||||||
for (i = 0; i < plapic_num; i++) {
|
|
||||||
if (is_pcpu_assigned_to_guest(ssram->apic_id_tbl[i])) {
|
|
||||||
lapicids[vlapic_num++] = ssram->apic_id_tbl[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vlapic_num > 0) {
|
|
||||||
/*
|
|
||||||
* argument 'base' is set to HPA(ssram->base) in passthru RTCT
|
|
||||||
* soluation as it is required to calculate Software SRAM regions range
|
|
||||||
* in host physical address space, this 'base' will be updated to
|
|
||||||
* GPA when mapping all Software SRAM regions from HPA to GPA.
|
|
||||||
*/
|
|
||||||
rc = vrtct_add_ssram_entry(vrtct, ssram->cache_level, ssram->base,
|
|
||||||
ssram->ways, ssram->size, lapicids, vlapic_num);
|
|
||||||
}
|
|
||||||
} else if (entry->type == RTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY) {
|
|
||||||
mem_hi = (struct rtct_entry_data_mem_hi_latency *)entry->data;
|
|
||||||
rc = vrtct_add_mem_hierarchy_entry(vrtct, mem_hi->hierarchy, mem_hi->clock_cycles);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize Software SRAM and memory hierarchy entries in virtual RTCT,
|
|
||||||
* configurations of these entries are from native RTCT.
|
|
||||||
*
|
|
||||||
* @param vrtct Pointer to virtual RTCT.
|
|
||||||
* @param native_rtct Pointer to native RTCT.
|
|
||||||
*
|
|
||||||
* @return 0 on success and non-zero on fail.
|
|
||||||
*/
|
|
||||||
static int init_vrtct_v2(struct acpi_table_hdr *vrtct, struct acpi_table_hdr *native_rtct)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct rtct_entry *entry;
|
|
||||||
struct rtct_entry_data_ssram_v2 *ssram_v2;
|
|
||||||
|
|
||||||
foreach_rtct_entry(native_rtct, entry) {
|
|
||||||
if ((entry->type == RTCT_V2_COMPATIBILITY) ||
|
|
||||||
(entry->type == RTCT_V2_MEMORY_HIERARCHY_LATENCY)) {
|
|
||||||
rc = vrtct_passthru_native_entry(vrtct, entry);
|
|
||||||
} else if (entry->type == RTCT_V2_SSRAM) {
|
|
||||||
ssram_v2 = (struct rtct_entry_data_ssram_v2 *)entry->data;
|
|
||||||
if (is_cache_accessible_to_guest(ssram_v2->cache_id, ssram_v2->cache_level)) {
|
|
||||||
rc = vrtct_passthru_native_entry(vrtct, entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize Software SRAM and memory hierarchy entries in virtual RTCT,
|
|
||||||
* configurations of these entries are from native RTCT.
|
|
||||||
*
|
|
||||||
* @param vrtct Pointer to virtual RTCT.
|
|
||||||
* @param native_rtct Pointer to native RTCT.
|
|
||||||
*
|
|
||||||
* @return 0 on success and non-zero on fail.
|
|
||||||
*/
|
|
||||||
static int passthru_rtct_to_guest(struct acpi_table_hdr *vrtct, struct acpi_table_hdr *native_rtct)
|
|
||||||
{
|
|
||||||
int rtct_ver = RTCT_V1, rc = -1;
|
|
||||||
struct rtct_entry *entry;
|
|
||||||
struct rtct_entry_data_compatibility *compat;
|
|
||||||
|
|
||||||
/* get native RTCT version. */
|
|
||||||
foreach_rtct_entry(native_rtct, entry) {
|
|
||||||
if (entry->type == RTCT_V2_COMPATIBILITY) {
|
|
||||||
compat = (struct rtct_entry_data_compatibility *)entry->data;
|
|
||||||
rtct_ver = compat->rtct_ver_major;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("%s, Native RTCT version:%d.\n", __func__, rtct_ver);
|
|
||||||
|
|
||||||
if (rtct_ver == RTCT_V1) {
|
|
||||||
rc = init_vrtct_v1(vrtct, native_rtct);
|
|
||||||
} else if (rtct_ver == RTCT_V2) {
|
|
||||||
rc = init_vrtct_v2(vrtct, native_rtct);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
remap_software_sram_regions(vrtct, rtct_ver);
|
|
||||||
vrtct->checksum = vrtct_checksum((uint8_t *)vrtct, vrtct->length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int init_guest_lapicid_tbl(struct acrn_platform_info *platform_info, uint64_t guest_pcpu_bitmask)
|
static int init_guest_lapicid_tbl(struct acrn_platform_info *platform_info, uint64_t guest_pcpu_bitmask)
|
||||||
{
|
{
|
||||||
int pcpu_id = 0, vcpu_id = 0;
|
int pcpu_id = 0, vcpu_id = 0;
|
||||||
@ -414,16 +95,9 @@ static int init_guest_lapicid_tbl(struct acrn_platform_info *platform_info, uint
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @pre buid_vrtct(ctx, cfg) != NULL
|
|
||||||
*/
|
|
||||||
uint64_t get_software_sram_base_hpa(void)
|
|
||||||
{
|
|
||||||
return software_sram_base_hpa;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @pre buid_vrtct(ctx, cfg) != NULL
|
* @pre init_vssram(ctx) == 0
|
||||||
*/
|
*/
|
||||||
uint64_t get_vssram_gpa_base(void)
|
uint64_t get_vssram_gpa_base(void)
|
||||||
{
|
{
|
||||||
@ -431,44 +105,36 @@ uint64_t get_vssram_gpa_base(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @pre buid_vrtct(ctx, cfg) != NULL
|
* @pre init_vssram(ctx) == 0
|
||||||
*/
|
*/
|
||||||
uint64_t get_vssram_size(void)
|
uint64_t get_vssram_size(void)
|
||||||
{
|
{
|
||||||
return vssram_size;
|
return vssram_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* @brief Initialize virtual RTCT based on configurations from native RTCT in Service VM.
|
* @pre init_vssram(ctx) == 0
|
||||||
*
|
|
||||||
* @param ctx Pointer to context of guest.
|
|
||||||
* @param cfg Pointer to configuration data, it pointers to native RTCT in passthru RTCT solution.
|
|
||||||
*
|
|
||||||
* @return Pointer to virtual RTCT data on success and NULL on fail.
|
|
||||||
*/
|
*/
|
||||||
uint8_t *build_vrtct(struct vmctx *ctx, void *cfg)
|
uint8_t *get_vssram_vrtct(void)
|
||||||
|
{
|
||||||
|
return (uint8_t *)vrtct_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize software SRAM device for user VM.
|
||||||
|
*
|
||||||
|
* @param ctx Pointer to context of user VM.
|
||||||
|
*
|
||||||
|
* @return 0 on success and -1 on fail.
|
||||||
|
*/
|
||||||
|
int init_vssram(struct vmctx *ctx)
|
||||||
{
|
{
|
||||||
#define PTCT_BUF_SIZE 4096
|
#define PTCT_BUF_SIZE 4096
|
||||||
struct acrn_vm_config_header vm_cfg;
|
struct acrn_vm_config_header vm_cfg;
|
||||||
struct acpi_table_hdr *rtct_cfg, *vrtct = NULL;
|
|
||||||
uint64_t dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask;
|
uint64_t dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask;
|
||||||
uint32_t gpu_rsvmem_base_gpa = 0;
|
uint32_t gpu_rsvmem_base_gpa = 0;
|
||||||
struct acrn_platform_info platform_info;
|
struct acrn_platform_info platform_info;
|
||||||
|
|
||||||
if ((cfg == NULL) || (ctx == NULL))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rtct_cfg = (struct acpi_table_hdr *)cfg;
|
|
||||||
vrtct = malloc(PTCT_BUF_SIZE);
|
|
||||||
if (vrtct == NULL) {
|
|
||||||
pr_err("%s, Failed to allocate vRTCT buffer.\n", __func__);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy((void *)vrtct, (void *)rtct_cfg, sizeof(struct acpi_table_hdr));
|
|
||||||
vrtct->length = sizeof(struct acpi_table_hdr);
|
|
||||||
vrtct->checksum = 0;
|
|
||||||
|
|
||||||
if (vm_get_config(ctx, &vm_cfg, &platform_info)) {
|
if (vm_get_config(ctx, &vm_cfg, &platform_info)) {
|
||||||
pr_err("%s, get VM configuration fail.\n", __func__);
|
pr_err("%s, get VM configuration fail.\n", __func__);
|
||||||
goto error;
|
goto error;
|
||||||
@ -501,9 +167,6 @@ uint8_t *build_vrtct(struct vmctx *ctx, void *cfg)
|
|||||||
__func__, dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask);
|
__func__, dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask);
|
||||||
|
|
||||||
guest_vcpu_num = bitmap_weight(guest_pcpu_bitmask);
|
guest_vcpu_num = bitmap_weight(guest_pcpu_bitmask);
|
||||||
guest_l2_cat_shift = platform_info.hw.l2_cat_shift;
|
|
||||||
guest_l3_cat_shift = platform_info.hw.l3_cat_shift;
|
|
||||||
|
|
||||||
if (init_guest_lapicid_tbl(&platform_info, guest_pcpu_bitmask) < 0) {
|
if (init_guest_lapicid_tbl(&platform_info, guest_pcpu_bitmask) < 0) {
|
||||||
pr_err("%s,init guest lapicid table fail.\n", __func__);
|
pr_err("%s,init guest lapicid table fail.\n", __func__);
|
||||||
goto error;
|
goto error;
|
||||||
@ -520,13 +183,7 @@ uint8_t *build_vrtct(struct vmctx *ctx, void *cfg)
|
|||||||
vssram_gpa_base = ((gpu_rsvmem_base_gpa ? gpu_rsvmem_base_gpa : 0x80000000UL) -
|
vssram_gpa_base = ((gpu_rsvmem_base_gpa ? gpu_rsvmem_base_gpa : 0x80000000UL) -
|
||||||
vssram_size) & ~vssram_size;
|
vssram_size) & ~vssram_size;
|
||||||
|
|
||||||
if (passthru_rtct_to_guest(vrtct, rtct_cfg)) {
|
return 0;
|
||||||
pr_err("%s, initialize vRTCT fail.", __func__);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint8_t *)vrtct;
|
|
||||||
error:
|
error:
|
||||||
free(vrtct);
|
return -1;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ extern char *mac_seed;
|
|||||||
extern bool lapic_pt;
|
extern bool lapic_pt;
|
||||||
extern bool is_rtvm;
|
extern bool is_rtvm;
|
||||||
extern bool pt_tpm2;
|
extern bool pt_tpm2;
|
||||||
extern bool pt_rtct;
|
extern bool ssram;
|
||||||
extern bool vtpm2;
|
extern bool vtpm2;
|
||||||
extern bool is_winvm;
|
extern bool is_winvm;
|
||||||
|
|
||||||
|
@ -7,16 +7,6 @@
|
|||||||
#ifndef RTCT_H
|
#ifndef RTCT_H
|
||||||
#define RTCT_H
|
#define RTCT_H
|
||||||
|
|
||||||
#define RTCT_ENTRY_TYPE_PTCD_LIMIT 1U
|
|
||||||
#define RTCT_ENTRY_TYPE_PTCM_BINARY 2U
|
|
||||||
#define RTCT_ENTRY_TYPE_WRC_L3_MASKS 3U
|
|
||||||
#define RTCT_ENTRY_TYPE_GT_L3_MASKS 4U
|
|
||||||
#define RTCT_ENTRY_TYPE_SSRAM 5U
|
|
||||||
#define RTCT_ENTRY_TYPE_STREAM_DATAPATH 6U
|
|
||||||
#define RTCT_ENTRY_TYPE_TIMEAWARE_SUBSYS 7U
|
|
||||||
#define RTCT_ENTRY_TYPE_RT_IOMMU 8U
|
|
||||||
#define RTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY 9U
|
|
||||||
|
|
||||||
/*Entry IDs for RTCT version 2*/
|
/*Entry IDs for RTCT version 2*/
|
||||||
#define RTCT_V2_COMPATIBILITY 0U
|
#define RTCT_V2_COMPATIBILITY 0U
|
||||||
#define RTCT_V2_RTCD_LIMIT 1U
|
#define RTCT_V2_RTCD_LIMIT 1U
|
||||||
@ -43,14 +33,6 @@ struct rtct_entry_data_compatibility {
|
|||||||
uint32_t rtcd_ver_Minor;
|
uint32_t rtcd_ver_Minor;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct rtct_entry_data_ssram {
|
|
||||||
uint32_t cache_level;
|
|
||||||
uint64_t base;
|
|
||||||
uint32_t ways;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t apic_id_tbl[64];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct rtct_entry_data_ssram_v2 {
|
struct rtct_entry_data_ssram_v2 {
|
||||||
uint32_t cache_level;
|
uint32_t cache_level;
|
||||||
uint32_t cache_id;
|
uint32_t cache_id;
|
||||||
@ -59,15 +41,9 @@ struct rtct_entry_data_ssram_v2 {
|
|||||||
uint32_t shared;
|
uint32_t shared;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct rtct_entry_data_mem_hi_latency {
|
|
||||||
uint32_t hierarchy;
|
|
||||||
uint32_t clock_cycles;
|
|
||||||
uint32_t apic_id_tbl[64];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
uint64_t get_vssram_gpa_base(void);
|
uint64_t get_vssram_gpa_base(void);
|
||||||
uint64_t get_software_sram_base_hpa(void);
|
|
||||||
uint64_t get_vssram_size(void);
|
uint64_t get_vssram_size(void);
|
||||||
uint8_t *build_vrtct(struct vmctx *ctx, void *cfg);
|
uint8_t *get_vssram_vrtct(void);
|
||||||
|
int init_vssram(struct vmctx *ctx);
|
||||||
|
|
||||||
#endif /* RTCT_H */
|
#endif /* RTCT_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user