mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-05 13:42:07 +00:00
dm: add RTCT v2 support for guest
The latest version of RTCT specification is version 2. This patch is to add RTCT v2 support for virtual RTCT of guest. Tracked-On: #6020 Signed-off-by: Yonghua Huang <yonghua.huang@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
parent
69808297b1
commit
d0426fd249
@ -1161,12 +1161,15 @@ static struct {
|
||||
int create_and_inject_vrtct(struct vmctx *ctx)
|
||||
{
|
||||
#define RTCT_NATIVE_FILE_PATH_IN_SOS "/sys/firmware/acpi/tables/PTCT"
|
||||
#define RTCT_V2_NATIVE_FILE_PATH_IN_SOS "/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[RTCT_BUF_LEN] = {0};
|
||||
uint8_t *buf;
|
||||
uint8_t *vrtct;
|
||||
struct vm_memmap memmap = {
|
||||
.type = VM_MMIO,
|
||||
@ -1176,14 +1179,19 @@ int create_and_inject_vrtct(struct vmctx *ctx)
|
||||
.prot = PROT_ALL
|
||||
};
|
||||
|
||||
/* Name of native RTCT table is "PTCT"(v1) or "RTCT"(v2) */
|
||||
native_rtct_fd = open(RTCT_NATIVE_FILE_PATH_IN_SOS, O_RDONLY);
|
||||
if (native_rtct_fd < 0) {
|
||||
pr_err("failed to open /sys/firmware/acpi/tables/PTCT !!!!! errno:%d\n", errno);
|
||||
return -1;
|
||||
native_rtct_fd = open(RTCT_V2_NATIVE_FILE_PATH_IN_SOS, 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);
|
||||
if (native_rtct_len > RTCT_BUF_LEN) {
|
||||
pr_err("%s native_rtct_len = %d large than RTCT_BUF_LEN\n", __func__, native_rtct_len);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1196,8 +1204,10 @@ int create_and_inject_vrtct(struct vmctx *ctx)
|
||||
close(native_rtct_fd);
|
||||
|
||||
vrtct = build_vrtct(ctx, (void *)buf);
|
||||
if (vrtct == NULL)
|
||||
if (vrtct == NULL) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
vrtct_len = ((struct acpi_table_hdr *)vrtct)->length;
|
||||
if (vrtct_len > RTCT_BUF_LEN) {
|
||||
@ -1205,6 +1215,7 @@ int create_and_inject_vrtct(struct vmctx *ctx)
|
||||
}
|
||||
memcpy(vm_map_gpa(ctx, ACPI_BASE + RTCT_OFFSET, vrtct_len), vrtct, vrtct_len);
|
||||
free(vrtct);
|
||||
free(buf);
|
||||
|
||||
memmap.hpa = get_software_sram_base_hpa();
|
||||
memmap.gpa = get_software_sram_base_gpa();
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include "log.h"
|
||||
#include "rtct.h"
|
||||
|
||||
#define RTCT_V1 1
|
||||
#define RTCT_V2 2
|
||||
|
||||
#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)
|
||||
@ -34,6 +37,8 @@
|
||||
e = (struct rtct_entry *)((uint64_t)e + e->size))
|
||||
|
||||
static uint16_t guest_vcpu_num;
|
||||
static uint32_t guest_l2_cat_shift;
|
||||
static uint32_t guest_l3_cat_shift;
|
||||
static uint32_t guest_lapicid_tbl[MAX_PLATFORM_LAPIC_IDS];
|
||||
|
||||
static uint64_t software_sram_base_hpa;
|
||||
@ -61,6 +66,25 @@ static inline void add_rtct_entry(struct acpi_table_hdr *rtct, struct rtct_entry
|
||||
rtct->length += e->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pass-through a native entry to virtual RTCT.
|
||||
*
|
||||
* @param vrtct Pointer to virtual RTCT.
|
||||
* @param entry Pointer to native RTCT entry.
|
||||
*
|
||||
* @return 0 on success and non-zero on fail.
|
||||
*/
|
||||
static int vrtct_passthru_native_entry(struct acpi_table_hdr *vrtct, struct rtct_entry *entry)
|
||||
{
|
||||
struct rtct_entry *rtct_entry;
|
||||
|
||||
rtct_entry = get_free_rtct_entry(vrtct);
|
||||
memcpy((void *)rtct_entry, (void *)entry, entry->size);
|
||||
|
||||
add_rtct_entry(vrtct, rtct_entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a new Software SRAM region entry to virtual RTCT.
|
||||
*
|
||||
@ -130,32 +154,50 @@ static int vrtct_add_mem_hierarchy_entry(struct acpi_table_hdr *vrtct, uint32_t
|
||||
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)
|
||||
static void remap_software_sram_regions(struct acpi_table_hdr *vrtct, int rtct_ver)
|
||||
{
|
||||
struct rtct_entry *entry;
|
||||
struct rtct_entry_data_ssram *sw_sram_region;
|
||||
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;
|
||||
|
||||
foreach_rtct_entry(vrtct, entry) {
|
||||
if (entry->type == RTCT_ENTRY_TYPE_SSRAM) {
|
||||
sw_sram_region = (struct rtct_entry_data_ssram *)entry->data;
|
||||
if (hpa_bottom > sw_sram_region->base) {
|
||||
hpa_bottom = sw_sram_region->base;
|
||||
}
|
||||
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 < sw_sram_region->base + sw_sram_region->size) {
|
||||
hpa_top = sw_sram_region->base + sw_sram_region->size;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,10 +206,19 @@ static void remap_software_sram_regions(struct acpi_table_hdr *vrtct)
|
||||
software_sram_base_hpa = hpa_bottom;
|
||||
software_sram_size = hpa_top - hpa_bottom;
|
||||
|
||||
foreach_rtct_entry(vrtct, entry) {
|
||||
if (entry->type == RTCT_ENTRY_TYPE_SSRAM) {
|
||||
sw_sram_region = (struct rtct_entry_data_ssram *)entry->data;
|
||||
sw_sram_region->base = software_sram_base_gpa + (sw_sram_region->base - 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 = software_sram_base_gpa + (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 = software_sram_base_gpa + (ssram_v2->base - hpa_bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,6 +241,31 @@ static bool is_pcpu_assigned_to_guest(uint32_t lapicid)
|
||||
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.
|
||||
@ -199,7 +275,7 @@ static bool is_pcpu_assigned_to_guest(uint32_t lapicid)
|
||||
*
|
||||
* @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)
|
||||
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;
|
||||
@ -240,7 +316,77 @@ static int passthru_rtct_to_guest(struct acpi_table_hdr *vrtct, struct acpi_tabl
|
||||
return -1;
|
||||
}
|
||||
|
||||
remap_software_sram_regions(vrtct);
|
||||
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;
|
||||
}
|
||||
@ -346,12 +492,17 @@ uint8_t *build_vrtct(struct vmctx *ctx, void *cfg)
|
||||
__func__, dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask);
|
||||
|
||||
guest_vcpu_num = bitmap_weight(guest_pcpu_bitmask);
|
||||
guest_l2_cat_shift = platform_info.l2_cat_shift;
|
||||
guest_l3_cat_shift = platform_info.l3_cat_shift;
|
||||
|
||||
if (init_guest_lapicid_tbl(&platform_info, guest_pcpu_bitmask) < 0) {
|
||||
pr_err("%s,init guest lapicid table fail.\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("%s, vcpu_num:%d, l2_shift:%d, l3_shift:%d.\n", __func__,
|
||||
guest_vcpu_num, guest_l2_cat_shift, guest_l3_cat_shift);
|
||||
|
||||
gpu_rsvmem_base_gpa = get_gpu_rsvmem_base_gpa();
|
||||
software_sram_size = SOFTWARE_SRAM_MAX_SIZE;
|
||||
/* TODO: It is better to put one boundary between GPU region and SW SRAM
|
||||
|
@ -17,6 +17,18 @@
|
||||
#define RTCT_ENTRY_TYPE_RT_IOMMU 8U
|
||||
#define RTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY 9U
|
||||
|
||||
/*Entry IDs for RTCT version 2*/
|
||||
#define RTCT_V2_COMPATIBILITY 0U
|
||||
#define RTCT_V2_RTCD_LIMIT 1U
|
||||
#define RTCT_V2_CRL_BINARY 2U
|
||||
#define RTCT_V2_IA_WAYMASK 3U
|
||||
#define RTCT_V2_WRC_WAYMASK 4U
|
||||
#define RTCT_V2_GT_WAYMASK 5U
|
||||
#define RTCT_V2_SSRAM_WAYMASK 6U
|
||||
#define RTCT_V2_SSRAM 7U
|
||||
#define RTCT_V2_MEMORY_HIERARCHY_LATENCY 8U
|
||||
#define RTCT_V2_ERROR_LOG_ADDRESS 9U
|
||||
|
||||
struct rtct_entry {
|
||||
uint16_t size;
|
||||
uint16_t format_version;
|
||||
@ -24,6 +36,13 @@ struct rtct_entry {
|
||||
uint32_t data[64];
|
||||
} __packed;
|
||||
|
||||
struct rtct_entry_data_compatibility {
|
||||
uint32_t RTCT_Ver_Major;
|
||||
uint32_t RTCT_Ver_Minor;
|
||||
uint32_t RTCD_Ver_Major;
|
||||
uint32_t RTCD_Ver_Minor;
|
||||
} __packed;
|
||||
|
||||
struct rtct_entry_data_ssram {
|
||||
uint32_t cache_level;
|
||||
uint64_t base;
|
||||
@ -32,6 +51,14 @@ struct rtct_entry_data_ssram {
|
||||
uint32_t apic_id_tbl[64];
|
||||
} __packed;
|
||||
|
||||
struct rtct_entry_data_ssram_v2 {
|
||||
uint32_t cache_level;
|
||||
uint32_t cache_id;
|
||||
uint64_t base;
|
||||
uint32_t size;
|
||||
uint32_t shared;
|
||||
} __packed;
|
||||
|
||||
struct rtct_entry_data_mem_hi_latency {
|
||||
uint32_t hierarchy;
|
||||
uint32_t clock_cycles;
|
||||
|
Loading…
Reference in New Issue
Block a user