oscourse-tsinghua / rcore_plus

Rust version of THU uCore OS. Linux compatible.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Linear mapping does not work on raspi3 real machine

equation314 opened this issue · comments

Commit: e63f11d
Build command:

make arch=aarch64 LOG=info graphic=on

Serial port log (with some debug info):

Hello Raspberry Pi!
[ INFO][-] FrameAllocator init end
[ INFO][-] heap init end
[ INFO][-] memory: init end
[ INFO][-] framebuffer: init end
Framebuffer {
    fb_info: FramebufferInfo {
        xres: 0x500,
        yres: 0x2d0,
        xres_virtual: 0x500,
        yres_virtual: 0x2d0,
        xoffset: 0x0,
        yoffset: 0x0,
        depth: 0x10,
        pitch: 0xa00,
        bus_addr: 0xfea38000,
        screen_size: 0x1c2000
    },
    color_depth: ColorDepth16,
    color_config: RGB565,
    base_addr: 0xffff00003ea38000
}
[ INFO][-] timer: init end
[ INFO][-] console: init end

    ____                __   ____  _____
   / __ \ __  __ _____ / /_ / __ \/ ___/
  / /_/ // / / // ___// __// / / /\__ \
 / _, _// /_/ /(__  )/ /_ / /_/ /___/ /
/_/ |_| \__,_//____/ \__/ \____//____/

[ INFO][-] SFS linked to kernel, from ffff000000158088 to ffff000001fee290
[ERROR][-] MAP BEGIN 0 126cec
[ERROR][-] MAP END
[ERROR][-] MAP BEGIN 137780 5648
[ERROR][-] MAP END
[ERROR][-] MAP BEGIN 7ffffff00000 fc000
[ERROR][-] MAP END
[ERROR][-] MAP BEGIN 7fffffffc000 4000
[ERROR][-] MAP END
[ INFO][-] process: init end
[ERROR][0] ESR: 0x8200000e, Syndrome: InstructionAbort { kind: Permission, level: 2 }, elr: 84dc
[ WARN][0] 
handle_page_fault OK @ 0x84dc elr 0x84dc
[ERROR][0] ESR: 0x92000007, Syndrome: DataAbort { kind: Translation, level: 3 }, elr: 8588
[ WARN][0] 
handle_page_fault OK @ 0x13ac38 elr 0x8588
[ERROR][0] ESR: 0x92000007, Syndrome: DataAbort { kind: Translation, level: 3 }, elr: 85a4
[ WARN][0] 
handle_page_fault OK @ 0x40 elr 0x85a4
[ERROR][0] ESR: 0x92000047, Syndrome: DataAbort { kind: Translation, level: 3 }, elr: 867c
[ WARN][0] 
handle_page_fault OK @ 0x137780 elr 0x867c
[ERROR][0] ESR: 0x8200000e, Syndrome: InstructionAbort { kind: Permission, level: 2 }, elr: 867c
[ERROR][0] 
EXCEPTION: Page Fault @ 0x867c elr 0x867c
[ERROR][0] TrapFrame {
    elr: 0x867c,
    spsr: 0x60000340,
    sp: 0x7ffffffffd70,
    tpidr: 0x0,
    x1to29: [
        0x1c8,
        0x84a8,
        0x875c,
        0x7fffffffff70,
        0x137780,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0,
        0x0
    ],
    __reserved: 0x0,
    x30: 0x0,
    x0: 0x0
}
[ERROR][0] On CPU0 Thread 0
[ERROR][-] UNMAP BEGIN 0 126cec
[ERROR][-] UNMAP END
[ERROR][-] UNMAP BEGIN 137780 5648
[ERROR][-] UNMAP END
[ERROR][-] UNMAP BEGIN 7ffffff00000 fc000
[ERROR][-] UNMAP END
[ERROR][-] UNMAP BEGIN 7fffffffc000 4000
[ERROR][-] UNMAP END
[ INFO][-] PageTable dropping: PhysFrame[4KiB](0x3b3ff000)
commented

可以复现

在trap handler里把四级页表打出来,没看出问题
(感觉是玄学)

发生此问题的主要原因是:上下文切换到内核线程时,往 TLB 中加入了 gloabl 属性的某项,导致切换为用户线程后访问同一虚拟地址时,根据 TLB 中错误的该项,将该虚拟地址映射为了错误的物理地址。

具体地,对于位于低地址空间的 0x8000 的虚拟地址,内核线程的页表会将其映射为相同的物理地址 0x8000。当上下文切换到内核线程时,由于某些原因(可能是对 [0~0x20000] 这 2MB 大页内的地址进行了访存,暂未查明)将 0x80000x8000 的映射加入了 TLB,并且属性为 global。切换为用户线程后,用户程序对 0x8000 页内的某一虚拟地址进行了取指,此时虽有 ASID 机制,但 TLB 中的那项属性为 global,仍然可以匹配成功,于是仍将该虚拟页映射到了 0x8000 的错误物理页帧,从而取出了错误的数据,将其作为了非法的指令,导致了 page fault。

d56a889 的解决方法:将内核线程的 ttbr0_el1 设为空,使得内核线程无法访问低地址空间。