2018-03-07 20:57:14 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
|
|
|
*
|
2018-05-26 01:49:13 +08:00
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
2018-03-07 20:57:14 +08:00
|
|
|
*/
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @file mmu.h
|
|
|
|
*
|
|
|
|
* @brief APIs for Memory Management module
|
|
|
|
*/
|
2018-03-07 20:57:14 +08:00
|
|
|
#ifndef MMU_H
|
|
|
|
#define MMU_H
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief Memory Management
|
|
|
|
*
|
|
|
|
* @defgroup acrn_mem ACRN Memory Management
|
|
|
|
* @{
|
|
|
|
*/
|
2018-03-07 20:57:14 +08:00
|
|
|
/** The flag that indicates that the page fault was caused by a non present
|
|
|
|
* page.
|
|
|
|
*/
|
2018-08-23 16:11:17 +08:00
|
|
|
#define PAGE_FAULT_P_FLAG 0x00000001U
|
2018-03-07 20:57:14 +08:00
|
|
|
/** The flag that indicates that the page fault was caused by a write access. */
|
2018-08-23 16:11:17 +08:00
|
|
|
#define PAGE_FAULT_WR_FLAG 0x00000002U
|
2018-03-07 20:57:14 +08:00
|
|
|
/** The flag that indicates that the page fault was caused in user mode. */
|
2018-08-23 16:11:17 +08:00
|
|
|
#define PAGE_FAULT_US_FLAG 0x00000004U
|
2018-03-07 20:57:14 +08:00
|
|
|
/** The flag that indicates that the page fault was caused by a reserved bit
|
|
|
|
* violation.
|
|
|
|
*/
|
2018-08-23 16:11:17 +08:00
|
|
|
#define PAGE_FAULT_RSVD_FLAG 0x00000008U
|
2018-03-07 20:57:14 +08:00
|
|
|
/** The flag that indicates that the page fault was caused by an instruction
|
|
|
|
* fetch.
|
|
|
|
*/
|
2018-08-23 16:11:17 +08:00
|
|
|
#define PAGE_FAULT_ID_FLAG 0x00000010U
|
2018-03-07 20:57:14 +08:00
|
|
|
|
|
|
|
/* Defines used for common memory sizes */
|
2018-08-23 16:11:17 +08:00
|
|
|
#define MEM_1K 1024U
|
|
|
|
#define MEM_2K (MEM_1K * 2U)
|
|
|
|
#define MEM_4K (MEM_1K * 4U)
|
|
|
|
#define MEM_1M (MEM_1K * 1024U)
|
|
|
|
#define MEM_2M (MEM_1M * 2U)
|
|
|
|
#define MEM_1G (MEM_1M * 1024U)
|
2018-03-07 20:57:14 +08:00
|
|
|
|
|
|
|
#ifndef ASSEMBLER
|
|
|
|
|
2018-04-04 00:07:21 +08:00
|
|
|
#include <cpu.h>
|
2018-10-30 05:55:57 +08:00
|
|
|
#include <page.h>
|
2018-12-19 18:12:45 +08:00
|
|
|
#include <pgtable.h>
|
2019-02-03 15:07:13 +08:00
|
|
|
#include <cpu_caps.h>
|
2018-04-04 00:07:21 +08:00
|
|
|
|
2018-03-07 20:57:14 +08:00
|
|
|
/* Define cache line size (in bytes) */
|
2018-08-23 16:11:17 +08:00
|
|
|
#define CACHE_LINE_SIZE 64U
|
2018-03-07 20:57:14 +08:00
|
|
|
|
|
|
|
/* IA32E Paging constants */
|
2019-04-22 05:52:12 +08:00
|
|
|
#define IA32E_REF_MASK ((get_pcpu_info())->physical_address_mask)
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2019-02-02 10:24:18 +08:00
|
|
|
struct acrn_vcpu;
|
2018-09-10 13:21:56 +08:00
|
|
|
static inline uint64_t round_page_up(uint64_t addr)
|
|
|
|
{
|
2018-12-03 09:41:18 +08:00
|
|
|
return (((addr + (uint64_t)PAGE_SIZE) - 1UL) & PAGE_MASK);
|
2018-09-10 13:21:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint64_t round_page_down(uint64_t addr)
|
|
|
|
{
|
2018-12-03 09:41:18 +08:00
|
|
|
return (addr & PAGE_MASK);
|
2018-09-10 13:21:56 +08:00
|
|
|
}
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2018-12-19 18:12:45 +08:00
|
|
|
static inline uint64_t round_pde_up(uint64_t val)
|
|
|
|
{
|
|
|
|
return (((val + (uint64_t)PDE_SIZE) - 1UL) & PDE_MASK);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint64_t round_pde_down(uint64_t val)
|
|
|
|
{
|
|
|
|
return (val & PDE_MASK);
|
|
|
|
}
|
|
|
|
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief Page tables level in IA32 paging mode
|
|
|
|
*/
|
2018-03-07 20:57:14 +08:00
|
|
|
enum _page_table_level {
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief The PML4 level in the page tables
|
|
|
|
*/
|
2018-03-07 20:57:14 +08:00
|
|
|
IA32E_PML4 = 0,
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief The Page-Directory-Pointer-Table level in the page tables
|
|
|
|
*/
|
2018-03-07 20:57:14 +08:00
|
|
|
IA32E_PDPT = 1,
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief The Page-Directory level in the page tables
|
|
|
|
*/
|
2018-03-07 20:57:14 +08:00
|
|
|
IA32E_PD = 2,
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief The Page-Table level in the page tables
|
|
|
|
*/
|
2018-03-07 20:57:14 +08:00
|
|
|
IA32E_PT = 3,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Page size */
|
|
|
|
#define PAGE_SIZE_4K MEM_4K
|
|
|
|
#define PAGE_SIZE_2M MEM_2M
|
|
|
|
#define PAGE_SIZE_1G MEM_1G
|
|
|
|
|
2019-07-01 12:23:15 +08:00
|
|
|
void sanitize_pte_entry(uint64_t *ptep, const struct memory_ops *mem_ops);
|
|
|
|
void sanitize_pte(uint64_t *pt_page, const struct memory_ops *mem_ops);
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief MMU paging enable
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*/
|
2018-10-31 07:41:59 +08:00
|
|
|
void enable_paging(void);
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief Supervisor-mode execution prevention (SMEP) enable
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*/
|
2018-06-14 18:22:51 +08:00
|
|
|
void enable_smep(void);
|
2018-12-13 16:55:11 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Supervisor-mode Access Prevention (SMAP) enable
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*/
|
|
|
|
void enable_smap(void);
|
|
|
|
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief MMU page tables initialization
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*/
|
2018-03-07 20:57:14 +08:00
|
|
|
void init_paging(void);
|
2018-10-30 05:55:57 +08:00
|
|
|
void mmu_add(uint64_t *pml4_page, uint64_t paddr_base, uint64_t vaddr_base,
|
|
|
|
uint64_t size, uint64_t prot, const struct memory_ops *mem_ops);
|
|
|
|
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);
|
2018-12-13 16:55:11 +08:00
|
|
|
void hv_access_memory_region_update(uint64_t base, uint64_t size);
|
|
|
|
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief Specified signle VPID flush
|
|
|
|
*
|
|
|
|
* @param[in] vpid the specified VPID
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*/
|
HV:treewide:Add 16-bit atomic operations and update vpid type
There are some integer type conversions reported by static
analysis tool for vcpu id, number of created vcpus, and
vpid, to reduce these type conversions, redesign vcpu id,
number of created vcpus, and vpid type as uint16_t as per
their usage, related 16-bit atomic operations shall be
added in HV.
MISRA C requires that all unsigned constants should have the suffix 'U'
(e.g. 0xffU), but the assembler may not accept such C-style constants.
Add 16-bit atomic add/dec/store operations;
Update temporary variables type and parameters type of
related caller;
Update vpid type as uint16_t;
Replace Macro with constant value for CPU_PAGE_SIZE.
Note: According to SDM A.10, there are some bits defined
in the IA32_VMX_EPT_VPID_CAP MSR to support the INVVPID
instruction, these bits don't mean actual VPID, so
the vpid field in the data struct vmx_capability doesn't
be updated.
V1--V2:
update comments for assembly code as per coding style;
Signed-off-by: Xiangyang Wu <xiangyang.wu@intel.com>
2018-07-11 11:09:10 +08:00
|
|
|
void flush_vpid_single(uint16_t vpid);
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief All VPID flush
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*/
|
2018-05-31 16:39:49 +08:00
|
|
|
void flush_vpid_global(void);
|
2019-06-13 18:03:53 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Flush address space
|
|
|
|
*
|
|
|
|
* @param[in] addr the specified virtual address
|
|
|
|
*
|
|
|
|
* @param[in] size the specified size to flush
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*/
|
|
|
|
void flush_address_space(void *addr, uint64_t size);
|
|
|
|
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @brief Guest-physical mappings and combined mappings invalidation
|
|
|
|
*
|
2019-08-29 16:29:25 +08:00
|
|
|
* @param[in] eptp the pointer that points the eptp
|
2018-10-31 11:24:31 +08:00
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*/
|
2019-08-29 16:29:25 +08:00
|
|
|
void invept(const void *eptp);
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2018-09-10 13:21:56 +08:00
|
|
|
static inline void cache_flush_invalidate_all(void)
|
|
|
|
{
|
|
|
|
asm volatile (" wbinvd\n" : : : "memory");
|
2018-03-07 20:57:14 +08:00
|
|
|
}
|
|
|
|
|
2019-07-01 12:23:15 +08:00
|
|
|
static inline void clflush(const volatile void *p)
|
2018-04-11 17:00:05 +08:00
|
|
|
{
|
|
|
|
asm volatile ("clflush (%0)" :: "r"(p));
|
|
|
|
}
|
|
|
|
|
2019-07-01 12:23:15 +08:00
|
|
|
static inline void clflushopt(const volatile void *p)
|
2019-06-13 17:40:05 +08:00
|
|
|
{
|
|
|
|
asm volatile ("clflushopt (%0)" :: "r"(p));
|
|
|
|
}
|
|
|
|
|
2019-02-19 17:05:23 +08:00
|
|
|
/* get PDPT address from CR3 vaule in PAE mode */
|
|
|
|
static inline uint64_t get_pae_pdpt_addr(uint64_t cr3)
|
|
|
|
{
|
|
|
|
return (cr3 & 0xFFFFFFE0UL);
|
|
|
|
}
|
2018-03-07 20:57:14 +08:00
|
|
|
|
2018-10-31 11:24:31 +08:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
2018-03-07 20:57:14 +08:00
|
|
|
#endif /* ASSEMBLER not defined */
|
|
|
|
|
|
|
|
#endif /* MMU_H */
|