]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
target/loongarch: Fix raise_mmu_exception() set wrong exception_index
authorSong Gao <gaosong@loongson.cn>
Tue, 1 Nov 2022 06:53:31 +0000 (14:53 +0800)
committerSong Gao <gaosong@loongson.cn>
Fri, 4 Nov 2022 09:09:50 +0000 (17:09 +0800)
When the address is invalid address, We should set exception_index
according to MMUAccessType, and EXCCODE_ADEF need't update badinstr.
Otherwise, The system enters an infinite loop. e.g:
run test.c on system mode
test.c:
    #include<stdio.h>

    void (*func)(int *);

    int main()
    {
        int i = 8;
        void *ptr = (void *)0x4000000000000000;
        func = ptr;
        func(&i);
        return 0;
    }

Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20221101073210.3934280-2-gaosong@loongson.cn>

target/loongarch/cpu.c
target/loongarch/tlb_helper.c

index b28aaed5ba624b86700d72a911dae022e903b967..1512664214573d8b45aeef18d5dfb94c7ed55391 100644 (file)
@@ -177,6 +177,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
         }
         QEMU_FALLTHROUGH;
     case EXCCODE_PIF:
+    case EXCCODE_ADEF:
         cause = cs->exception_index;
         update_badinstr = 0;
         break;
index 610b6d123c59c6d9e16eae9fd2b7b6736f0382b4..d2f8fb0c609cd762c4694f0a560e1d06d80eded6 100644 (file)
@@ -229,7 +229,8 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
     switch (tlb_error) {
     default:
     case TLBRET_BADADDR:
-        cs->exception_index = EXCCODE_ADEM;
+        cs->exception_index = access_type == MMU_INST_FETCH
+                              ? EXCCODE_ADEF : EXCCODE_ADEM;
         break;
     case TLBRET_NOMATCH:
         /* No TLB match for a mapped address */
@@ -643,7 +644,7 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     CPULoongArchState *env = &cpu->env;
     hwaddr physical;
     int prot;
-    int ret = TLBRET_BADADDR;
+    int ret;
 
     /* Data access */
     ret = get_physical_address(env, &physical, &prot, address,