KVM: arm64: Define our own swab32() to avoid a uapi static inline
KVM uses swab32() when mediating GIC MMIO accesses if the GICV is badly aligned, and the host and guest differ in endianness. arm64 doesn't provide a __arch_swab32(), so __fswab32() is always backed by the macro implementation that the compiler reduces to a single instruction. But the static-inline causes problems for KVM if the compiler chooses not to inline this function, it may not be located in the __hyp_text where __vgic_v2_perform_cpuif_access() needs it. Create our own __kvm_swab32() macro that calls ___constant_swab32() directly. This way we know it will always be inlined. Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20200220165839.256881-3-james.morse@arm.com
This commit is contained in:
parent
5c37f1ae1c
commit
8c2d146ee7
@ -47,6 +47,13 @@
|
|||||||
#define read_sysreg_el2(r) read_sysreg_elx(r, _EL2, _EL1)
|
#define read_sysreg_el2(r) read_sysreg_elx(r, _EL2, _EL1)
|
||||||
#define write_sysreg_el2(v,r) write_sysreg_elx(v, r, _EL2, _EL1)
|
#define write_sysreg_el2(v,r) write_sysreg_elx(v, r, _EL2, _EL1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Without an __arch_swab32(), we fall back to ___constant_swab32(), but the
|
||||||
|
* static inline can allow the compiler to out-of-line this. KVM always wants
|
||||||
|
* the macro version as its always inlined.
|
||||||
|
*/
|
||||||
|
#define __kvm_swab32(x) ___constant_swab32(x)
|
||||||
|
|
||||||
int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
|
int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
|
void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
|
||||||
|
@ -69,14 +69,14 @@ int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu)
|
|||||||
u32 data = vcpu_get_reg(vcpu, rd);
|
u32 data = vcpu_get_reg(vcpu, rd);
|
||||||
if (__is_be(vcpu)) {
|
if (__is_be(vcpu)) {
|
||||||
/* guest pre-swabbed data, undo this for writel() */
|
/* guest pre-swabbed data, undo this for writel() */
|
||||||
data = swab32(data);
|
data = __kvm_swab32(data);
|
||||||
}
|
}
|
||||||
writel_relaxed(data, addr);
|
writel_relaxed(data, addr);
|
||||||
} else {
|
} else {
|
||||||
u32 data = readl_relaxed(addr);
|
u32 data = readl_relaxed(addr);
|
||||||
if (__is_be(vcpu)) {
|
if (__is_be(vcpu)) {
|
||||||
/* guest expects swabbed data */
|
/* guest expects swabbed data */
|
||||||
data = swab32(data);
|
data = __kvm_swab32(data);
|
||||||
}
|
}
|
||||||
vcpu_set_reg(vcpu, rd, data);
|
vcpu_set_reg(vcpu, rd, data);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user