mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-11-14 10:31:59 +00:00
Add arch_hva2hpa_early/arch_hpa2hva_early to common, and wrap it in hva2hpa_early/hpa2hva_early. Tracked-On: #8831 Signed-off-by: hangliu1 <hang1.liu@intel.com> Reviewed-by: Liu, Yifan1 <yifan1.liu@intel.com> Acked-by: Wang, Yu1 <yu1.wang@intel.com>
277 lines
8.1 KiB
C
277 lines
8.1 KiB
C
/*
|
|
* Copyright (C) 2018-2025 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*
|
|
*/
|
|
|
|
#ifndef COMMON_PGTABLE_H
|
|
#define COMMON_PGTABLE_H
|
|
#include <asm/page.h>
|
|
#include <asm/mm_common.h>
|
|
|
|
uint64_t arch_pgtl_page_paddr(uint64_t pgtle);
|
|
uint64_t arch_pgtl_large(uint64_t pgtle);
|
|
void *arch_hpa2hva_early(uint64_t x);
|
|
uint64_t arch_hva2hpa_early(void *x);
|
|
|
|
/**
|
|
* @brief Translate a host physical address to a host virtual address.
|
|
*
|
|
* This function is used to translate a host physical address to a host virtual address. HPA is 1:1 mapping to HVA.
|
|
*
|
|
* It returns the host virtual address that corresponds to the given host physical address.
|
|
*
|
|
* @param[in] hpa The host physical address to be translated.
|
|
*
|
|
* @return The translated host virtual address
|
|
*
|
|
* @retval NULL if hpa == 0
|
|
*
|
|
* @pre N/A
|
|
*
|
|
* @post N/A
|
|
*
|
|
* @remark This function is used after paging mode enabled.
|
|
*/
|
|
static inline void *hpa2hva(uint64_t hpa)
|
|
{
|
|
return (void *)hpa;
|
|
}
|
|
|
|
/**
|
|
* @brief Translate a host virtual address to a host physical address.
|
|
*
|
|
* This function is used to translate a host virtual address to a host physical address. HVA is 1:1 mapping to HPA.
|
|
*
|
|
* It returns the host physical address that corresponds to the given host virtual address.
|
|
*
|
|
* @param[in] va The host virtual address to be translated.
|
|
*
|
|
* @return The translated host physical address.
|
|
*
|
|
* @retval 0 if va == NULL
|
|
*
|
|
* @pre N/A
|
|
*
|
|
* @post N/A
|
|
*
|
|
* @remark This function is used after paging mode enabled.
|
|
*/
|
|
static inline uint64_t hva2hpa(const void *va)
|
|
{
|
|
return (uint64_t)va;
|
|
}
|
|
|
|
static inline uint64_t round_page_up(uint64_t addr)
|
|
{
|
|
return (((addr + (uint64_t)PAGE_SIZE) - 1UL) & PAGE_MASK);
|
|
}
|
|
|
|
static inline uint64_t round_page_down(uint64_t addr)
|
|
{
|
|
return (addr & PAGE_MASK);
|
|
}
|
|
|
|
static inline uint64_t pgtl3e_index(uint64_t address)
|
|
{
|
|
return (address >> PGTL3_SHIFT) & (PTRS_PER_PGTL3E - 1UL);
|
|
}
|
|
|
|
static inline uint64_t pgtl2e_index(uint64_t address)
|
|
{
|
|
return (address >> PGTL2_SHIFT) & (PTRS_PER_PGTL2E- 1UL);
|
|
}
|
|
|
|
static inline uint64_t pgtl1e_index(uint64_t address)
|
|
{
|
|
return (address >> PGTL1_SHIFT) & (PTRS_PER_PGTL1E - 1UL);
|
|
}
|
|
|
|
static inline uint64_t pgtl0e_index(uint64_t address)
|
|
{
|
|
return (address >> PGTL0_SHIFT) & (PTRS_PER_PGTL0E - 1UL);
|
|
}
|
|
|
|
static inline uint64_t *page_addr(uint64_t pgtle)
|
|
{
|
|
return hpa2hva(arch_pgtl_page_paddr(pgtle));
|
|
}
|
|
|
|
static inline uint64_t is_pgtl_large(uint64_t pgtle)
|
|
{
|
|
return arch_pgtl_large(pgtle);
|
|
}
|
|
|
|
/**
|
|
* @brief Calculate the page map PGT_LVL3 table entry for a specified input address.
|
|
*
|
|
* The page map PGT_LVL3 table contains 512 entries, each of which points to a PGT_LVL2 page table.
|
|
* Address has the index to the PGT_LVL3 entry. This function is used to calculate the address of PGT_LVL3 entry.
|
|
* It is typically used during the page translation process.
|
|
*
|
|
* It will return a pointer to the page map PGT_LVL3 table entry.
|
|
*
|
|
* @param[in] pgtl3_page A pointer to a PGT_LVL3 page.
|
|
* @param[in] addr The address value for which the page map PGT_LVL3 table entry address is to be calculated.
|
|
* For hypervisor's MMU, it is the host virtual address.
|
|
* For each VM's stage 2 tranlation, it is the guest physical address.
|
|
*
|
|
* @return A pointer to the PGT_LVL3 entry.
|
|
*
|
|
* @pre pgtl3_page != NULL
|
|
*
|
|
* @post N/A
|
|
*/
|
|
static inline uint64_t *pgtl3e_offset(uint64_t *pgtl3_page, uint64_t addr)
|
|
{
|
|
return pgtl3_page + pgtl3e_index(addr);
|
|
}
|
|
|
|
/**
|
|
* @brief Calculate the PGT_LVL2 page table entry for a specified input address.
|
|
*
|
|
* The PGT_LVL2 page table is referenced by a page map PGT_LVL3 table entry and echo entry
|
|
* in PGT_LVL2 points to a PGT_LVL1 page table. Address has the index to the PGT_LVL2 entry. This function is used to
|
|
* calculate the address of PGT_LVL2 entry. It is typically used during the page translation process.
|
|
*
|
|
* It will return a pointer to the PGT_LVL2 page table entry.
|
|
*
|
|
* @param[in] pgtl3e A pointer to a PGT_LVL3 page map table entry.
|
|
* @param[in] addr The address for which the PGT_LVL2 page table entry address is to be calculated.
|
|
* For hypervisor's MMU, it is the host virtual address.
|
|
* For each VM's stage2 tranlation, it is the guest physical address.
|
|
*
|
|
* @return A pointer to the PGT_LVL2 entry.
|
|
*
|
|
* @pre pgtl3e != NULL
|
|
*
|
|
* @post N/A
|
|
*/
|
|
static inline uint64_t *pgtl2e_offset(const uint64_t *pgtl3e, uint64_t addr)
|
|
{
|
|
return page_addr(*pgtl3e) + pgtl2e_index(addr);
|
|
}
|
|
|
|
/**
|
|
* @brief Calculate the PGT_LVL1 page table entry for a specified input address.
|
|
*
|
|
* The PGT_LVL1 page table is referenced by a PGT_LVL2 page table entry and echo entry
|
|
* points to a page table. Address has the index to the entry in PGT_LVL1 page table . This function
|
|
* is used to calculate the address of PDE. It is typically used during the page translation process.
|
|
*
|
|
* It will return a pointer to the PGT_LVL1 page table entry.
|
|
*
|
|
* @param[in] pgtl2e A pointer to a PGT_LVL2 page table entry.
|
|
* @param[in] addr The address for which the PGT_LVL1 page table entry address is to be calculated.
|
|
* For hypervisor's MMU, it is the host virtual address.
|
|
* For each VM's stage 2 translation, it is the guest physical address.
|
|
*
|
|
* @return A pointer to the PGT_LVL1 page table entry.
|
|
*
|
|
* @pre pgtl2e != NULL
|
|
*
|
|
* @post N/A
|
|
*/
|
|
static inline uint64_t *pgtl1e_offset(const uint64_t *pgtl2e, uint64_t addr)
|
|
{
|
|
return page_addr(*pgtl2e) + pgtl1e_index(addr);
|
|
}
|
|
|
|
/**
|
|
* @brief Calculate the PGT_LVL0 page table entry for a specified input address.
|
|
*
|
|
* The PGT_LVL0 page table entry is the entry that maps a page. This function is used to calculate
|
|
* the address of the PGT_LVL0 entry. It is typically used during the page translation process.
|
|
* The function is essential for managing memory access permissions and for implementing memory systems.
|
|
*
|
|
* It will return the address of a PGT_LVL0 page table entry.
|
|
*
|
|
* @param[in] pgtl1e A pointer to a PGT_LVL1 page table entry.
|
|
* @param[in] addr The address for which the PGT_LVL1 page table entry address is to be calculated.
|
|
* For hypervisor's MMU, it is the host virtual address.
|
|
* For each VM's stage 2 translation, it is the guest physical address.
|
|
*
|
|
* @return A pointer to the PGT_LVL0 page table entry.
|
|
*
|
|
* @pre pgtl1e != NULL
|
|
*
|
|
* @post N/A
|
|
*/
|
|
static inline uint64_t *pgtl0e_offset(const uint64_t *pgtl1e, uint64_t addr)
|
|
{
|
|
return page_addr(*pgtl1e) + pgtl0e_index(addr);
|
|
}
|
|
|
|
static inline uint64_t round_pgtl1_up(uint64_t val)
|
|
{
|
|
return (((val + (uint64_t)PGTL1_SIZE) - 1UL) & PGTL1_MASK);
|
|
}
|
|
|
|
static inline uint64_t round_pgtl1_down(uint64_t val)
|
|
{
|
|
return (val & PGTL1_MASK);
|
|
}
|
|
|
|
static inline uint64_t pfn2paddr(uint64_t pfn)
|
|
{
|
|
return ((pfn >> PAGE_PFN_OFFSET) << PAGE_SHIFT);
|
|
}
|
|
|
|
static inline uint64_t paddr2pfn(uint64_t paddr)
|
|
{
|
|
return ((paddr >> PAGE_SHIFT) << PAGE_PFN_OFFSET);
|
|
}
|
|
|
|
/**
|
|
* @brief Translate a host physical address to a host virtual address before paging mode enabled.
|
|
*
|
|
* This function is used to translate a host physical address to a host virtual address before paging mode enabled.
|
|
* To get HVA by calling arch_hpa2hva_early.
|
|
*
|
|
* It returns the host virtual address that corresponds to the given host physical address.
|
|
*
|
|
* @param[in] x The host physical address
|
|
*
|
|
* @return The translated host virtual address
|
|
*
|
|
* @retval NULL if x == 0
|
|
*
|
|
* @pre N/A
|
|
*
|
|
* @post N/A
|
|
*
|
|
* @remark This function is used before paging mode enabled.
|
|
*/
|
|
static inline void *hpa2hva_early(uint64_t x)
|
|
{
|
|
return arch_hpa2hva_early(x);
|
|
}
|
|
|
|
/**
|
|
* @brief Translate a host virtual address to a host physical address before paging mode enabled.
|
|
*
|
|
* This function is used to translate a host virtual address to a host physical address before paging mode enabled. HVA
|
|
* To get HPA by calling arch_hva2hpa_early.
|
|
*
|
|
* It returns the host physical address that corresponds to the given host virtual address.
|
|
*
|
|
* @param[in] x The host virtual address to be translated
|
|
*
|
|
* @return The translated host physical address
|
|
*
|
|
* @retval 0 if x == NULL
|
|
*
|
|
* @pre N/A
|
|
*
|
|
* @post N/A
|
|
*
|
|
* @remark This function is used before paging mode enabled.
|
|
*/
|
|
static inline uint64_t hva2hpa_early(void *x)
|
|
{
|
|
return arch_hva2hpa_early(x);
|
|
}
|
|
|
|
#endif /* COMMON_PGTABLE_H*/
|