hv: remove hardcoding of SW SRAM HPA base

Physical address to SW SRAM region maybe different
 on different platforms, this hardcoded address may
 result in address mismatch for SW SRAM operations.

 This patch removes above hardcoded address and uses
 the physical address parsed from native RTCT.

Tracked-On: #5649
Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Yonghua Huang 2021-01-26 22:56:07 +08:00 committed by wenlingz
parent a6420e8cfa
commit a6e666dbe7
5 changed files with 56 additions and 45 deletions

View File

@ -174,48 +174,46 @@ void ept_flush_leaf_page(uint64_t *pge, uint64_t size)
uint64_t flush_base_hpa = INVALID_HPA, flush_end_hpa;
void *hva = NULL;
uint64_t flush_size = size;
uint64_t sw_sram_bottom, sw_sram_top;
if ((*pge & EPT_MT_MASK) != EPT_UNCACHED) {
flush_base_hpa = (*pge & (~(size - 1UL)));
flush_end_hpa = flush_base_hpa + size;
/* When Software SRAM is not initialized, both software_sram_area_bottom
* and software_sram_area_top is 0,
sw_sram_bottom = get_software_sram_base();
sw_sram_top = sw_sram_bottom + get_software_sram_size();
/* When Software SRAM is not initialized, both sw_sram_bottom and sw_sram_top is 0,
* so the below if/else will have no use
*/
if (flush_base_hpa < software_sram_area_bottom) {
/* Only flush [flush_base_hpa, software_sram_area_bottom)
* and [software_sram_area_top, flush_base_hpa),
* ignore [software_sram_area_bottom, software_sram_area_top)
if (flush_base_hpa < sw_sram_bottom) {
/* Only flush [flush_base_hpa, sw_sram_bottom) and [sw_sram_top, flush_base_hpa),
* ignore [sw_sram_bottom, sw_sram_top)
*/
if (flush_end_hpa > software_sram_area_top) {
/* Only flush [flush_base_hpa, software_sram_area_bottom)
* and [software_sram_area_top, flush_base_hpa),
* ignore [software_sram_area_bottom, software_sram_area_top)
if (flush_end_hpa > sw_sram_top) {
/* Only flush [flush_base_hpa, sw_sram_bottom) and [sw_sram_top, flush_base_hpa),
* ignore [sw_sram_bottom, sw_sram_top)
*/
flush_size = software_sram_area_bottom - flush_base_hpa;
flush_size = sw_sram_bottom - flush_base_hpa;
hva = hpa2hva(flush_base_hpa);
stac();
flush_address_space(hva, flush_size);
clac();
flush_size = flush_end_hpa - software_sram_area_top;
flush_base_hpa = software_sram_area_top;
} else if (flush_end_hpa > software_sram_area_bottom) {
/* Only flush [flush_base_hpa, software_sram_area_bottom) and
* ignore [software_sram_area_bottom, flush_end_hpa)
flush_size = flush_end_hpa - sw_sram_top;
flush_base_hpa = sw_sram_top;
} else if (flush_end_hpa > sw_sram_bottom) {
/* Only flush [flush_base_hpa, sw_sram_bottom)
* and ignore [sw_sram_bottom, flush_end_hpa)
*/
flush_size = software_sram_area_bottom - flush_base_hpa;
flush_size = sw_sram_bottom - flush_base_hpa;
}
} else if (flush_base_hpa < software_sram_area_top) {
if (flush_end_hpa <= software_sram_area_top) {
} else if (flush_base_hpa < sw_sram_top) {
if (flush_end_hpa <= sw_sram_top) {
flush_size = 0UL;
} else {
/* Only flush [software_sram_area_top, flush_end_hpa)
* and ignore [flush_base_hpa, software_sram_area_top)
*/
flush_base_hpa = software_sram_area_top;
flush_size = flush_end_hpa - software_sram_area_top;
/* Only flush [sw_sram_top, flush_end_hpa) and ignore [flush_base_hpa, sw_sram_top) */
flush_base_hpa = sw_sram_top;
flush_size = flush_end_hpa - sw_sram_top;
}
}

View File

@ -235,8 +235,8 @@ static void prepare_prelaunched_vm_memmap(struct acrn_vm *vm, const struct acrn_
((vm_config->guest_flags & GUEST_FLAG_RT) != 0U)){
/* pass through Software SRAM to pre-RTVM */
ept_add_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp,
SOFTWARE_SRAM_BASE_HPA, SOFTWARE_SRAM_BASE_GPA,
SOFTWARE_SRAM_MAX_SIZE, EPT_RWX | EPT_WB);
get_software_sram_base(), SOFTWARE_SRAM_BASE_GPA,
get_software_sram_size(), EPT_RWX | EPT_WB);
continue;
}
}

View File

@ -5,14 +5,15 @@
*/
#include <types.h>
#include <bits.h>
#include <rtl.h>
#include <logmsg.h>
#include <misc_cfg.h>
#include <mmu.h>
#include <rtcm.h>
uint64_t software_sram_area_bottom;
uint64_t software_sram_area_top;
static uint64_t software_sram_bottom_hpa;
static uint64_t software_sram_top_hpa;
/* is_sw_sram_initialized is used to tell whether Software SRAM is successfully initialized for all cores */
volatile bool is_sw_sram_initialized = false;
@ -39,7 +40,6 @@ static inline void rtcm_flush_binary_tlb(void)
}
static inline void *get_rtct_address()
{
return (void *)acpi_rtct_tbl + sizeof(*acpi_rtct_tbl);
@ -59,14 +59,14 @@ static void parse_rtct(void)
pr_info("found RTCT subtable in HPA %llx, length: %d", acpi_rtct_tbl, acpi_rtct_tbl->length);
entry = get_rtct_address();
software_sram_area_bottom = SOFTWARE_SRAM_BASE_HPA;
software_sram_bottom_hpa = ULONG_MAX;
while (((uint64_t)entry - (uint64_t)acpi_rtct_tbl) < acpi_rtct_tbl->length) {
switch (entry->type) {
case RTCT_ENTRY_TYPE_RTCM_BINARY:
rtcm_binary = (struct rtct_entry_data_rtcm_binary *)entry->data;
if (software_sram_area_top < rtcm_binary->address + rtcm_binary->size) {
software_sram_area_top = rtcm_binary->address + rtcm_binary->size;
if (software_sram_top_hpa < rtcm_binary->address + rtcm_binary->size) {
software_sram_top_hpa = rtcm_binary->address + rtcm_binary->size;
}
pr_info("found RTCM bin, in HPA %llx, size %llx",
rtcm_binary->address, rtcm_binary->size);
@ -74,8 +74,11 @@ static void parse_rtct(void)
case RTCT_ENTRY_TYPE_SOFTWARE_SRAM:
sw_sram_entry = (struct rtct_entry_data_software_sram *)entry->data;
if (software_sram_area_top < sw_sram_entry->base + sw_sram_entry->size) {
software_sram_area_top = sw_sram_entry->base + sw_sram_entry->size;
if (software_sram_top_hpa < sw_sram_entry->base + sw_sram_entry->size) {
software_sram_top_hpa = sw_sram_entry->base + sw_sram_entry->size;
}
if (software_sram_bottom_hpa > sw_sram_entry->base) {
software_sram_bottom_hpa = sw_sram_entry->base;
}
pr_info("found L%d Software SRAM, at HPA %llx, size %x", sw_sram_entry->cache_level,
sw_sram_entry->base, sw_sram_entry->size);
@ -87,7 +90,7 @@ static void parse_rtct(void)
/* point to next rtct entry */
entry = (struct rtct_entry *)((uint64_t)entry + entry->size);
}
software_sram_area_top = round_page_up(software_sram_area_top);
software_sram_top_hpa = round_page_up(software_sram_top_hpa);
} else {
pr_fatal("Cannot find RTCT pointer!!!!");
}
@ -153,7 +156,8 @@ void init_software_sram(bool is_bsp)
if (is_bsp) {
is_sw_sram_initialized = true;
pr_info("BSP Software SRAM has been initialized\n");
pr_info("BSP Software SRAM has been initialized, base_hpa:0x%lx, top_hpa:0x%lx.\n",
software_sram_bottom_hpa, software_sram_top_hpa);
}
}
}
@ -166,3 +170,13 @@ void init_software_sram(__unused bool is_bsp)
{
}
#endif
uint64_t get_software_sram_base(void)
{
return software_sram_bottom_hpa;
}
uint64_t get_software_sram_size(void)
{
return (software_sram_top_hpa - software_sram_bottom_hpa);
}

View File

@ -583,13 +583,15 @@ static int32_t add_vm_memory_region(struct acrn_vm *vm, struct acrn_vm *target_v
}
/* If Software SRAM is initialized, and HV received a request to map Software SRAM
* area to guest, we should add EPT_WB flag to make Software SRAM effective.
* Assumption: SOS must assign the Software SRAM area as a whole and as a separate memory
* region whose base address is SOFTWARE_SRAM_BASE_HPA
* TODO: We can enforce WB for any region has overlap with Software SRAM, for simplicity,
* and leave it to SOS to make sure it won't violate.
*/
if ((hpa == SOFTWARE_SRAM_BASE_HPA) && is_sw_sram_initialized) {
prot |= EPT_WB;
if (is_sw_sram_initialized) {
base_paddr = get_software_sram_base();
if ((hpa >= base_paddr) &&
((hpa + region->size) <= (base_paddr + get_software_sram_size()))) {
prot |= EPT_WB;
}
}
/* create gpa to hpa EPT mapping */
ept_add_mr(target_vm, pml4_page, hpa,

View File

@ -20,7 +20,6 @@
#define RTCT_ENTRY_TYPE_RT_IOMMU 8U
#define RTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY 9U
#define SOFTWARE_SRAM_BASE_HPA 0x40080000U
#define SOFTWARE_SRAM_BASE_GPA 0x40080000U
#define SOFTWARE_SRAM_MAX_SIZE 0x00800000U
@ -46,8 +45,6 @@ struct rtct_entry_data_software_sram
uint32_t apic_id_0; /*only the first core is responsible for initialization of L3 mem region*/
} __packed;
extern uint64_t software_sram_area_bottom;
extern uint64_t software_sram_area_top;
uint64_t get_software_sram_base(void);
uint64_t get_software_sram_size(void);
#endif /* RTCT_H */