来自用户空间的陷阱

作者: 橡树人 | 来源:发表于2020-12-18 23:19 被阅读0次

    问题1:内核如何处理来自用户空间的陷阱?

    进入内核空间的路径:先uservec,后usertrap
    返回用户空间的路径:先usertrapret,后userret

    问题2:函数uservec都做了哪些事?

    • 保存除了pc之外的所有寄存器的值;
    • 切换内核页表;
    • 切换内核栈;
    • 调用usertrap

    问题3:函数usertrap都做了哪些事?

    • 判断陷阱的原因;
    • 处理陷阱;
    • 从内核中返回,即调用usertrapret

    问题4:函数usertrapret都做了哪些事?

    为下一次来自用户空间的陷阱做好准备,包括:

    • 修改stvec指向uservec
    • 准备好trapframe字段;
    • 设置sepc为之前保存的用户pc
    • 调用userret

    问题5:函数userret都做了哪些事?

    • 切换用户页表;
    • 恢复用户寄存器的值;
    • sscratch中保存用户trapframe的地址;
    • 使用sret指令返回到用户空间;

    问题6:进程的trapframe有哪些性质?

    • 什么时候创建?
      创建进程时,分配一个页用于进程的trapframe,并映射到用户的虚拟地址TRAPFRAME
    • 相关的指针有哪些?
      p->trapframe

    问题7:在处理来自用户空间的陷阱时,是如何使用trapframe的?

    • 进入内核空间时,在trapframe上保存属于用户空间的寄存器的值;
    • 返回用户空间时,保存trapframe为下次陷阱做好准备;
      比如,当前进程的内核栈指针、usertrap的地址、内核页表的地址等;

    问题8:uservec函数和trampoline页的联系?

    • uservec函数在trampline页上。
    • 基于事实:trampoline页被映射到内核页表和用户页表的虚拟地址是相同的,所以在修改satp后,uservec可继续执行。

    问题9:陷阱帧trapframe上有哪些数据?

    • 当前进程内核栈的指针;
    • 当前CPU的hartid;
    • usertrap的地址;
    • 内核页表的地址;

    问题10:在处理来自用户空间的陷阱过程中,a0sscratch进行了几次交换?

    两次,分别是

    • 在进入内核的过程中,uservec在一开始就使用csrrw指令交换a0sscratch
      交换后,原用户空间的a0值被保存到sscratch中,即sscratch此时的值是陷阱发生时用户空间的a0a0的值是内核先前在sscratch中放入的值。
    • 在返回用户空间的过程中,userret交换a0sscratch
      交换前,sscratch中记录的是陷阱发生时保存的用户空间的a0值,交换后,a0的值就是先前保存的用户空间的值;
      交换前,在usertrapret调用userret时,给a0传递了指向TRAPFRAME的指针,交换后,sscratch中记录的就是指向TRAPFRAME的指针;

    相关文章

      网友评论

        本文标题:来自用户空间的陷阱

        本文链接:https://www.haomeiwen.com/subject/zgrfnktx.html