Skip to content

Commit 34884a0

Browse files
Quentin PerretMarc Zyngier
authored andcommitted
KVM: arm64: Introduce __pkvm_host_relax_guest_perms()
Introduce a new hypercall allowing the host to relax the stage-2 permissions of mappings in a non-protected guest page-table. It will be used later once we start allowing RO memslots and dirty logging. Tested-by: Fuad Tabba <[email protected]> Reviewed-by: Fuad Tabba <[email protected]> Signed-off-by: Quentin Perret <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 72db3d3 commit 34884a0

File tree

4 files changed

+45
-0
lines changed

4 files changed

+45
-0
lines changed

arch/arm64/include/asm/kvm_asm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ enum __kvm_host_smccc_func {
6767
__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
6868
__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
6969
__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
70+
__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
7071
__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
7172
__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
7273
__KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,

arch/arm64/kvm/hyp/include/nvhe/mem_protect.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages);
4242
int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu,
4343
enum kvm_pgtable_prot prot);
4444
int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
45+
int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
4546

4647
bool addr_is_memory(phys_addr_t phys);
4748
int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);

arch/arm64/kvm/hyp/nvhe/hyp-main.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,25 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
264264
cpu_reg(host_ctxt, 1) = ret;
265265
}
266266

267+
static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *host_ctxt)
268+
{
269+
DECLARE_REG(u64, gfn, host_ctxt, 1);
270+
DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 2);
271+
struct pkvm_hyp_vcpu *hyp_vcpu;
272+
int ret = -EINVAL;
273+
274+
if (!is_protected_kvm_enabled())
275+
goto out;
276+
277+
hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
278+
if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
279+
goto out;
280+
281+
ret = __pkvm_host_relax_perms_guest(gfn, hyp_vcpu, prot);
282+
out:
283+
cpu_reg(host_ctxt, 1) = ret;
284+
}
285+
267286
static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
268287
{
269288
DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -475,6 +494,7 @@ static const hcall_t host_hcall[] = {
475494
HANDLE_FUNC(__pkvm_host_unshare_hyp),
476495
HANDLE_FUNC(__pkvm_host_share_guest),
477496
HANDLE_FUNC(__pkvm_host_unshare_guest),
497+
HANDLE_FUNC(__pkvm_host_relax_perms_guest),
478498
HANDLE_FUNC(__kvm_adjust_pc),
479499
HANDLE_FUNC(__kvm_vcpu_run),
480500
HANDLE_FUNC(__kvm_flush_vm_context),

arch/arm64/kvm/hyp/nvhe/mem_protect.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,3 +1488,26 @@ int __pkvm_host_unshare_guest(u64 gfn, struct pkvm_hyp_vm *vm)
14881488

14891489
return ret;
14901490
}
1491+
1492+
int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot)
1493+
{
1494+
struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
1495+
u64 ipa = hyp_pfn_to_phys(gfn);
1496+
u64 phys;
1497+
int ret;
1498+
1499+
if (prot & ~KVM_PGTABLE_PROT_RWX)
1500+
return -EINVAL;
1501+
1502+
host_lock_component();
1503+
guest_lock_component(vm);
1504+
1505+
ret = __check_host_shared_guest(vm, &phys, ipa);
1506+
if (!ret)
1507+
ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0);
1508+
1509+
guest_unlock_component(vm);
1510+
host_unlock_component();
1511+
1512+
return ret;
1513+
}

0 commit comments

Comments
 (0)