diff options
-rw-r--r-- | arch/x86/mm/pageattr.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 87c0d361c6d4..9f7e1b445e66 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -1304,12 +1304,6 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) | |||
1304 | return 0; | 1304 | return 0; |
1305 | } | 1305 | } |
1306 | 1306 | ||
1307 | static inline int cache_attr(pgprot_t attr) | ||
1308 | { | ||
1309 | return pgprot_val(attr) & | ||
1310 | (_PAGE_PAT | _PAGE_PWT | _PAGE_PCD); | ||
1311 | } | ||
1312 | |||
1313 | static int change_page_attr_set_clr(unsigned long *addr, int numpages, | 1307 | static int change_page_attr_set_clr(unsigned long *addr, int numpages, |
1314 | pgprot_t mask_set, pgprot_t mask_clr, | 1308 | pgprot_t mask_set, pgprot_t mask_clr, |
1315 | int force_split, int in_flag, | 1309 | int force_split, int in_flag, |
@@ -1390,7 +1384,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, | |||
1390 | * No need to flush, when we did not set any of the caching | 1384 | * No need to flush, when we did not set any of the caching |
1391 | * attributes: | 1385 | * attributes: |
1392 | */ | 1386 | */ |
1393 | cache = cache_attr(mask_set); | 1387 | cache = !!pgprot2cachemode(mask_set); |
1394 | 1388 | ||
1395 | /* | 1389 | /* |
1396 | * On success we use CLFLUSH, when the CPU supports it to | 1390 | * On success we use CLFLUSH, when the CPU supports it to |
@@ -1445,7 +1439,8 @@ int _set_memory_uc(unsigned long addr, int numpages) | |||
1445 | * for now UC MINUS. see comments in ioremap_nocache() | 1439 | * for now UC MINUS. see comments in ioremap_nocache() |
1446 | */ | 1440 | */ |
1447 | return change_page_attr_set(&addr, numpages, | 1441 | return change_page_attr_set(&addr, numpages, |
1448 | __pgprot(_PAGE_CACHE_UC_MINUS), 0); | 1442 | cachemode2pgprot(_PAGE_CACHE_MODE_UC_MINUS), |
1443 | 0); | ||
1449 | } | 1444 | } |
1450 | 1445 | ||
1451 | int set_memory_uc(unsigned long addr, int numpages) | 1446 | int set_memory_uc(unsigned long addr, int numpages) |
@@ -1474,7 +1469,7 @@ out_err: | |||
1474 | EXPORT_SYMBOL(set_memory_uc); | 1469 | EXPORT_SYMBOL(set_memory_uc); |
1475 | 1470 | ||
1476 | static int _set_memory_array(unsigned long *addr, int addrinarray, | 1471 | static int _set_memory_array(unsigned long *addr, int addrinarray, |
1477 | unsigned long new_type) | 1472 | enum page_cache_mode new_type) |
1478 | { | 1473 | { |
1479 | int i, j; | 1474 | int i, j; |
1480 | int ret; | 1475 | int ret; |
@@ -1484,17 +1479,19 @@ static int _set_memory_array(unsigned long *addr, int addrinarray, | |||
1484 | */ | 1479 | */ |
1485 | for (i = 0; i < addrinarray; i++) { | 1480 | for (i = 0; i < addrinarray; i++) { |
1486 | ret = reserve_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE, | 1481 | ret = reserve_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE, |
1487 | new_type, NULL); | 1482 | cachemode2protval(new_type), NULL); |
1488 | if (ret) | 1483 | if (ret) |
1489 | goto out_free; | 1484 | goto out_free; |
1490 | } | 1485 | } |
1491 | 1486 | ||
1492 | ret = change_page_attr_set(addr, addrinarray, | 1487 | ret = change_page_attr_set(addr, addrinarray, |
1493 | __pgprot(_PAGE_CACHE_UC_MINUS), 1); | 1488 | cachemode2pgprot(_PAGE_CACHE_MODE_UC_MINUS), |
1489 | 1); | ||
1494 | 1490 | ||
1495 | if (!ret && new_type == _PAGE_CACHE_WC) | 1491 | if (!ret && new_type == _PAGE_CACHE_MODE_WC) |
1496 | ret = change_page_attr_set_clr(addr, addrinarray, | 1492 | ret = change_page_attr_set_clr(addr, addrinarray, |
1497 | __pgprot(_PAGE_CACHE_WC), | 1493 | cachemode2pgprot( |
1494 | _PAGE_CACHE_MODE_WC), | ||
1498 | __pgprot(_PAGE_CACHE_MASK), | 1495 | __pgprot(_PAGE_CACHE_MASK), |
1499 | 0, CPA_ARRAY, NULL); | 1496 | 0, CPA_ARRAY, NULL); |
1500 | if (ret) | 1497 | if (ret) |
@@ -1511,13 +1508,13 @@ out_free: | |||
1511 | 1508 | ||
1512 | int set_memory_array_uc(unsigned long *addr, int addrinarray) | 1509 | int set_memory_array_uc(unsigned long *addr, int addrinarray) |
1513 | { | 1510 | { |
1514 | return _set_memory_array(addr, addrinarray, _PAGE_CACHE_UC_MINUS); | 1511 | return _set_memory_array(addr, addrinarray, _PAGE_CACHE_MODE_UC_MINUS); |
1515 | } | 1512 | } |
1516 | EXPORT_SYMBOL(set_memory_array_uc); | 1513 | EXPORT_SYMBOL(set_memory_array_uc); |
1517 | 1514 | ||
1518 | int set_memory_array_wc(unsigned long *addr, int addrinarray) | 1515 | int set_memory_array_wc(unsigned long *addr, int addrinarray) |
1519 | { | 1516 | { |
1520 | return _set_memory_array(addr, addrinarray, _PAGE_CACHE_WC); | 1517 | return _set_memory_array(addr, addrinarray, _PAGE_CACHE_MODE_WC); |
1521 | } | 1518 | } |
1522 | EXPORT_SYMBOL(set_memory_array_wc); | 1519 | EXPORT_SYMBOL(set_memory_array_wc); |
1523 | 1520 | ||
@@ -1527,10 +1524,12 @@ int _set_memory_wc(unsigned long addr, int numpages) | |||
1527 | unsigned long addr_copy = addr; | 1524 | unsigned long addr_copy = addr; |
1528 | 1525 | ||
1529 | ret = change_page_attr_set(&addr, numpages, | 1526 | ret = change_page_attr_set(&addr, numpages, |
1530 | __pgprot(_PAGE_CACHE_UC_MINUS), 0); | 1527 | cachemode2pgprot(_PAGE_CACHE_MODE_UC_MINUS), |
1528 | 0); | ||
1531 | if (!ret) { | 1529 | if (!ret) { |
1532 | ret = change_page_attr_set_clr(&addr_copy, numpages, | 1530 | ret = change_page_attr_set_clr(&addr_copy, numpages, |
1533 | __pgprot(_PAGE_CACHE_WC), | 1531 | cachemode2pgprot( |
1532 | _PAGE_CACHE_MODE_WC), | ||
1534 | __pgprot(_PAGE_CACHE_MASK), | 1533 | __pgprot(_PAGE_CACHE_MASK), |
1535 | 0, 0, NULL); | 1534 | 0, 0, NULL); |
1536 | } | 1535 | } |
@@ -1564,6 +1563,7 @@ EXPORT_SYMBOL(set_memory_wc); | |||
1564 | 1563 | ||
1565 | int _set_memory_wb(unsigned long addr, int numpages) | 1564 | int _set_memory_wb(unsigned long addr, int numpages) |
1566 | { | 1565 | { |
1566 | /* WB cache mode is hard wired to all cache attribute bits being 0 */ | ||
1567 | return change_page_attr_clear(&addr, numpages, | 1567 | return change_page_attr_clear(&addr, numpages, |
1568 | __pgprot(_PAGE_CACHE_MASK), 0); | 1568 | __pgprot(_PAGE_CACHE_MASK), 0); |
1569 | } | 1569 | } |
@@ -1586,6 +1586,7 @@ int set_memory_array_wb(unsigned long *addr, int addrinarray) | |||
1586 | int i; | 1586 | int i; |
1587 | int ret; | 1587 | int ret; |
1588 | 1588 | ||
1589 | /* WB cache mode is hard wired to all cache attribute bits being 0 */ | ||
1589 | ret = change_page_attr_clear(addr, addrinarray, | 1590 | ret = change_page_attr_clear(addr, addrinarray, |
1590 | __pgprot(_PAGE_CACHE_MASK), 1); | 1591 | __pgprot(_PAGE_CACHE_MASK), 1); |
1591 | if (ret) | 1592 | if (ret) |
@@ -1648,7 +1649,7 @@ int set_pages_uc(struct page *page, int numpages) | |||
1648 | EXPORT_SYMBOL(set_pages_uc); | 1649 | EXPORT_SYMBOL(set_pages_uc); |
1649 | 1650 | ||
1650 | static int _set_pages_array(struct page **pages, int addrinarray, | 1651 | static int _set_pages_array(struct page **pages, int addrinarray, |
1651 | unsigned long new_type) | 1652 | enum page_cache_mode new_type) |
1652 | { | 1653 | { |
1653 | unsigned long start; | 1654 | unsigned long start; |
1654 | unsigned long end; | 1655 | unsigned long end; |
@@ -1661,15 +1662,17 @@ static int _set_pages_array(struct page **pages, int addrinarray, | |||
1661 | continue; | 1662 | continue; |
1662 | start = page_to_pfn(pages[i]) << PAGE_SHIFT; | 1663 | start = page_to_pfn(pages[i]) << PAGE_SHIFT; |
1663 | end = start + PAGE_SIZE; | 1664 | end = start + PAGE_SIZE; |
1664 | if (reserve_memtype(start, end, new_type, NULL)) | 1665 | if (reserve_memtype(start, end, cachemode2protval(new_type), |
1666 | NULL)) | ||
1665 | goto err_out; | 1667 | goto err_out; |
1666 | } | 1668 | } |
1667 | 1669 | ||
1668 | ret = cpa_set_pages_array(pages, addrinarray, | 1670 | ret = cpa_set_pages_array(pages, addrinarray, |
1669 | __pgprot(_PAGE_CACHE_UC_MINUS)); | 1671 | cachemode2pgprot(_PAGE_CACHE_MODE_UC_MINUS)); |
1670 | if (!ret && new_type == _PAGE_CACHE_WC) | 1672 | if (!ret && new_type == _PAGE_CACHE_MODE_WC) |
1671 | ret = change_page_attr_set_clr(NULL, addrinarray, | 1673 | ret = change_page_attr_set_clr(NULL, addrinarray, |
1672 | __pgprot(_PAGE_CACHE_WC), | 1674 | cachemode2pgprot( |
1675 | _PAGE_CACHE_MODE_WC), | ||
1673 | __pgprot(_PAGE_CACHE_MASK), | 1676 | __pgprot(_PAGE_CACHE_MASK), |
1674 | 0, CPA_PAGES_ARRAY, pages); | 1677 | 0, CPA_PAGES_ARRAY, pages); |
1675 | if (ret) | 1678 | if (ret) |
@@ -1689,13 +1692,13 @@ err_out: | |||
1689 | 1692 | ||
1690 | int set_pages_array_uc(struct page **pages, int addrinarray) | 1693 | int set_pages_array_uc(struct page **pages, int addrinarray) |
1691 | { | 1694 | { |
1692 | return _set_pages_array(pages, addrinarray, _PAGE_CACHE_UC_MINUS); | 1695 | return _set_pages_array(pages, addrinarray, _PAGE_CACHE_MODE_UC_MINUS); |
1693 | } | 1696 | } |
1694 | EXPORT_SYMBOL(set_pages_array_uc); | 1697 | EXPORT_SYMBOL(set_pages_array_uc); |
1695 | 1698 | ||
1696 | int set_pages_array_wc(struct page **pages, int addrinarray) | 1699 | int set_pages_array_wc(struct page **pages, int addrinarray) |
1697 | { | 1700 | { |
1698 | return _set_pages_array(pages, addrinarray, _PAGE_CACHE_WC); | 1701 | return _set_pages_array(pages, addrinarray, _PAGE_CACHE_MODE_WC); |
1699 | } | 1702 | } |
1700 | EXPORT_SYMBOL(set_pages_array_wc); | 1703 | EXPORT_SYMBOL(set_pages_array_wc); |
1701 | 1704 | ||
@@ -1714,6 +1717,7 @@ int set_pages_array_wb(struct page **pages, int addrinarray) | |||
1714 | unsigned long end; | 1717 | unsigned long end; |
1715 | int i; | 1718 | int i; |
1716 | 1719 | ||
1720 | /* WB cache mode is hard wired to all cache attribute bits being 0 */ | ||
1717 | retval = cpa_clear_pages_array(pages, addrinarray, | 1721 | retval = cpa_clear_pages_array(pages, addrinarray, |
1718 | __pgprot(_PAGE_CACHE_MASK)); | 1722 | __pgprot(_PAGE_CACHE_MASK)); |
1719 | if (retval) | 1723 | if (retval) |