aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2018-12-03 12:03:50 -0500
committerIngo Molnar <mingo@kernel.org>2018-12-17 12:54:27 -0500
commit83b4e39146aa70913580966e0f2b78b7c3492760 (patch)
tree9e05cc0576a9bfb239380d40c48abfb281bd1e59
parent935f5839827ef54b53406e80906f7c355eb73c1b (diff)
x86/mm/cpa: Make cpa_data::numpages invariant
Make sure __change_page_attr_set_clr() doesn't modify cpa->numpages. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rik van Riel <riel@surriel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tom.StDenis@amd.com Cc: dave.hansen@intel.com Link: http://lkml.kernel.org/r/20181203171043.493000228@infradead.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/mm/pageattr.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 351874259a71..12b69263e501 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -1625,14 +1625,15 @@ static int cpa_process_alias(struct cpa_data *cpa)
1625static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) 1625static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
1626{ 1626{
1627 unsigned long numpages = cpa->numpages; 1627 unsigned long numpages = cpa->numpages;
1628 int ret; 1628 unsigned long rempages = numpages;
1629 int ret = 0;
1629 1630
1630 while (numpages) { 1631 while (rempages) {
1631 /* 1632 /*
1632 * Store the remaining nr of pages for the large page 1633 * Store the remaining nr of pages for the large page
1633 * preservation check. 1634 * preservation check.
1634 */ 1635 */
1635 cpa->numpages = numpages; 1636 cpa->numpages = rempages;
1636 /* for array changes, we can't use large page */ 1637 /* for array changes, we can't use large page */
1637 if (cpa->flags & (CPA_ARRAY | CPA_PAGES_ARRAY)) 1638 if (cpa->flags & (CPA_ARRAY | CPA_PAGES_ARRAY))
1638 cpa->numpages = 1; 1639 cpa->numpages = 1;
@@ -1643,12 +1644,12 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
1643 if (!debug_pagealloc_enabled()) 1644 if (!debug_pagealloc_enabled())
1644 spin_unlock(&cpa_lock); 1645 spin_unlock(&cpa_lock);
1645 if (ret) 1646 if (ret)
1646 return ret; 1647 goto out;
1647 1648
1648 if (checkalias) { 1649 if (checkalias) {
1649 ret = cpa_process_alias(cpa); 1650 ret = cpa_process_alias(cpa);
1650 if (ret) 1651 if (ret)
1651 return ret; 1652 goto out;
1652 } 1653 }
1653 1654
1654 /* 1655 /*
@@ -1656,11 +1657,15 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
1656 * CPA operation. Either a large page has been 1657 * CPA operation. Either a large page has been
1657 * preserved or a single page update happened. 1658 * preserved or a single page update happened.
1658 */ 1659 */
1659 BUG_ON(cpa->numpages > numpages || !cpa->numpages); 1660 BUG_ON(cpa->numpages > rempages || !cpa->numpages);
1660 numpages -= cpa->numpages; 1661 rempages -= cpa->numpages;
1661 cpa->curpage += cpa->numpages; 1662 cpa->curpage += cpa->numpages;
1662 } 1663 }
1663 return 0; 1664
1665out:
1666 /* Restore the original numpages */
1667 cpa->numpages = numpages;
1668 return ret;
1664} 1669}
1665 1670
1666/* 1671/*