arm64: KVM: Allow for direct call of HYP functions when using VHE
When running VHE, there is no need to jump via some stub to perform a "HYP" function call, as there is a single address space. Let's thus change kvm_call_hyp() and co to perform a direct call in this case. Although this results in a bit of code expansion, it allows the compiler to check for type compatibility, something that we are missing so far. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Christoffer Dall <christoffer.dall@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
This commit is contained in:
parent
7aa8d14641
commit
18fc7bf8e0
|
@ -370,8 +370,36 @@ void kvm_arm_halt_guest(struct kvm *kvm);
|
||||||
void kvm_arm_resume_guest(struct kvm *kvm);
|
void kvm_arm_resume_guest(struct kvm *kvm);
|
||||||
|
|
||||||
u64 __kvm_call_hyp(void *hypfn, ...);
|
u64 __kvm_call_hyp(void *hypfn, ...);
|
||||||
#define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__)
|
|
||||||
#define kvm_call_hyp_ret(f, ...) kvm_call_hyp(f, ##__VA_ARGS__)
|
/*
|
||||||
|
* The couple of isb() below are there to guarantee the same behaviour
|
||||||
|
* on VHE as on !VHE, where the eret to EL1 acts as a context
|
||||||
|
* synchronization event.
|
||||||
|
*/
|
||||||
|
#define kvm_call_hyp(f, ...) \
|
||||||
|
do { \
|
||||||
|
if (has_vhe()) { \
|
||||||
|
f(__VA_ARGS__); \
|
||||||
|
isb(); \
|
||||||
|
} else { \
|
||||||
|
__kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define kvm_call_hyp_ret(f, ...) \
|
||||||
|
({ \
|
||||||
|
typeof(f(__VA_ARGS__)) ret; \
|
||||||
|
\
|
||||||
|
if (has_vhe()) { \
|
||||||
|
ret = f(__VA_ARGS__); \
|
||||||
|
isb(); \
|
||||||
|
} else { \
|
||||||
|
ret = __kvm_call_hyp(kvm_ksym_ref(f), \
|
||||||
|
##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
ret; \
|
||||||
|
})
|
||||||
|
|
||||||
void force_vm_exit(const cpumask_t *mask);
|
void force_vm_exit(const cpumask_t *mask);
|
||||||
void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
|
void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
|
||||||
|
|
Loading…
Reference in New Issue