mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
ANDROID: BACKPORT: KVM: arm64: Make owner ids 32 bits wide
We will soon need more than 8 bits to encode all possible owner ids in KVM protected mode. To prepare the ground for this, introduce a new type for owner_ids, and make it a 32bits wide. Signed-off-by: Quentin Perret <qperret@google.com> [willdeacon@: Move IDs to header and fix S2MPU host_stage2_set_owner() callback] Bug: 209580772 Change-Id: I37add42a2d7f34aa110c00fd9569d81db279d765 Signed-off-by: Will Deacon <willdeacon@google.com>
This commit is contained in:
committed by
Will Deacon
parent
cc8d7dcc40
commit
5da4a4ca5f
@@ -123,18 +123,4 @@ extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
|
||||
extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
|
||||
extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
|
||||
|
||||
struct kvm_iommu_ops {
|
||||
int (*init)(void);
|
||||
bool (*host_smc_handler)(struct kvm_cpu_context *host_ctxt);
|
||||
bool (*host_mmio_dabt_handler)(struct kvm_cpu_context *host_ctxt,
|
||||
phys_addr_t fault_pa, unsigned int len,
|
||||
bool is_write, int rd);
|
||||
void (*host_stage2_set_owner)(phys_addr_t addr, size_t size, u8 owner_id);
|
||||
int (*host_stage2_adjust_mmio_range)(phys_addr_t addr, phys_addr_t *start,
|
||||
phys_addr_t *end);
|
||||
};
|
||||
|
||||
extern struct kvm_iommu_ops kvm_iommu_ops;
|
||||
extern const struct kvm_iommu_ops kvm_s2mpu_ops;
|
||||
|
||||
#endif /* __ARM64_KVM_HYP_H__ */
|
||||
|
||||
24
arch/arm64/kvm/hyp/include/nvhe/iommu.h
Normal file
24
arch/arm64/kvm/hyp/include/nvhe/iommu.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef __ARM64_KVM_NVHE_IOMMU_H__
|
||||
#define __ARM64_KVM_NVHE_IOMMU_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/kvm_host.h>
|
||||
|
||||
#include <nvhe/mem_protect.h>
|
||||
|
||||
struct kvm_iommu_ops {
|
||||
int (*init)(void);
|
||||
bool (*host_smc_handler)(struct kvm_cpu_context *host_ctxt);
|
||||
bool (*host_mmio_dabt_handler)(struct kvm_cpu_context *host_ctxt,
|
||||
phys_addr_t fault_pa, unsigned int len,
|
||||
bool is_write, int rd);
|
||||
void (*host_stage2_set_owner)(phys_addr_t addr, size_t size, pkvm_id owner_id);
|
||||
int (*host_stage2_adjust_mmio_range)(phys_addr_t addr, phys_addr_t *start,
|
||||
phys_addr_t *end);
|
||||
};
|
||||
|
||||
extern struct kvm_iommu_ops kvm_iommu_ops;
|
||||
extern const struct kvm_iommu_ops kvm_s2mpu_ops;
|
||||
|
||||
#endif /* __ARM64_KVM_NVHE_IOMMU_H__ */
|
||||
@@ -51,7 +51,10 @@ struct host_kvm {
|
||||
};
|
||||
extern struct host_kvm host_kvm;
|
||||
|
||||
extern const u8 pkvm_hyp_id;
|
||||
typedef u32 pkvm_id;
|
||||
static const pkvm_id pkvm_host_id = 0;
|
||||
static const pkvm_id pkvm_hyp_id = 1;
|
||||
static const pkvm_id pkvm_guest_id = 2;
|
||||
|
||||
extern unsigned long hyp_nr_cpus;
|
||||
|
||||
@@ -64,7 +67,7 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct kvm_vcpu *vcpu);
|
||||
|
||||
bool addr_is_memory(phys_addr_t phys);
|
||||
int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
|
||||
int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id);
|
||||
int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, pkvm_id owner_id);
|
||||
int kvm_host_prepare_stage2(void *pgt_pool_base);
|
||||
int kvm_guest_prepare_stage2(struct kvm_shadow_vm *vm, void *pgd);
|
||||
void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <asm/kvm_hyp.h>
|
||||
#include <asm/kvm_mmu.h>
|
||||
|
||||
#include <nvhe/iommu.h>
|
||||
#include <nvhe/mem_protect.h>
|
||||
#include <nvhe/mm.h>
|
||||
#include <nvhe/pkvm.h>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
|
||||
#include <nvhe/iommu.h>
|
||||
#include <nvhe/memory.h>
|
||||
#include <nvhe/mm.h>
|
||||
#include <nvhe/spinlock.h>
|
||||
@@ -254,10 +255,13 @@ static void set_mpt_range_locked(struct mpt *mpt, phys_addr_t first_byte,
|
||||
__range_invalidation(dev, first_byte, last_byte);
|
||||
}
|
||||
|
||||
static void s2mpu_host_stage2_set_owner(phys_addr_t addr, size_t size, u8 owner_id)
|
||||
static void s2mpu_host_stage2_set_owner(phys_addr_t addr, size_t size,
|
||||
pkvm_id owner_id)
|
||||
{
|
||||
enum mpt_prot prot;
|
||||
|
||||
/* Grant access only to the default owner of the page table (ID=0). */
|
||||
enum mpt_prot prot = owner_id ? MPT_PROT_NONE : MPT_PROT_RW;
|
||||
prot = owner_id == pkvm_host_id ? MPT_PROT_RW : MPT_PROT_NONE;
|
||||
|
||||
/*
|
||||
* NOTE: The following code refers to 'end' as the exclusive upper
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <hyp/fault.h>
|
||||
|
||||
#include <nvhe/gfp.h>
|
||||
#include <nvhe/iommu.h>
|
||||
#include <nvhe/memory.h>
|
||||
#include <nvhe/mem_protect.h>
|
||||
#include <nvhe/mm.h>
|
||||
@@ -28,9 +29,6 @@ struct host_kvm host_kvm;
|
||||
|
||||
static struct hyp_pool host_s2_pool;
|
||||
|
||||
const u8 pkvm_host_id = 0;
|
||||
const u8 pkvm_hyp_id = 1;
|
||||
|
||||
static DEFINE_PER_CPU(struct kvm_shadow_vm *, __current_vm);
|
||||
#define current_vm (*this_cpu_ptr(&__current_vm))
|
||||
|
||||
@@ -513,14 +511,14 @@ int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
|
||||
return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
|
||||
}
|
||||
|
||||
#define KVM_INVALID_PTE_OWNER_MASK GENMASK(9, 2)
|
||||
static kvm_pte_t kvm_init_invalid_leaf_owner(u8 owner_id)
|
||||
#define KVM_INVALID_PTE_OWNER_MASK GENMASK(32, 1)
|
||||
static kvm_pte_t kvm_init_invalid_leaf_owner(pkvm_id owner_id)
|
||||
{
|
||||
return FIELD_PREP(KVM_INVALID_PTE_OWNER_MASK, owner_id);
|
||||
}
|
||||
|
||||
int host_stage2_set_owner_locked(phys_addr_t addr, u64 size,
|
||||
u8 owner_id)
|
||||
pkvm_id owner_id)
|
||||
{
|
||||
kvm_pte_t annotation = kvm_init_invalid_leaf_owner(owner_id);
|
||||
int ret;
|
||||
@@ -682,7 +680,7 @@ struct pkvm_mem_donation {
|
||||
const struct pkvm_mem_transition tx;
|
||||
};
|
||||
|
||||
static u8 completer_owner_id(const struct pkvm_mem_transition *tx)
|
||||
static pkvm_id completer_owner_id(const struct pkvm_mem_transition *tx)
|
||||
{
|
||||
switch (tx->completer.id) {
|
||||
case PKVM_ID_HOST:
|
||||
@@ -797,7 +795,7 @@ static int host_initiate_unshare(u64 *completer_addr,
|
||||
static int host_initiate_donation(u64 *completer_addr,
|
||||
const struct pkvm_mem_transition *tx)
|
||||
{
|
||||
u8 owner_id = completer_owner_id(tx);
|
||||
pkvm_id owner_id = completer_owner_id(tx);
|
||||
u64 size = tx->nr_pages * PAGE_SIZE;
|
||||
|
||||
*completer_addr = tx->initiator.host.completer_addr;
|
||||
@@ -823,7 +821,7 @@ static int host_ack_donation(u64 addr, const struct pkvm_mem_transition *tx)
|
||||
static int host_complete_donation(u64 addr, const struct pkvm_mem_transition *tx)
|
||||
{
|
||||
u64 size = tx->nr_pages * PAGE_SIZE;
|
||||
u8 host_id = completer_owner_id(tx);
|
||||
pkvm_id host_id = completer_owner_id(tx);
|
||||
|
||||
return host_stage2_set_owner_locked(addr, size, host_id);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <nvhe/early_alloc.h>
|
||||
#include <nvhe/gfp.h>
|
||||
#include <nvhe/iommu.h>
|
||||
#include <nvhe/memory.h>
|
||||
#include <nvhe/mem_protect.h>
|
||||
#include <nvhe/mm.h>
|
||||
|
||||
Reference in New Issue
Block a user