Skip to content

Commit 26117e4

Browse files
Quentin PerretMarc Zyngier
authored andcommitted
KVM: arm64: Introduce __pkvm_host_wrprotect_guest()
Introduce a new hypercall to remove the write permission from a non-protected guest stage-2 mapping. This will be used for e.g. enabling 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 34884a0 commit 26117e4

File tree

4 files changed

+42
-0
lines changed

4 files changed

+42
-0
lines changed

arch/arm64/include/asm/kvm_asm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ enum __kvm_host_smccc_func {
6868
__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
6969
__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
7070
__KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
71+
__KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
7172
__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
7273
__KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
7374
__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
@@ -43,6 +43,7 @@ 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);
4545
int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot);
46+
int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *hyp_vm);
4647

4748
bool addr_is_memory(phys_addr_t phys);
4849
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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,26 @@ static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *host_ct
283283
cpu_reg(host_ctxt, 1) = ret;
284284
}
285285

286+
static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt)
287+
{
288+
DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
289+
DECLARE_REG(u64, gfn, host_ctxt, 2);
290+
struct pkvm_hyp_vm *hyp_vm;
291+
int ret = -EINVAL;
292+
293+
if (!is_protected_kvm_enabled())
294+
goto out;
295+
296+
hyp_vm = get_np_pkvm_hyp_vm(handle);
297+
if (!hyp_vm)
298+
goto out;
299+
300+
ret = __pkvm_host_wrprotect_guest(gfn, hyp_vm);
301+
put_pkvm_hyp_vm(hyp_vm);
302+
out:
303+
cpu_reg(host_ctxt, 1) = ret;
304+
}
305+
286306
static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
287307
{
288308
DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
@@ -495,6 +515,7 @@ static const hcall_t host_hcall[] = {
495515
HANDLE_FUNC(__pkvm_host_share_guest),
496516
HANDLE_FUNC(__pkvm_host_unshare_guest),
497517
HANDLE_FUNC(__pkvm_host_relax_perms_guest),
518+
HANDLE_FUNC(__pkvm_host_wrprotect_guest),
498519
HANDLE_FUNC(__kvm_adjust_pc),
499520
HANDLE_FUNC(__kvm_vcpu_run),
500521
HANDLE_FUNC(__kvm_flush_vm_context),

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,3 +1511,22 @@ int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_
15111511

15121512
return ret;
15131513
}
1514+
1515+
int __pkvm_host_wrprotect_guest(u64 gfn, struct pkvm_hyp_vm *vm)
1516+
{
1517+
u64 ipa = hyp_pfn_to_phys(gfn);
1518+
u64 phys;
1519+
int ret;
1520+
1521+
host_lock_component();
1522+
guest_lock_component(vm);
1523+
1524+
ret = __check_host_shared_guest(vm, &phys, ipa);
1525+
if (!ret)
1526+
ret = kvm_pgtable_stage2_wrprotect(&vm->pgt, ipa, PAGE_SIZE);
1527+
1528+
guest_unlock_component(vm);
1529+
host_unlock_component();
1530+
1531+
return ret;
1532+
}

0 commit comments

Comments
 (0)