(Un)map guest memory if it's sharing status changes. Signed-off-by: Fuad Tabba <tabba@xxxxxxxxxx> --- arm/aarch64/include/asm/kvm.h | 7 +++++ arm/kvm-cpu.c | 58 ++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/arm/aarch64/include/asm/kvm.h b/arm/aarch64/include/asm/kvm.h index 316917b..662c178 100644 --- a/arm/aarch64/include/asm/kvm.h +++ b/arm/aarch64/include/asm/kvm.h @@ -467,6 +467,13 @@ enum { /* run->fail_entry.hardware_entry_failure_reason codes. */ #define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0) +#define ARM_SMCCC_KVM_FUNC_MEM_SHARE 3 +#define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE 4 + +#define KVM_EXIT_HYPERCALL_VALID_MASK ((1ULL << ARM_SMCCC_KVM_FUNC_MEM_SHARE) | \ + (1ULL << ARM_SMCCC_KVM_FUNC_MEM_UNSHARE)) + + #endif #endif /* __ARM_KVM_H__ */ diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c index cb5a92a..fcefec8 100644 --- a/arm/kvm-cpu.c +++ b/arm/kvm-cpu.c @@ -144,16 +144,64 @@ void kvm_cpu__delete(struct kvm_cpu *vcpu) free(vcpu); } -bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) +static bool handle_mem_share(struct kvm_cpu *vcpu) { - switch (vcpu->kvm_run->exit_reason) { - case KVM_EXIT_HYPERCALL: - pr_warning("Unhandled exit hypercall: 0x%llx, 0x%llx, 0x%llx, 0x%llx", + u64 gpa = vcpu->kvm_run->hypercall.args[0]; + + if (!vcpu->kvm->cfg.pkvm) { + pr_warning("%s: non-protected guest memshare request for gpa 0x%llx", + __func__, gpa); + return true; + } + + map_guest_range(vcpu->kvm, gpa, PAGE_SIZE); + + return true; +} + +static bool handle_mem_unshare(struct kvm_cpu *vcpu) +{ + u64 gpa = vcpu->kvm_run->hypercall.args[0]; + + if (!vcpu->kvm->cfg.pkvm) { + pr_warning("%s: non-protected guest memunshare request for gpa 0x%llx", + __func__, gpa); + return true; + } + + unmap_guest_range(vcpu->kvm, gpa, PAGE_SIZE); + + return true; +} + +static bool handle_hypercall(struct kvm_cpu *vcpu) +{ + u64 call_nr = vcpu->kvm_run->hypercall.nr; + + switch (call_nr) + { + case ARM_SMCCC_KVM_FUNC_MEM_SHARE: + return handle_mem_share(vcpu); + case ARM_SMCCC_KVM_FUNC_MEM_UNSHARE: + return handle_mem_unshare(vcpu); + default: + pr_warning("%s: Unhandled exit hypercall: 0x%llx, 0x%llx, 0x%llx, 0x%llx", + __func__, vcpu->kvm_run->hypercall.nr, vcpu->kvm_run->hypercall.ret, vcpu->kvm_run->hypercall.args[0], vcpu->kvm_run->hypercall.args[1]); - return true; + break; + } + + return true; +} + +bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) +{ + switch (vcpu->kvm_run->exit_reason) { + case KVM_EXIT_HYPERCALL: + return handle_hypercall(vcpu); } return false; -- 2.39.0.rc0.267.gcb52ba06e7-goog