mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-28 08:16:54 +00:00
hv: pSRAM: temporarily remove NX bit of PTCM binary
Temporarily remove NX bit of PTCM binary in pagetable during pSRAM initialization: 1.added a function ppt_set_nx_bit to temporarily remove/restore the NX bit of a given area in pagetable. 2.Temporarily remove NX bit of PTCM binary during pSRAM initialization to make PTCM codes executable. 3. TODO: We may use SMP call to flush TLB and do pSRAM initilization on APs. Tracked-On: #5330 Signed-off-by: Qian Wang <qian1.wang@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
5fa816f921
commit
35abee60d6
@ -210,6 +210,21 @@ void hv_access_memory_region_update(uint64_t base, uint64_t size)
|
|||||||
round_pde_up(size_aligned), 0UL, PAGE_USER, &ppt_mem_ops, MR_MODIFY);
|
round_pde_up(size_aligned), 0UL, PAGE_USER, &ppt_mem_ops, MR_MODIFY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ppt_set_nx_bit(uint64_t base, uint64_t size, bool add)
|
||||||
|
{
|
||||||
|
uint64_t region_end = base + size;
|
||||||
|
uint64_t base_aligned = round_pde_down(base);
|
||||||
|
uint64_t size_aligned = round_pde_up(region_end - base_aligned);
|
||||||
|
|
||||||
|
if (add) {
|
||||||
|
mmu_modify_or_del((uint64_t *)ppt_mmu_pml4_addr,
|
||||||
|
base_aligned, size_aligned, PAGE_NX, 0UL, &ppt_mem_ops, MR_MODIFY);
|
||||||
|
} else {
|
||||||
|
mmu_modify_or_del((uint64_t *)ppt_mmu_pml4_addr,
|
||||||
|
base_aligned, size_aligned, 0UL, PAGE_NX, &ppt_mem_ops, MR_MODIFY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void init_paging(void)
|
void init_paging(void)
|
||||||
{
|
{
|
||||||
uint64_t hv_hva;
|
uint64_t hv_hva;
|
||||||
|
@ -23,6 +23,23 @@ static struct ptct_entry_data_ptcm_binary *ptcm_binary = NULL;
|
|||||||
|
|
||||||
static struct acpi_table_header *acpi_ptct_tbl = NULL;
|
static struct acpi_table_header *acpi_ptct_tbl = NULL;
|
||||||
|
|
||||||
|
static inline void ptcm_set_nx(bool add)
|
||||||
|
{
|
||||||
|
ppt_set_nx_bit((uint64_t)hpa2hva(ptcm_binary->address), ptcm_binary->size, add);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ptcm_flush_binary_tlb(void)
|
||||||
|
{
|
||||||
|
uint64_t linear_addr, start_addr = (uint64_t)hpa2hva(ptcm_binary->address);
|
||||||
|
uint64_t end_addr = start_addr + ptcm_binary->size;
|
||||||
|
|
||||||
|
for (linear_addr = start_addr; linear_addr < end_addr; linear_addr += PAGE_SIZE) {
|
||||||
|
invlpg(linear_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void *get_ptct_address()
|
static inline void *get_ptct_address()
|
||||||
{
|
{
|
||||||
return (void *)acpi_ptct_tbl + sizeof(*acpi_ptct_tbl);
|
return (void *)acpi_ptct_tbl + sizeof(*acpi_ptct_tbl);
|
||||||
@ -99,8 +116,11 @@ void init_psram(bool is_bsp)
|
|||||||
* That's why we add "!is_psram_initialized" as an condition.
|
* That's why we add "!is_psram_initialized" as an condition.
|
||||||
*/
|
*/
|
||||||
if (!is_psram_initialized && (acpi_ptct_tbl != NULL)) {
|
if (!is_psram_initialized && (acpi_ptct_tbl != NULL)) {
|
||||||
|
/* TODO: We may use SMP call to flush TLB and do pSRAM initilization on APs */
|
||||||
if (is_bsp) {
|
if (is_bsp) {
|
||||||
parse_ptct();
|
parse_ptct();
|
||||||
|
/* Clear the NX bit of PTCM area */
|
||||||
|
ptcm_set_nx(false);
|
||||||
bitmap_clear_lock(get_pcpu_id(), &init_psram_cpus_mask);
|
bitmap_clear_lock(get_pcpu_id(), &init_psram_cpus_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +131,8 @@ void init_psram(bool is_bsp)
|
|||||||
ptcm_binary->address, header->magic, header->version);
|
ptcm_binary->address, header->magic, header->version);
|
||||||
ASSERT(header->magic == PTCM_MAGIC, "Incorrect PTCM magic!");
|
ASSERT(header->magic == PTCM_MAGIC, "Incorrect PTCM magic!");
|
||||||
|
|
||||||
|
/* Flush the TLB, so that BSP/AP can execute the PTCM ABI */
|
||||||
|
ptcm_flush_binary_tlb();
|
||||||
ptcm_command_func = (ptcm_abi_func)(hpa2hva(ptcm_binary->address) + header->command_offset);
|
ptcm_command_func = (ptcm_abi_func)(hpa2hva(ptcm_binary->address) + header->command_offset);
|
||||||
pr_info("ptcm command function is found at %llx",ptcm_command_func);
|
pr_info("ptcm command function is found at %llx",ptcm_command_func);
|
||||||
ptcm_ret_code = ptcm_command_func(PTCM_CMD_INIT_PSRAM, get_ptct_address());
|
ptcm_ret_code = ptcm_command_func(PTCM_CMD_INIT_PSRAM, get_ptct_address());
|
||||||
@ -118,8 +140,15 @@ void init_psram(bool is_bsp)
|
|||||||
/* return 0 for success, -1 for failure */
|
/* return 0 for success, -1 for failure */
|
||||||
ASSERT(ptcm_ret_code == 0);
|
ASSERT(ptcm_ret_code == 0);
|
||||||
|
|
||||||
|
if (is_bsp) {
|
||||||
|
/* Restore the NX bit of PTCM area in page table */
|
||||||
|
ptcm_set_nx(true);
|
||||||
|
}
|
||||||
|
|
||||||
bitmap_set_lock(get_pcpu_id(), &init_psram_cpus_mask);
|
bitmap_set_lock(get_pcpu_id(), &init_psram_cpus_mask);
|
||||||
wait_sync_change(&init_psram_cpus_mask, ALL_CPUS_MASK);
|
wait_sync_change(&init_psram_cpus_mask, ALL_CPUS_MASK);
|
||||||
|
/* Flush the TLB on BSP and all APs to restore the NX for pSRAM area */
|
||||||
|
ptcm_flush_binary_tlb();
|
||||||
|
|
||||||
if (is_bsp) {
|
if (is_bsp) {
|
||||||
is_psram_initialized = true;
|
is_psram_initialized = true;
|
||||||
|
@ -114,6 +114,7 @@ void mmu_add(uint64_t *pml4_page, uint64_t paddr_base, uint64_t vaddr_base,
|
|||||||
void mmu_modify_or_del(uint64_t *pml4_page, uint64_t vaddr_base, uint64_t size,
|
void mmu_modify_or_del(uint64_t *pml4_page, uint64_t vaddr_base, uint64_t size,
|
||||||
uint64_t prot_set, uint64_t prot_clr, const struct memory_ops *mem_ops, uint32_t type);
|
uint64_t prot_set, uint64_t prot_clr, const struct memory_ops *mem_ops, uint32_t type);
|
||||||
void hv_access_memory_region_update(uint64_t base, uint64_t size);
|
void hv_access_memory_region_update(uint64_t base, uint64_t size);
|
||||||
|
void ppt_set_nx_bit(uint64_t base, uint64_t size, bool add);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Specified signle VPID flush
|
* @brief Specified signle VPID flush
|
||||||
@ -150,6 +151,11 @@ void flush_address_space(void *addr, uint64_t size);
|
|||||||
*/
|
*/
|
||||||
void invept(const void *eptp);
|
void invept(const void *eptp);
|
||||||
|
|
||||||
|
static inline void invlpg(unsigned long addr)
|
||||||
|
{
|
||||||
|
asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
static inline void cache_flush_invalidate_all(void)
|
static inline void cache_flush_invalidate_all(void)
|
||||||
{
|
{
|
||||||
asm volatile (" wbinvd\n" : : : "memory");
|
asm volatile (" wbinvd\n" : : : "memory");
|
||||||
|
Loading…
Reference in New Issue
Block a user