[PATCH] target/i386: ensure EXCP0D_GPF is propagated back to the guest

Mark Cave-Ayland posted 1 patch 2 years, 6 months ago
Test checkpatch passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20211030132943.21362-1-mark.cave-ayland@ilande.co.uk
Maintainers: Eduardo Habkost <ehabkost@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>
target/i386/tcg/sysemu/excp_helper.c | 4 ++++
1 file changed, 4 insertions(+)
[PATCH] target/i386: ensure EXCP0D_GPF is propagated back to the guest
Posted by Mark Cave-Ayland 2 years, 6 months ago
In the case where mmu_translate() returns EXCP0D_GPF ensure that handle_mmu_fault()
returns immediately to propagate the fault back to the guest instead of returning
EXCP0E_PAGE.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: 661ff4879e ("target/i386: extract mmu_translate")
Closes: https://gitlab.com/qemu-project/qemu/-/issues/394
---

[Paolo: this appears to fix the regression booting Windows 7 on TCG that appeared in 6.1
 as per the above Gitlab issue. Unfortunately as I'm not really familiar with x86 it will
 probably need a better implementation/description but it should at least indicate what
 the problem is.]

 target/i386/tcg/sysemu/excp_helper.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c
index 7af887be4d..0170f7f791 100644
--- a/target/i386/tcg/sysemu/excp_helper.c
+++ b/target/i386/tcg/sysemu/excp_helper.c
@@ -439,6 +439,10 @@ static int handle_mmu_fault(CPUState *cs, vaddr addr, int size,
                                 prot, mmu_idx, page_size);
         return 0;
     } else {
+        if (cs->exception_index == EXCP0D_GPF) {
+            return 1;
+        }
+
         if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
             /* cr2 is not modified in case of exceptions */
             x86_stq_phys(cs,
-- 
2.20.1


Re: [PATCH] target/i386: ensure EXCP0D_GPF is propagated back to the guest
Posted by Mark Cave-Ayland 2 years, 6 months ago
On 30/10/2021 14:29, Mark Cave-Ayland wrote:

> In the case where mmu_translate() returns EXCP0D_GPF ensure that handle_mmu_fault()
> returns immediately to propagate the fault back to the guest instead of returning
> EXCP0E_PAGE.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> Fixes: 661ff4879e ("target/i386: extract mmu_translate")
> Closes: https://gitlab.com/qemu-project/qemu/-/issues/394
> ---
> 
> [Paolo: this appears to fix the regression booting Windows 7 on TCG that appeared in 6.1
>   as per the above Gitlab issue. Unfortunately as I'm not really familiar with x86 it will
>   probably need a better implementation/description but it should at least indicate what
>   the problem is.]
> 
>   target/i386/tcg/sysemu/excp_helper.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c
> index 7af887be4d..0170f7f791 100644
> --- a/target/i386/tcg/sysemu/excp_helper.c
> +++ b/target/i386/tcg/sysemu/excp_helper.c
> @@ -439,6 +439,10 @@ static int handle_mmu_fault(CPUState *cs, vaddr addr, int size,
>                                   prot, mmu_idx, page_size);
>           return 0;
>       } else {
> +        if (cs->exception_index == EXCP0D_GPF) {
> +            return 1;
> +        }
> +
>           if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
>               /* cr2 is not modified in case of exceptions */
>               x86_stq_phys(cs,

Revisiting this I think the real issue is that mmu_translate() sets env->error_code 
to 0 and cs->exception_index to EXCP0D_GPF in target/i386/tcg/sysemu/excp_helper.c at 
line 102, so if this path is taken then mmu_translate() can change the vCPU state 
which doesn't seem right.

Presumably the real solution is to update the code in handle_mmu_fault() to detect 
when mmu_translate() returns 1 and check certain flags in env to determine whether 
either a EXCP0D_GPF or EXCP0E_PAGE exception should be generated?


ATB,

Mark.