Skip to content

Commit 3f868e1

Browse files
Quentin PerretMarc Zyngier
authored andcommitted
KVM: arm64: Introduce kvm_share_hyp()
The create_hyp_mappings() function can currently be called at any point in time. However, its behaviour in protected mode changes widely depending on when it is being called. Prior to KVM init, it is used to create the temporary page-table used to bring-up the hypervisor, and later on it is transparently turned into a 'share' hypercall when the kernel has lost control over the hypervisor stage-1. In order to prepare the ground for also unsharing pages with the hypervisor during guest teardown, introduce a kvm_share_hyp() function to make it clear in which places a share hypercall should be expected, as we will soon need a matching unshare hypercall in all those places. Signed-off-by: Quentin Perret <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 82bb024 commit 3f868e1

File tree

5 files changed

+26
-10
lines changed

5 files changed

+26
-10
lines changed

arch/arm64/include/asm/kvm_mmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ static __always_inline unsigned long __kern_hyp_va(unsigned long v)
150150
#include <asm/kvm_pgtable.h>
151151
#include <asm/stage2_pgtable.h>
152152

153+
int kvm_share_hyp(void *from, void *to);
153154
int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
154155
int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
155156
void __iomem **kaddr,

arch/arm64/kvm/arm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
146146
if (ret)
147147
return ret;
148148

149-
ret = create_hyp_mappings(kvm, kvm + 1, PAGE_HYP);
149+
ret = kvm_share_hyp(kvm, kvm + 1);
150150
if (ret)
151151
goto out_free_stage2_pgd;
152152

@@ -342,7 +342,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
342342
if (err)
343343
return err;
344344

345-
return create_hyp_mappings(vcpu, vcpu + 1, PAGE_HYP);
345+
return kvm_share_hyp(vcpu, vcpu + 1);
346346
}
347347

348348
void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)

arch/arm64/kvm/fpsimd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
3030
struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
3131

3232
/* Make sure the host task fpsimd state is visible to hyp: */
33-
ret = create_hyp_mappings(fpsimd, fpsimd + 1, PAGE_HYP);
33+
ret = kvm_share_hyp(fpsimd, fpsimd + 1);
3434
if (!ret)
3535
vcpu->arch.host_fpsimd_state = kern_hyp_va(fpsimd);
3636

arch/arm64/kvm/mmu.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,25 @@ static int pkvm_share_hyp(phys_addr_t start, phys_addr_t end)
296296
return 0;
297297
}
298298

299+
int kvm_share_hyp(void *from, void *to)
300+
{
301+
if (is_kernel_in_hyp_mode())
302+
return 0;
303+
304+
/*
305+
* The share hcall maps things in the 'fixed-offset' region of the hyp
306+
* VA space, so we can only share physically contiguous data-structures
307+
* for now.
308+
*/
309+
if (is_vmalloc_or_module_addr(from) || is_vmalloc_or_module_addr(to))
310+
return -EINVAL;
311+
312+
if (kvm_host_owns_hyp_mappings())
313+
return create_hyp_mappings(from, to, PAGE_HYP);
314+
315+
return pkvm_share_hyp(__pa(from), __pa(to));
316+
}
317+
299318
/**
300319
* create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode
301320
* @from: The virtual kernel start address of the range
@@ -316,12 +335,8 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
316335
if (is_kernel_in_hyp_mode())
317336
return 0;
318337

319-
if (!kvm_host_owns_hyp_mappings()) {
320-
if (WARN_ON(prot != PAGE_HYP))
321-
return -EPERM;
322-
return pkvm_share_hyp(kvm_kaddr_to_phys(from),
323-
kvm_kaddr_to_phys(to));
324-
}
338+
if (!kvm_host_owns_hyp_mappings())
339+
return -EPERM;
325340

326341
start = start & PAGE_MASK;
327342
end = PAGE_ALIGN(end);

arch/arm64/kvm/reset.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ static int kvm_vcpu_finalize_sve(struct kvm_vcpu *vcpu)
113113
if (!buf)
114114
return -ENOMEM;
115115

116-
ret = create_hyp_mappings(buf, buf + reg_sz, PAGE_HYP);
116+
ret = kvm_share_hyp(buf, buf + reg_sz);
117117
if (ret) {
118118
kfree(buf);
119119
return ret;

0 commit comments

Comments
 (0)