Messages in this thread | | | Subject | Re: "kernel ade access" oops on LoongArch | From | Xi Ruoyao <> | Date | Wed, 15 Feb 2023 20:51:38 +0800 |
| |
On Wed, 2023-02-15 at 19:52 +0800, Xi Ruoyao wrote: > On Wed, 2023-02-15 at 16:35 +0800, Xi Ruoyao wrote: > > On Wed, 2023-02-15 at 16:25 +0800, Youling Tang wrote: > > > Can you modify the kernel as follows and test it, so as to avoid > > > possible relationship with the exception table data link position > > > and > > > alignment rules (or use EXCEPTION_TABLE(12))? > > > > > > --- a/arch/loongarch/kernel/vmlinux.lds.S > > > +++ b/arch/loongarch/kernel/vmlinux.lds.S > > > @@ -4,7 +4,6 @@ > > > #include <asm/thread_info.h> > > > > > > #define PAGE_SIZE _PAGE_SIZE > > > -#define RO_EXCEPTION_TABLE_ALIGN 4 > > > > > > /* > > > * Put .bss..swapper_pg_dir as the first thing in .bss. This > > > will > > > @@ -54,6 +53,8 @@ SECTIONS > > > . = ALIGN(PECOFF_SEGMENT_ALIGN); > > > _etext = .; > > > > > > + EXCEPTION_TABLE(16) > > > + > > > > It seems the kernel refuses to boot after the change, but I'm not > > completely sure: I'm 5 km away from the board and operating it via > > ssh > > so maybe it's a reboot failure or network failure. I'll report > > again in > > the evening. > > It was a reboot failure. > > Now it has booted successfully, but the stack trace still shows (during > the 25th run of the make test t=... command).
Ouch, I know what's happening...
In the architecture-independent code we have something like
extern struct exception_table_entry a[], b[]; bsearch(a, b - a);
According to the C standard, when you write "b - a" where a and b are pointers to type T, "b" and "a" must be pointers to elements in the same array of T. So the compiler can assume ((uintptr_t)b - (uintptr_t)a) % 12 == 0 and optimize "b - a" to something like
(((uintptr_t)b - (uintptr_t)a) >> 2) * inv3
Here inv3 is the inversion of 3 in the modulo-2**64 integer ring, so the compiler can avoid an expensive divide instruction. But in my vmlinux ((uintptr_t)b - (uintptr_t)a) is somehow not a multiple of 12:
(gdb) p ((uintptr_t)__stop___ex_table - (uintptr_t)__start___ex_table) % sizeof(struct exception_table_entry) $9 = 8
So I guess
#define RO_EXCEPTION_TABLE_ALIGN 12
will work. I'll take a try...
-- Xi Ruoyao <xry111@xry111.site> School of Aerospace Science and Technology, Xidian University
| |