diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-07-24 05:03:41 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-08-01 08:55:05 -0400 |
commit | 152125b7a882df36a55a8eadbea6d0edf1461ee7 (patch) | |
tree | 247d93a58d6ff9ff9ccbe66840acaa240069d879 /arch/s390/include/asm/pgtable.h | |
parent | 55e4283c3eb1d850893f645dd695c9c75d5fa1fc (diff) |
s390/mm: implement dirty bits for large segment table entries
The large segment table entry format has block of bits for the
ACC/F values for the large page. These bits are valid only if
another bit (AV bit 0x10000) of the segment table entry is set.
The ACC/F bits do not have a meaning if the AV bit is off.
This allows to put the THP splitting bit, the segment young bit
and the new segment dirty bit into the ACC/F bits as long as
the AV bit stays off. The dirty and young information is only
available if the pmd is large.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/include/asm/pgtable.h')
-rw-r--r-- | arch/s390/include/asm/pgtable.h | 197 |
1 files changed, 109 insertions, 88 deletions
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index fcba5e03839f..b76317c1f3eb 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -287,7 +287,14 @@ extern unsigned long MODULES_END; | |||
287 | #define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */ | 287 | #define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */ |
288 | #define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */ | 288 | #define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */ |
289 | #define _SEGMENT_ENTRY_PTL 0x0f /* page table length */ | 289 | #define _SEGMENT_ENTRY_PTL 0x0f /* page table length */ |
290 | #define _SEGMENT_ENTRY_NONE _SEGMENT_ENTRY_PROTECT | 290 | |
291 | #define _SEGMENT_ENTRY_DIRTY 0 /* No sw dirty bit for 31-bit */ | ||
292 | #define _SEGMENT_ENTRY_YOUNG 0 /* No sw young bit for 31-bit */ | ||
293 | #define _SEGMENT_ENTRY_READ 0 /* No sw read bit for 31-bit */ | ||
294 | #define _SEGMENT_ENTRY_WRITE 0 /* No sw write bit for 31-bit */ | ||
295 | #define _SEGMENT_ENTRY_LARGE 0 /* No large pages for 31-bit */ | ||
296 | #define _SEGMENT_ENTRY_BITS_LARGE 0 | ||
297 | #define _SEGMENT_ENTRY_ORIGIN_LARGE 0 | ||
291 | 298 | ||
292 | #define _SEGMENT_ENTRY (_SEGMENT_ENTRY_PTL) | 299 | #define _SEGMENT_ENTRY (_SEGMENT_ENTRY_PTL) |
293 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID) | 300 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID) |
@@ -350,7 +357,7 @@ extern unsigned long MODULES_END; | |||
350 | 357 | ||
351 | /* Bits in the segment table entry */ | 358 | /* Bits in the segment table entry */ |
352 | #define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL | 359 | #define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL |
353 | #define _SEGMENT_ENTRY_BITS_LARGE 0xfffffffffff1ff33UL | 360 | #define _SEGMENT_ENTRY_BITS_LARGE 0xfffffffffff0ff33UL |
354 | #define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */ | 361 | #define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */ |
355 | #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ | 362 | #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ |
356 | #define _SEGMENT_ENTRY_PROTECT 0x200 /* page protection bit */ | 363 | #define _SEGMENT_ENTRY_PROTECT 0x200 /* page protection bit */ |
@@ -359,30 +366,34 @@ extern unsigned long MODULES_END; | |||
359 | #define _SEGMENT_ENTRY (0) | 366 | #define _SEGMENT_ENTRY (0) |
360 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID) | 367 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID) |
361 | 368 | ||
362 | #define _SEGMENT_ENTRY_LARGE 0x400 /* STE-format control, large page */ | 369 | #define _SEGMENT_ENTRY_DIRTY 0x2000 /* SW segment dirty bit */ |
363 | #define _SEGMENT_ENTRY_CO 0x100 /* change-recording override */ | 370 | #define _SEGMENT_ENTRY_YOUNG 0x1000 /* SW segment young bit */ |
364 | #define _SEGMENT_ENTRY_SPLIT 0x001 /* THP splitting bit */ | 371 | #define _SEGMENT_ENTRY_SPLIT 0x0800 /* THP splitting bit */ |
365 | #define _SEGMENT_ENTRY_YOUNG 0x002 /* SW segment young bit */ | 372 | #define _SEGMENT_ENTRY_LARGE 0x0400 /* STE-format control, large page */ |
366 | #define _SEGMENT_ENTRY_NONE _SEGMENT_ENTRY_YOUNG | 373 | #define _SEGMENT_ENTRY_CO 0x0100 /* change-recording override */ |
374 | #define _SEGMENT_ENTRY_READ 0x0002 /* SW segment read bit */ | ||
375 | #define _SEGMENT_ENTRY_WRITE 0x0001 /* SW segment write bit */ | ||
367 | 376 | ||
368 | /* | 377 | /* |
369 | * Segment table entry encoding (R = read-only, I = invalid, y = young bit): | 378 | * Segment table entry encoding (R = read-only, I = invalid, y = young bit): |
370 | * ..R...I...y. | 379 | * dy..R...I...wr |
371 | * prot-none, old ..0...1...1. | 380 | * prot-none, clean, old 00..1...1...00 |
372 | * prot-none, young ..1...1...1. | 381 | * prot-none, clean, young 01..1...1...00 |
373 | * read-only, old ..1...1...0. | 382 | * prot-none, dirty, old 10..1...1...00 |
374 | * read-only, young ..1...0...1. | 383 | * prot-none, dirty, young 11..1...1...00 |
375 | * read-write, old ..0...1...0. | 384 | * read-only, clean, old 00..1...1...01 |
376 | * read-write, young ..0...0...1. | 385 | * read-only, clean, young 01..1...0...01 |
386 | * read-only, dirty, old 10..1...1...01 | ||
387 | * read-only, dirty, young 11..1...0...01 | ||
388 | * read-write, clean, old 00..1...1...11 | ||
389 | * read-write, clean, young 01..1...0...11 | ||
390 | * read-write, dirty, old 10..0...1...11 | ||
391 | * read-write, dirty, young 11..0...0...11 | ||
377 | * The segment table origin is used to distinguish empty (origin==0) from | 392 | * The segment table origin is used to distinguish empty (origin==0) from |
378 | * read-write, old segment table entries (origin!=0) | 393 | * read-write, old segment table entries (origin!=0) |
379 | */ | 394 | */ |
380 | 395 | ||
381 | #define _SEGMENT_ENTRY_SPLIT_BIT 0 /* THP splitting bit number */ | 396 | #define _SEGMENT_ENTRY_SPLIT_BIT 11 /* THP splitting bit number */ |
382 | |||
383 | /* Set of bits not changed in pmd_modify */ | ||
384 | #define _SEGMENT_CHG_MASK (_SEGMENT_ENTRY_ORIGIN | _SEGMENT_ENTRY_LARGE \ | ||
385 | | _SEGMENT_ENTRY_SPLIT | _SEGMENT_ENTRY_CO) | ||
386 | 397 | ||
387 | /* Page status table bits for virtualization */ | 398 | /* Page status table bits for virtualization */ |
388 | #define PGSTE_ACC_BITS 0xf000000000000000UL | 399 | #define PGSTE_ACC_BITS 0xf000000000000000UL |
@@ -455,10 +466,11 @@ extern unsigned long MODULES_END; | |||
455 | * Segment entry (large page) protection definitions. | 466 | * Segment entry (large page) protection definitions. |
456 | */ | 467 | */ |
457 | #define SEGMENT_NONE __pgprot(_SEGMENT_ENTRY_INVALID | \ | 468 | #define SEGMENT_NONE __pgprot(_SEGMENT_ENTRY_INVALID | \ |
458 | _SEGMENT_ENTRY_NONE) | ||
459 | #define SEGMENT_READ __pgprot(_SEGMENT_ENTRY_INVALID | \ | ||
460 | _SEGMENT_ENTRY_PROTECT) | 469 | _SEGMENT_ENTRY_PROTECT) |
461 | #define SEGMENT_WRITE __pgprot(_SEGMENT_ENTRY_INVALID) | 470 | #define SEGMENT_READ __pgprot(_SEGMENT_ENTRY_PROTECT | \ |
471 | _SEGMENT_ENTRY_READ) | ||
472 | #define SEGMENT_WRITE __pgprot(_SEGMENT_ENTRY_READ | \ | ||
473 | _SEGMENT_ENTRY_WRITE) | ||
462 | 474 | ||
463 | static inline int mm_has_pgste(struct mm_struct *mm) | 475 | static inline int mm_has_pgste(struct mm_struct *mm) |
464 | { | 476 | { |
@@ -569,25 +581,23 @@ static inline int pmd_none(pmd_t pmd) | |||
569 | 581 | ||
570 | static inline int pmd_large(pmd_t pmd) | 582 | static inline int pmd_large(pmd_t pmd) |
571 | { | 583 | { |
572 | #ifdef CONFIG_64BIT | ||
573 | return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0; | 584 | return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0; |
574 | #else | ||
575 | return 0; | ||
576 | #endif | ||
577 | } | 585 | } |
578 | 586 | ||
579 | static inline int pmd_prot_none(pmd_t pmd) | 587 | static inline int pmd_pfn(pmd_t pmd) |
580 | { | 588 | { |
581 | return (pmd_val(pmd) & _SEGMENT_ENTRY_INVALID) && | 589 | unsigned long origin_mask; |
582 | (pmd_val(pmd) & _SEGMENT_ENTRY_NONE); | 590 | |
591 | origin_mask = _SEGMENT_ENTRY_ORIGIN; | ||
592 | if (pmd_large(pmd)) | ||
593 | origin_mask = _SEGMENT_ENTRY_ORIGIN_LARGE; | ||
594 | return (pmd_val(pmd) & origin_mask) >> PAGE_SHIFT; | ||
583 | } | 595 | } |
584 | 596 | ||
585 | static inline int pmd_bad(pmd_t pmd) | 597 | static inline int pmd_bad(pmd_t pmd) |
586 | { | 598 | { |
587 | #ifdef CONFIG_64BIT | ||
588 | if (pmd_large(pmd)) | 599 | if (pmd_large(pmd)) |
589 | return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS_LARGE) != 0; | 600 | return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS_LARGE) != 0; |
590 | #endif | ||
591 | return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS) != 0; | 601 | return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS) != 0; |
592 | } | 602 | } |
593 | 603 | ||
@@ -607,20 +617,22 @@ extern int pmdp_clear_flush_young(struct vm_area_struct *vma, | |||
607 | #define __HAVE_ARCH_PMD_WRITE | 617 | #define __HAVE_ARCH_PMD_WRITE |
608 | static inline int pmd_write(pmd_t pmd) | 618 | static inline int pmd_write(pmd_t pmd) |
609 | { | 619 | { |
610 | if (pmd_prot_none(pmd)) | 620 | return (pmd_val(pmd) & _SEGMENT_ENTRY_WRITE) != 0; |
611 | return 0; | 621 | } |
612 | return (pmd_val(pmd) & _SEGMENT_ENTRY_PROTECT) == 0; | 622 | |
623 | static inline int pmd_dirty(pmd_t pmd) | ||
624 | { | ||
625 | int dirty = 1; | ||
626 | if (pmd_large(pmd)) | ||
627 | dirty = (pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY) != 0; | ||
628 | return dirty; | ||
613 | } | 629 | } |
614 | 630 | ||
615 | static inline int pmd_young(pmd_t pmd) | 631 | static inline int pmd_young(pmd_t pmd) |
616 | { | 632 | { |
617 | int young = 0; | 633 | int young = 1; |
618 | #ifdef CONFIG_64BIT | 634 | if (pmd_large(pmd)) |
619 | if (pmd_prot_none(pmd)) | ||
620 | young = (pmd_val(pmd) & _SEGMENT_ENTRY_PROTECT) != 0; | ||
621 | else | ||
622 | young = (pmd_val(pmd) & _SEGMENT_ENTRY_YOUNG) != 0; | 635 | young = (pmd_val(pmd) & _SEGMENT_ENTRY_YOUNG) != 0; |
623 | #endif | ||
624 | return young; | 636 | return young; |
625 | } | 637 | } |
626 | 638 | ||
@@ -1391,7 +1403,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) | |||
1391 | #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) | 1403 | #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) |
1392 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | 1404 | #define pte_page(x) pfn_to_page(pte_pfn(x)) |
1393 | 1405 | ||
1394 | #define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) | 1406 | #define pmd_page(pmd) pfn_to_page(pmd_pfn(pmd)) |
1395 | 1407 | ||
1396 | /* Find an entry in the lowest level page table.. */ | 1408 | /* Find an entry in the lowest level page table.. */ |
1397 | #define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr)) | 1409 | #define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr)) |
@@ -1413,41 +1425,75 @@ static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) | |||
1413 | return pgprot_val(SEGMENT_WRITE); | 1425 | return pgprot_val(SEGMENT_WRITE); |
1414 | } | 1426 | } |
1415 | 1427 | ||
1416 | static inline pmd_t pmd_mkyoung(pmd_t pmd) | 1428 | static inline pmd_t pmd_wrprotect(pmd_t pmd) |
1417 | { | 1429 | { |
1418 | #ifdef CONFIG_64BIT | 1430 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_WRITE; |
1419 | if (pmd_prot_none(pmd)) { | 1431 | pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT; |
1432 | return pmd; | ||
1433 | } | ||
1434 | |||
1435 | static inline pmd_t pmd_mkwrite(pmd_t pmd) | ||
1436 | { | ||
1437 | pmd_val(pmd) |= _SEGMENT_ENTRY_WRITE; | ||
1438 | if (pmd_large(pmd) && !(pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY)) | ||
1439 | return pmd; | ||
1440 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_PROTECT; | ||
1441 | return pmd; | ||
1442 | } | ||
1443 | |||
1444 | static inline pmd_t pmd_mkclean(pmd_t pmd) | ||
1445 | { | ||
1446 | if (pmd_large(pmd)) { | ||
1447 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_DIRTY; | ||
1420 | pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT; | 1448 | pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT; |
1421 | } else { | 1449 | } |
1450 | return pmd; | ||
1451 | } | ||
1452 | |||
1453 | static inline pmd_t pmd_mkdirty(pmd_t pmd) | ||
1454 | { | ||
1455 | if (pmd_large(pmd)) { | ||
1456 | pmd_val(pmd) |= _SEGMENT_ENTRY_DIRTY; | ||
1457 | if (pmd_val(pmd) & _SEGMENT_ENTRY_WRITE) | ||
1458 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_PROTECT; | ||
1459 | } | ||
1460 | return pmd; | ||
1461 | } | ||
1462 | |||
1463 | static inline pmd_t pmd_mkyoung(pmd_t pmd) | ||
1464 | { | ||
1465 | if (pmd_large(pmd)) { | ||
1422 | pmd_val(pmd) |= _SEGMENT_ENTRY_YOUNG; | 1466 | pmd_val(pmd) |= _SEGMENT_ENTRY_YOUNG; |
1423 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_INVALID; | 1467 | if (pmd_val(pmd) & _SEGMENT_ENTRY_READ) |
1468 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_INVALID; | ||
1424 | } | 1469 | } |
1425 | #endif | ||
1426 | return pmd; | 1470 | return pmd; |
1427 | } | 1471 | } |
1428 | 1472 | ||
1429 | static inline pmd_t pmd_mkold(pmd_t pmd) | 1473 | static inline pmd_t pmd_mkold(pmd_t pmd) |
1430 | { | 1474 | { |
1431 | #ifdef CONFIG_64BIT | 1475 | if (pmd_large(pmd)) { |
1432 | if (pmd_prot_none(pmd)) { | ||
1433 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_PROTECT; | ||
1434 | } else { | ||
1435 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_YOUNG; | 1476 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_YOUNG; |
1436 | pmd_val(pmd) |= _SEGMENT_ENTRY_INVALID; | 1477 | pmd_val(pmd) |= _SEGMENT_ENTRY_INVALID; |
1437 | } | 1478 | } |
1438 | #endif | ||
1439 | return pmd; | 1479 | return pmd; |
1440 | } | 1480 | } |
1441 | 1481 | ||
1442 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) | 1482 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) |
1443 | { | 1483 | { |
1444 | int young; | 1484 | if (pmd_large(pmd)) { |
1445 | 1485 | pmd_val(pmd) &= _SEGMENT_ENTRY_ORIGIN_LARGE | | |
1446 | young = pmd_young(pmd); | 1486 | _SEGMENT_ENTRY_DIRTY | _SEGMENT_ENTRY_YOUNG | |
1447 | pmd_val(pmd) &= _SEGMENT_CHG_MASK; | 1487 | _SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_SPLIT; |
1488 | pmd_val(pmd) |= massage_pgprot_pmd(newprot); | ||
1489 | if (!(pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY)) | ||
1490 | pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT; | ||
1491 | if (!(pmd_val(pmd) & _SEGMENT_ENTRY_YOUNG)) | ||
1492 | pmd_val(pmd) |= _SEGMENT_ENTRY_INVALID; | ||
1493 | return pmd; | ||
1494 | } | ||
1495 | pmd_val(pmd) &= _SEGMENT_ENTRY_ORIGIN; | ||
1448 | pmd_val(pmd) |= massage_pgprot_pmd(newprot); | 1496 | pmd_val(pmd) |= massage_pgprot_pmd(newprot); |
1449 | if (young) | ||
1450 | pmd = pmd_mkyoung(pmd); | ||
1451 | return pmd; | 1497 | return pmd; |
1452 | } | 1498 | } |
1453 | 1499 | ||
@@ -1455,16 +1501,9 @@ static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot) | |||
1455 | { | 1501 | { |
1456 | pmd_t __pmd; | 1502 | pmd_t __pmd; |
1457 | pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot); | 1503 | pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot); |
1458 | return pmd_mkyoung(__pmd); | 1504 | return __pmd; |
1459 | } | 1505 | } |
1460 | 1506 | ||
1461 | static inline pmd_t pmd_mkwrite(pmd_t pmd) | ||
1462 | { | ||
1463 | /* Do not clobber PROT_NONE segments! */ | ||
1464 | if (!pmd_prot_none(pmd)) | ||
1465 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_PROTECT; | ||
1466 | return pmd; | ||
1467 | } | ||
1468 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLB_PAGE */ | 1507 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLB_PAGE */ |
1469 | 1508 | ||
1470 | static inline void __pmdp_csp(pmd_t *pmdp) | 1509 | static inline void __pmdp_csp(pmd_t *pmdp) |
@@ -1555,34 +1594,21 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); | |||
1555 | 1594 | ||
1556 | static inline int pmd_trans_splitting(pmd_t pmd) | 1595 | static inline int pmd_trans_splitting(pmd_t pmd) |
1557 | { | 1596 | { |
1558 | return pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT; | 1597 | return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) && |
1598 | (pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT); | ||
1559 | } | 1599 | } |
1560 | 1600 | ||
1561 | static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, | 1601 | static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, |
1562 | pmd_t *pmdp, pmd_t entry) | 1602 | pmd_t *pmdp, pmd_t entry) |
1563 | { | 1603 | { |
1564 | if (!(pmd_val(entry) & _SEGMENT_ENTRY_INVALID) && MACHINE_HAS_EDAT1) | ||
1565 | pmd_val(entry) |= _SEGMENT_ENTRY_CO; | ||
1566 | *pmdp = entry; | 1604 | *pmdp = entry; |
1567 | } | 1605 | } |
1568 | 1606 | ||
1569 | static inline pmd_t pmd_mkhuge(pmd_t pmd) | 1607 | static inline pmd_t pmd_mkhuge(pmd_t pmd) |
1570 | { | 1608 | { |
1571 | pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE; | 1609 | pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE; |
1572 | return pmd; | 1610 | pmd_val(pmd) |= _SEGMENT_ENTRY_YOUNG; |
1573 | } | 1611 | pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT; |
1574 | |||
1575 | static inline pmd_t pmd_wrprotect(pmd_t pmd) | ||
1576 | { | ||
1577 | /* Do not clobber PROT_NONE segments! */ | ||
1578 | if (!pmd_prot_none(pmd)) | ||
1579 | pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT; | ||
1580 | return pmd; | ||
1581 | } | ||
1582 | |||
1583 | static inline pmd_t pmd_mkdirty(pmd_t pmd) | ||
1584 | { | ||
1585 | /* No dirty bit in the segment table entry. */ | ||
1586 | return pmd; | 1612 | return pmd; |
1587 | } | 1613 | } |
1588 | 1614 | ||
@@ -1647,11 +1673,6 @@ static inline int has_transparent_hugepage(void) | |||
1647 | { | 1673 | { |
1648 | return MACHINE_HAS_HPAGE ? 1 : 0; | 1674 | return MACHINE_HAS_HPAGE ? 1 : 0; |
1649 | } | 1675 | } |
1650 | |||
1651 | static inline unsigned long pmd_pfn(pmd_t pmd) | ||
1652 | { | ||
1653 | return pmd_val(pmd) >> PAGE_SHIFT; | ||
1654 | } | ||
1655 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 1676 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
1656 | 1677 | ||
1657 | /* | 1678 | /* |