|
499 | 499 | * this happens is quite subtle, read below */
|
500 | 500 | .macro make_insert_tlb spc,pte,prot,tmp
|
501 | 501 | space_to_prot \spc \prot /* create prot id from space */
|
| 502 | + |
| 503 | +#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT |
| 504 | + /* need to drop DMB bit, as it's used as SPECIAL flag */ |
| 505 | + depi 0,_PAGE_SPECIAL_BIT,1,\pte |
| 506 | +#endif |
| 507 | + |
502 | 508 | /* The following is the real subtlety. This is depositing
|
503 | 509 | * T <-> _PAGE_REFTRAP
|
504 | 510 | * D <-> _PAGE_DIRTY
|
|
511 | 517 | * Finally, _PAGE_READ goes in the top bit of PL1 (so we
|
512 | 518 | * trigger an access rights trap in user space if the user
|
513 | 519 | * tries to read an unreadable page */
|
514 |
| -#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT |
515 |
| - /* need to drop DMB bit, as it's used as SPECIAL flag */ |
516 |
| - depi 0,_PAGE_SPECIAL_BIT,1,\pte |
517 |
| -#endif |
518 | 520 | depd \pte,8,7,\prot
|
519 | 521 |
|
520 | 522 | /* PAGE_USER indicates the page can be read with user privileges,
|
521 | 523 | * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
|
522 |
| - * contains _PAGE_READ) */ |
| 524 | + * contains _PAGE_READ). While the kernel can't directly write |
| 525 | + * user pages which have _PAGE_WRITE zero, it can read pages |
| 526 | + * which have _PAGE_READ zero (PL <= PL1). Thus, the kernel |
| 527 | + * exception fault handler doesn't trigger when reading pages |
| 528 | + * that aren't user read accessible */ |
523 | 529 | extrd,u,*= \pte,_PAGE_USER_BIT+32,1,%r0
|
524 | 530 | depdi 7,11,3,\prot
|
| 531 | + |
525 | 532 | /* If we're a gateway page, drop PL2 back to zero for promotion
|
526 | 533 | * to kernel privilege (so we can execute the page as kernel).
|
527 | 534 | * Any privilege promotion page always denys read and write */
|
|
0 commit comments