acrn-hypervisor/hypervisor/include/arch/x86/page.h
Li Fei1 b4a23e6c13 hv: ept: build 4KB page mapping in EPT for code pages of rtvm
RTVM is enforced to use 4KB pages to mitigate CVE-2018-12207 and performance jitter,
which may be introduced by splitting large page into 4KB pages on demand. It works
fine in previous hardware platform where the size of address space for the RTVM is
relatively small. However, this is a problem when the platforms support 64 bits
high MMIO space, which could be super large and therefore consumes large # of
EPT page table pages.

This patch optimize it by using large page for purely data pages, such as MMIO spaces,
even for the RTVM.

Signed-off-by: Li Fei1 <fei1.li@intel.com>
Tracked-On: #5788
2021-03-11 12:36:17 +08:00

86 lines
2.1 KiB
C

/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PAGE_H
#define PAGE_H
#include <spinlock.h>
#include <board_info.h>
#define PAGE_SHIFT 12U
#define PAGE_SIZE (1U << PAGE_SHIFT)
#define PAGE_MASK 0xFFFFFFFFFFFFF000UL
#define MAXIMUM_PA_WIDTH 39U /* maximum physical-address width */
/* size of the low MMIO address space: 2GB */
#define PLATFORM_LO_MMIO_SIZE 0x80000000UL
/* size of the high MMIO address space: 1GB */
#define PLATFORM_HI_MMIO_SIZE 0x40000000UL
#define PML4_PAGE_NUM(size) 1UL
#define PDPT_PAGE_NUM(size) (((size) + PML4E_SIZE - 1UL) >> PML4E_SHIFT)
#define PD_PAGE_NUM(size) (((size) + PDPTE_SIZE - 1UL) >> PDPTE_SHIFT)
#define PT_PAGE_NUM(size) (((size) + PDE_SIZE - 1UL) >> PDE_SHIFT)
/**
* @brief Page tables level in IA32 paging mode
*/
enum _page_table_level {
/**
* @brief The PML4 level in the page tables
*/
IA32E_PML4 = 0,
/**
* @brief The Page-Directory-Pointer-Table level in the page tables
*/
IA32E_PDPT = 1,
/**
* @brief The Page-Directory level in the page tables
*/
IA32E_PD = 2,
/**
* @brief The Page-Table level in the page tables
*/
IA32E_PT = 3,
};
struct acrn_vm;
struct page {
uint8_t contents[PAGE_SIZE];
} __aligned(PAGE_SIZE);
struct page_pool {
struct page *start_page;
spinlock_t lock;
uint64_t bitmap_size;
uint64_t *bitmap;
uint64_t last_hint_id;
struct page *dummy_page;
};
struct memory_ops {
struct page_pool *pool;
bool (*large_page_support)(enum _page_table_level level, uint64_t prot);
uint64_t (*get_default_access_right)(void);
uint64_t (*pgentry_present)(uint64_t pte);
void (*clflush_pagewalk)(const void *p);
void (*tweak_exe_right)(uint64_t *entry);
void (*recover_exe_right)(uint64_t *entry);
};
extern const struct memory_ops ppt_mem_ops;
void init_ept_mem_ops(struct memory_ops *mem_ops, uint16_t vm_id);
struct page *alloc_page(struct page_pool *pool);
void free_page(struct page_pool *pool, struct page *page);
void *get_reserve_sworld_memory_base(void);
void reserve_buffer_for_ept_pages(void);
#endif /* PAGE_H */