Commit f76cfa3c authored by Andrea Arcangeli's avatar Andrea Arcangeli Committed by Ingo Molnar

x86/mm/cpa: Convert noop to functional fix

Commit:

  a8aed3e0 ("x86/mm/pageattr: Prevent PSE and GLOABL leftovers to confuse pmd/pte_present and pmd_huge")

introduced a valid fix but one location that didn't trigger the bug that
lead to finding those (small) problems, wasn't updated using the
right variable.

The wrong variable was also initialized for no good reason, that
may have been the source of the confusion. Remove the noop
initialization accordingly.

Commit a8aed3e0 also erroneously removed one canon_pgprot pass meant
to clear pmd bitflags not supported in hardware by older CPUs, that
automatically gets corrected by this patch too by applying it to the right
variable in the new location.
Reported-by: default avatarStefan Bader <stefan.bader@canonical.com>
Signed-off-by: default avatarAndrea Arcangeli <aarcange@redhat.com>
Acked-by: default avatarBorislav Petkov <bp@alien8.de>
Cc: Andy Whitcroft <apw@canonical.com>
Cc: Mel Gorman <mgorman@suse.de>
Link: http://lkml.kernel.org/r/1365600505-19314-1-git-send-email-aarcange@redhat.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 511ba86e
...@@ -467,7 +467,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, ...@@ -467,7 +467,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
* We are safe now. Check whether the new pgprot is the same: * We are safe now. Check whether the new pgprot is the same:
*/ */
old_pte = *kpte; old_pte = *kpte;
old_prot = new_prot = req_prot = pte_pgprot(old_pte); old_prot = req_prot = pte_pgprot(old_pte);
pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr); pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr);
pgprot_val(req_prot) |= pgprot_val(cpa->mask_set); pgprot_val(req_prot) |= pgprot_val(cpa->mask_set);
...@@ -478,12 +478,12 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, ...@@ -478,12 +478,12 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
* a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL * a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL
* for the ancient hardware that doesn't support it. * for the ancient hardware that doesn't support it.
*/ */
if (pgprot_val(new_prot) & _PAGE_PRESENT) if (pgprot_val(req_prot) & _PAGE_PRESENT)
pgprot_val(new_prot) |= _PAGE_PSE | _PAGE_GLOBAL; pgprot_val(req_prot) |= _PAGE_PSE | _PAGE_GLOBAL;
else else
pgprot_val(new_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); pgprot_val(req_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL);
new_prot = canon_pgprot(new_prot); req_prot = canon_pgprot(req_prot);
/* /*
* old_pte points to the large page base address. So we need * old_pte points to the large page base address. So we need
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment