|
@@ -933,8 +933,17 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte)
|
|
|
* cross-processor TLB flush, even if no stale TLB entries exist
|
|
|
* on other processors.
|
|
|
*
|
|
|
+ * Spurious faults may only occur if the TLB contains an entry with
|
|
|
+ * fewer permission than the page table entry. Non-present (P = 0)
|
|
|
+ * and reserved bit (R = 1) faults are never spurious.
|
|
|
+ *
|
|
|
* There are no security implications to leaving a stale TLB when
|
|
|
* increasing the permissions on a page.
|
|
|
+ *
|
|
|
+ * Returns non-zero if a spurious fault was handled, zero otherwise.
|
|
|
+ *
|
|
|
+ * See Intel Developer's Manual Vol 3 Section 4.10.4.3, bullet 3
|
|
|
+ * (Optional Invalidation).
|
|
|
*/
|
|
|
static noinline int
|
|
|
spurious_fault(unsigned long error_code, unsigned long address)
|
|
@@ -945,8 +954,17 @@ spurious_fault(unsigned long error_code, unsigned long address)
|
|
|
pte_t *pte;
|
|
|
int ret;
|
|
|
|
|
|
- /* Reserved-bit violation or user access to kernel space? */
|
|
|
- if (error_code & (PF_USER | PF_RSVD))
|
|
|
+ /*
|
|
|
+ * Only writes to RO or instruction fetches from NX may cause
|
|
|
+ * spurious faults.
|
|
|
+ *
|
|
|
+ * These could be from user or supervisor accesses but the TLB
|
|
|
+ * is only lazily flushed after a kernel mapping protection
|
|
|
+ * change, so user accesses are not expected to cause spurious
|
|
|
+ * faults.
|
|
|
+ */
|
|
|
+ if (error_code != (PF_WRITE | PF_PROT)
|
|
|
+ && error_code != (PF_INSTR | PF_PROT))
|
|
|
return 0;
|
|
|
|
|
|
pgd = init_mm.pgd + pgd_index(address);
|