ANDROID: KVM: arm64: Introduce module-owned pages

In order to let vendor pKVM modules change the permission of host pages,
introduce a new concept of module-owned pages. This flag is stored in
the vmemmap so it can be set for pages that have been unmapped from the
host and for which the stage-2 PTEs are invalid.

Bug: 264070847
Change-Id: Ic831d3873cf7d31a2bd9f411306d657cc2f4db01
Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
Quentin Perret
2023-01-30 16:07:44 +00:00
parent 0a5d1bf965
commit 9d6994b7e3
3 changed files with 7 additions and 1 deletions

View File

@@ -32,6 +32,7 @@ enum pkvm_page_state {
/* Meta-states which aren't encoded directly in the PTE's SW bits */
PKVM_NOPAGE = BIT(0),
PKVM_PAGE_RESTRICTED_PROT = BIT(1),
PKVM_MODULE_DONT_TOUCH = BIT(2),
};
#define PKVM_PAGE_STATE_PROT_MASK (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)

View File

@@ -13,6 +13,7 @@
*/
#define HOST_PAGE_NEED_POISONING BIT(0)
#define HOST_PAGE_PENDING_RECLAIM BIT(1)
#define MODULE_OWNED_PAGE BIT(2)
struct hyp_page {
unsigned short refcount;

View File

@@ -903,15 +903,19 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size,
static enum pkvm_page_state host_get_page_state(kvm_pte_t pte, u64 addr)
{
bool is_memory = addr_is_memory(addr);
enum pkvm_page_state state = 0;
enum kvm_pgtable_prot prot;
if (is_memory && hyp_phys_to_page(addr)->flags & MODULE_OWNED_PAGE)
return PKVM_MODULE_DONT_TOUCH;
if (!kvm_pte_valid(pte) && pte)
return PKVM_NOPAGE;
prot = kvm_pgtable_stage2_pte_prot(pte);
if (kvm_pte_valid(pte)) {
if ((prot & KVM_PGTABLE_PROT_RWX) != default_host_prot(addr_is_memory(addr)))
if ((prot & KVM_PGTABLE_PROT_RWX) != default_host_prot(is_memory))
state = PKVM_PAGE_RESTRICTED_PROT;
}