tests/mmu: Add a test of PTE refetching on permission error
authorPaul Mackerras <paulus@ozlabs.org>
Thu, 7 May 2020 10:12:46 +0000 (20:12 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Fri, 8 May 2020 02:12:02 +0000 (12:12 +1000)
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
tests/mmu/mmu.c
tests/test_mmu.bin
tests/test_mmu.console_out

index 994ffe3bde679cf36e5319337b0e8e35635132cc..8281b044299b6f9439a18181eb8525cddbbc8b37 100644 (file)
@@ -145,8 +145,6 @@ void map(void *ea, void *pa, unsigned long perm_attr)
                free_ptr += 512 * sizeof(unsigned long);
        }
        ptep = read_pgd(i);
-       if (ptep[j])
-               do_tlbie(((unsigned long)ea & ~0xfff), 0);
        store_pte(&ptep[j], 0xc000000000000000 | ((unsigned long)pa & 0x00fffffffffff000) | perm_attr);
        eas_mapped[neas_mapped++] = ea;
 }
@@ -569,6 +567,7 @@ int mmu_test_17(void)
        if (mfspr(SRR0) != (long) ptr || mfspr(SRR1) != 0x00040020)
                return 2;
        /* create a PTE without ref or execute permission */
+       unmap((void *)ptr);
        map((void *)ptr, (void *)mem, 0);
        /* this should fail */
        if (test_exec(2, ptr, MSR_IR))
@@ -599,6 +598,28 @@ int mmu_test_18(void)
        return 0;
 }
 
+int mmu_test_19(void)
+{
+       long *mem = (long *) 0x8000;
+       long *ptr = (long *) 0x124000;
+
+       *mem = 0x123456789abcdef0;
+       /* create PTE with read but not write permission */
+       map(ptr, mem, REF | PERM_RD);
+       /* this should fail and create a TLB entry */
+       if (test_write(ptr, 0xdeadbeef0dd1))
+               return 1;
+       /* DAR and DSISR should be set correctly */
+       if (mfspr(DAR) != (long)ptr || mfspr(DSISR) != 0x0a000000)
+               return 2;
+       /* Update the PTE to have write permission */
+       map(ptr, mem, REF | CHG | PERM_RD | PERM_WR);
+       /* this should succeed */
+       if (!test_write(ptr, 0xdeadbeef0dd1))
+               return 3;
+       return 0;
+}
+
 int fail = 0;
 
 void do_test(int num, int (*test)(void))
@@ -616,7 +637,7 @@ void do_test(int num, int (*test)(void))
                fail = 1;
                print_string("FAIL ");
                putchar(ret + '0');
-               if (num <= 10) {
+               if (num <= 10 || num == 19) {
                        print_string(" DAR=");
                        print_hex(mfspr(DAR));
                        print_string(" DSISR=");
@@ -654,6 +675,7 @@ int main(void)
        do_test(16, mmu_test_16);
        do_test(17, mmu_test_17);
        do_test(18, mmu_test_18);
+       do_test(19, mmu_test_19);
 
        return fail;
 }
index 416ae706ac754e79daab704110bf8e4c8379c8f6..a1861b22dbbdfc857e7d512d9a924efe9a997bbb 100755 (executable)
Binary files a/tests/test_mmu.bin and b/tests/test_mmu.bin differ
index a5c08eadcfbab4cc3dc5837d8e03d4275188d755..cb4ad85e7ea67db5012d3d9bfc0e42d0b7461f65 100644 (file)
@@ -16,3 +16,4 @@ test 15:PASS
 test 16:PASS\r
 test 17:PASS\r
 test 18:PASS\r
+test 19:PASS\r