On Mon, 28 Sep 2020 at 23:16, Greg KH gregkh@linuxfoundation.org wrote:
On Mon, Sep 28, 2020 at 06:18:50PM +0100, Marc Zyngier wrote:
Commit c4ad98e4b72cb5be30ea282fce935248f2300e62 upstream.
KVM currently assumes that an instruction abort can never be a write. This is in general true, except when the abort is triggered by a S1PTW on instruction fetch that tries to update the S1 page tables (to set AF, for example).
This can happen if the page tables have been paged out and brought back in without seeing a direct write to them (they are thus marked read only), and the fault handling code will make the PT executable(!) instead of writable. The guest gets stuck forever.
In these conditions, the permission fault must be considered as a write so that the Stage-1 update can take place. This is essentially the I-side equivalent of the problem fixed by 60e21a0ef54c ("arm64: KVM: Take S1 walks into account when determining S2 write faults").
Update kvm_is_write_fault() to return true on IABT+S1PTW, and introduce kvm_vcpu_trap_is_exec_fault() that only return true when no faulting on a S1 fault. Additionally, kvm_vcpu_dabt_iss1tw() is renamed to kvm_vcpu_abt_iss1tw(), as the above makes it plain that it isn't specific to data abort.
Signed-off-by: Marc Zyngier maz@kernel.org Reviewed-by: Will Deacon will@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200915104218.1284701-2-maz@kernel.org
Thanks for all 3 of these, now queued up!
stable rc branch 4.19 arm64 build broken.
../arch/arm64/kvm/../../../virt/kvm/arm/mmu.c:1283:13: error: redefinition of ‘kvm_is_write_fault’ 1283 | static bool kvm_is_write_fault(struct kvm_vcpu *vcpu) | ^~~~~~~~~~~~~~~~~~
Reported-by: Naresh Kamboju naresh.kamboju@linaro.org
build log,
make -sk KBUILD_BUILD_USER=TuxBuild -C/linux -j16 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- HOSTCC=gcc CC="sccache aarch64-linux-gnu-gcc" O=build Image # In file included from ../arch/arm64/kvm/hyp/../../../../virt/kvm/arm/hyp/vgic-v3-sr.c:22: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/hyp/../../../../virt/kvm/arm/hyp/aarch32.c:14: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c:23: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/hyp/sysreg-sr.c:23: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/hyp/switch.c:29: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/arm.c:51: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/mmio.c:21: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/psci.c:25: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/perf.c:23: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/regmap.c:24: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/inject_fault.c:25: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/mmu.c:31: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ ../arch/arm64/kvm/../../../virt/kvm/arm/mmu.c: At top level: ../arch/arm64/kvm/../../../virt/kvm/arm/mmu.c:1283:13: error: redefinition of ‘kvm_is_write_fault’ 1283 | static bool kvm_is_write_fault(struct kvm_vcpu *vcpu) | ^~~~~~~~~~~~~~~~~~ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/mmu.c:31: ../arch/arm64/include/asm/kvm_emulate.h:382:20: note: previous definition of ‘kvm_is_write_fault’ was here 382 | static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu) | ^~~~~~~~~~~~~~~~~~ make[2]: *** [../scripts/Makefile.build:303: arch/arm64/kvm/../../../virt/kvm/arm/mmu.o] Error 1 In file included from ../arch/arm64/kvm/handle_exit.c:31: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/guest.c:32: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/debug.c:26: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/reset.c:34: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/sys_regs_generic_v8.c:27: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/vgic-sys-reg-v3.c:17: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/sys_regs.c:35: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/aarch32.c:26: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:22: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:20: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-its.c:30: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ In file included from ../arch/arm64/kvm/../../../virt/kvm/arm/pmu.c:23: ../arch/arm64/include/asm/kvm_emulate.h: In function ‘kvm_vcpu_sys_get_rt’: ../arch/arm64/include/asm/kvm_emulate.h:379:6: warning: unused variable ‘esr’ [-Wunused-variable] 379 | u32 esr = kvm_vcpu_get_hsr(vcpu); | ^~~ ../arch/arm64/include/asm/kvm_emulate.h:380:1: warning: no return statement in function returning non-void [-Wreturn-type] 380 | } | ^ make[2]: Target '__build' not remade because of errors. make[1]: *** [/linux/Makefile:1074: arch/arm64/kvm] Error 2
On Tue, Sep 29, 2020 at 01:16:34AM +0530, Naresh Kamboju wrote:
On Mon, 28 Sep 2020 at 23:16, Greg KH gregkh@linuxfoundation.org wrote:
On Mon, Sep 28, 2020 at 06:18:50PM +0100, Marc Zyngier wrote:
Commit c4ad98e4b72cb5be30ea282fce935248f2300e62 upstream.
KVM currently assumes that an instruction abort can never be a write. This is in general true, except when the abort is triggered by a S1PTW on instruction fetch that tries to update the S1 page tables (to set AF, for example).
This can happen if the page tables have been paged out and brought back in without seeing a direct write to them (they are thus marked read only), and the fault handling code will make the PT executable(!) instead of writable. The guest gets stuck forever.
In these conditions, the permission fault must be considered as a write so that the Stage-1 update can take place. This is essentially the I-side equivalent of the problem fixed by 60e21a0ef54c ("arm64: KVM: Take S1 walks into account when determining S2 write faults").
Update kvm_is_write_fault() to return true on IABT+S1PTW, and introduce kvm_vcpu_trap_is_exec_fault() that only return true when no faulting on a S1 fault. Additionally, kvm_vcpu_dabt_iss1tw() is renamed to kvm_vcpu_abt_iss1tw(), as the above makes it plain that it isn't specific to data abort.
Signed-off-by: Marc Zyngier maz@kernel.org Reviewed-by: Will Deacon will@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200915104218.1284701-2-maz@kernel.org
Thanks for all 3 of these, now queued up!
stable rc branch 4.19 arm64 build broken.
../arch/arm64/kvm/../../../virt/kvm/arm/mmu.c:1283:13: error: redefinition of ‘kvm_is_write_fault’ 1283 | static bool kvm_is_write_fault(struct kvm_vcpu *vcpu) | ^~~~~~~~~~~~~~~~~~
Reported-by: Naresh Kamboju naresh.kamboju@linaro.org
Thanks, I'll go drop this patch from the 4.19.y queue and wait for a fixed up version from Marc.
greg k-h
On 2020-09-29 08:01, Greg KH wrote:
On Tue, Sep 29, 2020 at 01:16:34AM +0530, Naresh Kamboju wrote:
On Mon, 28 Sep 2020 at 23:16, Greg KH gregkh@linuxfoundation.org wrote:
On Mon, Sep 28, 2020 at 06:18:50PM +0100, Marc Zyngier wrote:
Commit c4ad98e4b72cb5be30ea282fce935248f2300e62 upstream.
KVM currently assumes that an instruction abort can never be a write. This is in general true, except when the abort is triggered by a S1PTW on instruction fetch that tries to update the S1 page tables (to set AF, for example).
This can happen if the page tables have been paged out and brought back in without seeing a direct write to them (they are thus marked read only), and the fault handling code will make the PT executable(!) instead of writable. The guest gets stuck forever.
In these conditions, the permission fault must be considered as a write so that the Stage-1 update can take place. This is essentially the I-side equivalent of the problem fixed by 60e21a0ef54c ("arm64: KVM: Take S1 walks into account when determining S2 write faults").
Update kvm_is_write_fault() to return true on IABT+S1PTW, and introduce kvm_vcpu_trap_is_exec_fault() that only return true when no faulting on a S1 fault. Additionally, kvm_vcpu_dabt_iss1tw() is renamed to kvm_vcpu_abt_iss1tw(), as the above makes it plain that it isn't specific to data abort.
Signed-off-by: Marc Zyngier maz@kernel.org Reviewed-by: Will Deacon will@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200915104218.1284701-2-maz@kernel.org
Thanks for all 3 of these, now queued up!
stable rc branch 4.19 arm64 build broken.
../arch/arm64/kvm/../../../virt/kvm/arm/mmu.c:1283:13: error: redefinition of ‘kvm_is_write_fault’ 1283 | static bool kvm_is_write_fault(struct kvm_vcpu *vcpu) | ^~~~~~~~~~~~~~~~~~
Reported-by: Naresh Kamboju naresh.kamboju@linaro.org
Thanks, I'll go drop this patch from the 4.19.y queue and wait for a fixed up version from Marc.
Right. I have no idea what I tested yesterday, but clearly this didn't stand a chance to even compile on arm64... :-( Funnily enough, 32bit ARM (which nobody cares about when it comes to KVM) was just fine. Bah.
Apologies for the noise, v2 coming once I have had my second coffee...
M.