https://piazza.com/class/i5j09fnsl7k5x0?cid=757
我对该问题的理解,欢迎大家继续讨论。
1、lab的代码注释里这样描述3个flag bits:
-- The P flag (bit 0) indicates whether the exception was due to a not-present page (0)
or to either an access rights violation or the use of a reserved bit (1).
-- The W/R flag (bit 1) indicates whether the memory access that caused the exception
was a read (0) or write (1).
-- The U/S flag (bit 2) indicates whether the processor was executing at user mode (1)
or supervisor mode (0) at the time of the exception.
2、Intel Manual的相关描述,截取片段:

小结intel的文档内容:
- 造成page fault有两种情况
- 线性地址转换无效;
- 线性地址转换有效,但权限不合法。
- 线性地址转换无效的原因
- error code的P位
- 如果页表项的P位为0,则error code的P位为0。
3、清晰的error code的图表示

4、结论
- 从文档和图示,基本能得知x86的page-fault及其发生时的error code的工作。
- error code的P位
- P位为0时,表示page-fault缺页(准确来说,是entry的P位为0)。
- P位为1时,则不是因为缺页,而是因为page-level protection violation,即我们应该检测后面的标志位。
- ucore的do_pgfault中
- P为0的处理,即case 0和case 2,作为缺页处理,没问题。
- P为1时,这时应该检测后面的标志位。先看case 1,ucore直接failed,也就是说,非缺页的读操作产生的page fault,ucore不做处理(后面的U/S、RSVD或I/D的错误),可以理解,没问题。再看看case 3,ucore先检测虚地址管理vma的写位,如果vma有写的权限,而发生了page fault,那么可能是entry没有写权限,因此可以尝试在entry添加上写权限。问题在于,如果不是因为entry的写权限造成的page fault的呢?此时ucore将陷入死循环!
- 简单总结
- ucore的page fault处理P=1,W/R=1的情况时,只处理了因为entry缺少写权限的情况,而没有考虑entry有写权限而由其它权限造成的异常,该处理可能导致ucore陷入死循环。赞同高思达同学对此处的质疑。
5、参考
- Intel 64 and IA-32 ASD’s Manual 3A, Chapter 4, 4.7 PAGE-FAULT EXCEPTIONS
- Intel 64 and IA-32 ASD’s Manual 3A, Chapter 6, 6.15 EXCEPTION AND INTERRUPT REFERENCE