|
18 | 18 | #include <linux/compiler.h>
|
19 | 19 | #include <linux/irqchip/arm-gic.h>
|
20 | 20 | #include <linux/kvm_host.h>
|
| 21 | +#include <linux/swab.h> |
21 | 22 |
|
22 | 23 | #include <asm/kvm_emulate.h>
|
23 | 24 | #include <asm/kvm_hyp.h>
|
24 | 25 | #include <asm/kvm_mmu.h>
|
25 | 26 |
|
| 27 | +static bool __hyp_text __is_be(struct kvm_vcpu *vcpu) |
| 28 | +{ |
| 29 | + if (vcpu_mode_is_32bit(vcpu)) |
| 30 | + return !!(read_sysreg_el2(spsr) & COMPAT_PSR_E_BIT); |
| 31 | + |
| 32 | + return !!(read_sysreg(SCTLR_EL1) & SCTLR_ELx_EE); |
| 33 | +} |
| 34 | + |
26 | 35 | /*
|
27 | 36 | * __vgic_v2_perform_cpuif_access -- perform a GICV access on behalf of the
|
28 | 37 | * guest.
|
@@ -64,14 +73,19 @@ int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu)
|
64 | 73 | addr += fault_ipa - vgic->vgic_cpu_base;
|
65 | 74 |
|
66 | 75 | if (kvm_vcpu_dabt_iswrite(vcpu)) {
|
67 |
| - u32 data = vcpu_data_guest_to_host(vcpu, |
68 |
| - vcpu_get_reg(vcpu, rd), |
69 |
| - sizeof(u32)); |
| 76 | + u32 data = vcpu_get_reg(vcpu, rd); |
| 77 | + if (__is_be(vcpu)) { |
| 78 | + /* guest pre-swabbed data, undo this for writel() */ |
| 79 | + data = swab32(data); |
| 80 | + } |
70 | 81 | writel_relaxed(data, addr);
|
71 | 82 | } else {
|
72 | 83 | u32 data = readl_relaxed(addr);
|
73 |
| - vcpu_set_reg(vcpu, rd, vcpu_data_host_to_guest(vcpu, data, |
74 |
| - sizeof(u32))); |
| 84 | + if (__is_be(vcpu)) { |
| 85 | + /* guest expects swabbed data */ |
| 86 | + data = swab32(data); |
| 87 | + } |
| 88 | + vcpu_set_reg(vcpu, rd, data); |
75 | 89 | }
|
76 | 90 |
|
77 | 91 | return 1;
|
|
0 commit comments