home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-s390 / pgtable.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  24.6 KB  |  815 lines

  1. /*
  2.  *  include/asm-s390/pgtable.h
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *    Author(s): Hartmut Penner (hp@de.ibm.com)
  7.  *               Ulrich Weigand (weigand@de.ibm.com)
  8.  *               Martin Schwidefsky (schwidefsky@de.ibm.com)
  9.  *
  10.  *  Derived from "include/asm-i386/pgtable.h"
  11.  */
  12.  
  13. #ifndef _ASM_S390_PGTABLE_H
  14. #define _ASM_S390_PGTABLE_H
  15.  
  16. #include <asm-generic/4level-fixup.h>
  17.  
  18. /*
  19.  * The Linux memory management assumes a three-level page table setup. For
  20.  * s390 31 bit we "fold" the mid level into the top-level page table, so
  21.  * that we physically have the same two-level page table as the s390 mmu
  22.  * expects in 31 bit mode. For s390 64 bit we use three of the five levels
  23.  * the hardware provides (region first and region second tables are not
  24.  * used).
  25.  *
  26.  * The "pgd_xxx()" functions are trivial for a folded two-level
  27.  * setup: the pgd is never bad, and a pmd always exists (as it's folded
  28.  * into the pgd entry)
  29.  *
  30.  * This file contains the functions and defines necessary to modify and use
  31.  * the S390 page table tree.
  32.  */
  33. #ifndef __ASSEMBLY__
  34. #include <asm/bug.h>
  35. #include <asm/processor.h>
  36. #include <linux/threads.h>
  37.  
  38. struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
  39. struct mm_struct;
  40.  
  41. extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
  42. extern void paging_init(void);
  43.  
  44. /*
  45.  * The S390 doesn't have any external MMU info: the kernel page
  46.  * tables contain all the necessary information.
  47.  */
  48. #define update_mmu_cache(vma, address, pte)     do { } while (0)
  49.  
  50. /*
  51.  * ZERO_PAGE is a global shared page that is always zero: used
  52.  * for zero-mapped memory areas etc..
  53.  */
  54. extern char empty_zero_page[PAGE_SIZE];
  55. #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
  56. #endif /* !__ASSEMBLY__ */
  57.  
  58. /*
  59.  * PMD_SHIFT determines the size of the area a second-level page
  60.  * table can map
  61.  * PGDIR_SHIFT determines what a third-level page table entry can map
  62.  */
  63. #ifndef __s390x__
  64. # define PMD_SHIFT    22
  65. # define PGDIR_SHIFT    22
  66. #else /* __s390x__ */
  67. # define PMD_SHIFT    21
  68. # define PGDIR_SHIFT    31
  69. #endif /* __s390x__ */
  70.  
  71. #define PMD_SIZE        (1UL << PMD_SHIFT)
  72. #define PMD_MASK        (~(PMD_SIZE-1))
  73. #define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
  74. #define PGDIR_MASK      (~(PGDIR_SIZE-1))
  75.  
  76. /*
  77.  * entries per page directory level: the S390 is two-level, so
  78.  * we don't really have any PMD directory physically.
  79.  * for S390 segment-table entries are combined to one PGD
  80.  * that leads to 1024 pte per pgd
  81.  */
  82. #ifndef __s390x__
  83. # define PTRS_PER_PTE    1024
  84. # define PTRS_PER_PMD    1
  85. # define PTRS_PER_PGD    512
  86. #else /* __s390x__ */
  87. # define PTRS_PER_PTE    512
  88. # define PTRS_PER_PMD    1024
  89. # define PTRS_PER_PGD    2048
  90. #endif /* __s390x__ */
  91.  
  92. /*
  93.  * pgd entries used up by user/kernel:
  94.  */
  95. #ifndef __s390x__
  96. # define USER_PTRS_PER_PGD  512
  97. # define USER_PGD_PTRS      512
  98. # define KERNEL_PGD_PTRS    512
  99. #else /* __s390x__ */
  100. # define USER_PTRS_PER_PGD  2048
  101. # define USER_PGD_PTRS      2048
  102. # define KERNEL_PGD_PTRS    2048
  103. #endif /* __s390x__ */
  104.  
  105. #define FIRST_USER_ADDRESS  0
  106.  
  107. #define pte_ERROR(e) \
  108.     printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e))
  109. #define pmd_ERROR(e) \
  110.     printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e))
  111. #define pgd_ERROR(e) \
  112.     printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e))
  113.  
  114. #ifndef __ASSEMBLY__
  115. /*
  116.  * Just any arbitrary offset to the start of the vmalloc VM area: the
  117.  * current 8MB value just means that there will be a 8MB "hole" after the
  118.  * physical memory until the kernel virtual memory starts.  That means that
  119.  * any out-of-bounds memory accesses will hopefully be caught.
  120.  * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  121.  * area for the same reason. ;)
  122.  */
  123. #define VMALLOC_OFFSET  (8*1024*1024)
  124. #define VMALLOC_START   (((unsigned long) high_memory + VMALLOC_OFFSET) \
  125.              & ~(VMALLOC_OFFSET-1))
  126. #ifndef __s390x__
  127. # define VMALLOC_END     (0x7fffffffL)
  128. #else /* __s390x__ */
  129. # define VMALLOC_END     (0x40000000000L)
  130. #endif /* __s390x__ */
  131.  
  132.  
  133. /*
  134.  * A 31 bit pagetable entry of S390 has following format:
  135.  *  |   PFRA          |    |  OS  |
  136.  * 0                   0IP0
  137.  * 00000000001111111111222222222233
  138.  * 01234567890123456789012345678901
  139.  *
  140.  * I Page-Invalid Bit:    Page is not available for address-translation
  141.  * P Page-Protection Bit: Store access not possible for page
  142.  *
  143.  * A 31 bit segmenttable entry of S390 has following format:
  144.  *  |   P-table origin      |  |PTL
  145.  * 0                         IC
  146.  * 00000000001111111111222222222233
  147.  * 01234567890123456789012345678901
  148.  *
  149.  * I Segment-Invalid Bit:    Segment is not available for address-translation
  150.  * C Common-Segment Bit:     Segment is not private (PoP 3-30)
  151.  * PTL Page-Table-Length:    Page-table length (PTL+1*16 entries -> up to 256)
  152.  *
  153.  * The 31 bit segmenttable origin of S390 has following format:
  154.  *
  155.  *  |S-table origin   |     | STL |
  156.  * X                   **GPS
  157.  * 00000000001111111111222222222233
  158.  * 01234567890123456789012345678901
  159.  *
  160.  * X Space-Switch event:
  161.  * G Segment-Invalid Bit:     *
  162.  * P Private-Space Bit:       Segment is not private (PoP 3-30)
  163.  * S Storage-Alteration:
  164.  * STL Segment-Table-Length:  Segment-table length (STL+1*16 entries -> up to 2048)
  165.  *
  166.  * A 64 bit pagetable entry of S390 has following format:
  167.  * |                     PFRA                         |0IP0|  OS  |
  168.  * 0000000000111111111122222222223333333333444444444455555555556666
  169.  * 0123456789012345678901234567890123456789012345678901234567890123
  170.  *
  171.  * I Page-Invalid Bit:    Page is not available for address-translation
  172.  * P Page-Protection Bit: Store access not possible for page
  173.  *
  174.  * A 64 bit segmenttable entry of S390 has following format:
  175.  * |        P-table origin                              |      TT
  176.  * 0000000000111111111122222222223333333333444444444455555555556666
  177.  * 0123456789012345678901234567890123456789012345678901234567890123
  178.  *
  179.  * I Segment-Invalid Bit:    Segment is not available for address-translation
  180.  * C Common-Segment Bit:     Segment is not private (PoP 3-30)
  181.  * P Page-Protection Bit: Store access not possible for page
  182.  * TT Type 00
  183.  *
  184.  * A 64 bit region table entry of S390 has following format:
  185.  * |        S-table origin                             |   TF  TTTL
  186.  * 0000000000111111111122222222223333333333444444444455555555556666
  187.  * 0123456789012345678901234567890123456789012345678901234567890123
  188.  *
  189.  * I Segment-Invalid Bit:    Segment is not available for address-translation
  190.  * TT Type 01
  191.  * TF
  192.  * TL Table lenght
  193.  *
  194.  * The 64 bit regiontable origin of S390 has following format:
  195.  * |      region table origon                          |       DTTL
  196.  * 0000000000111111111122222222223333333333444444444455555555556666
  197.  * 0123456789012345678901234567890123456789012345678901234567890123
  198.  *
  199.  * X Space-Switch event:
  200.  * G Segment-Invalid Bit:  
  201.  * P Private-Space Bit:    
  202.  * S Storage-Alteration:
  203.  * R Real space
  204.  * TL Table-Length:
  205.  *
  206.  * A storage key has the following format:
  207.  * | ACC |F|R|C|0|
  208.  *  0   3 4 5 6 7
  209.  * ACC: access key
  210.  * F  : fetch protection bit
  211.  * R  : referenced bit
  212.  * C  : changed bit
  213.  */
  214.  
  215. /* Hardware bits in the page table entry */
  216. #define _PAGE_RO        0x200          /* HW read-only                     */
  217. #define _PAGE_INVALID   0x400          /* HW invalid                       */
  218.  
  219. /* Mask and four different kinds of invalid pages. */
  220. #define _PAGE_INVALID_MASK    0x601
  221. #define _PAGE_INVALID_EMPTY    0x400
  222. #define _PAGE_INVALID_NONE    0x401
  223. #define _PAGE_INVALID_SWAP    0x600
  224. #define _PAGE_INVALID_FILE    0x601
  225.  
  226. #ifndef __s390x__
  227.  
  228. /* Bits in the segment table entry */
  229. #define _PAGE_TABLE_LEN 0xf            /* only full page-tables            */
  230. #define _PAGE_TABLE_COM 0x10           /* common page-table                */
  231. #define _PAGE_TABLE_INV 0x20           /* invalid page-table               */
  232. #define _SEG_PRESENT    0x001          /* Software (overlap with PTL)      */
  233.  
  234. /* Bits int the storage key */
  235. #define _PAGE_CHANGED    0x02          /* HW changed bit                   */
  236. #define _PAGE_REFERENCED 0x04          /* HW referenced bit                */
  237.  
  238. #define _USER_SEG_TABLE_LEN    0x7f    /* user-segment-table up to 2 GB    */
  239. #define _KERNEL_SEG_TABLE_LEN  0x7f    /* kernel-segment-table up to 2 GB  */
  240.  
  241. /*
  242.  * User and Kernel pagetables are identical
  243.  */
  244. #define _PAGE_TABLE    _PAGE_TABLE_LEN
  245. #define _KERNPG_TABLE    _PAGE_TABLE_LEN
  246.  
  247. /*
  248.  * The Kernel segment-tables includes the User segment-table
  249.  */
  250.  
  251. #define _SEGMENT_TABLE    (_USER_SEG_TABLE_LEN|0x80000000|0x100)
  252. #define _KERNSEG_TABLE    _KERNEL_SEG_TABLE_LEN
  253.  
  254. #define USER_STD_MASK    0x00000080UL
  255.  
  256. #else /* __s390x__ */
  257.  
  258. /* Bits in the segment table entry */
  259. #define _PMD_ENTRY_INV   0x20          /* invalid segment table entry      */
  260. #define _PMD_ENTRY       0x00        
  261.  
  262. /* Bits in the region third table entry */
  263. #define _PGD_ENTRY_INV   0x20          /* invalid region table entry       */
  264. #define _PGD_ENTRY       0x07
  265.  
  266. /*
  267.  * User and kernel page directory
  268.  */
  269. #define _REGION_THIRD       0x4
  270. #define _REGION_THIRD_LEN   0x3 
  271. #define _REGION_TABLE       (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100)
  272. #define _KERN_REGION_TABLE  (_REGION_THIRD|_REGION_THIRD_LEN)
  273.  
  274. #define USER_STD_MASK           0x0000000000000080UL
  275.  
  276. /* Bits in the storage key */
  277. #define _PAGE_CHANGED    0x02          /* HW changed bit                   */
  278. #define _PAGE_REFERENCED 0x04          /* HW referenced bit                */
  279.  
  280. #endif /* __s390x__ */
  281.  
  282. /*
  283.  * No mapping available
  284.  */
  285. #define PAGE_NONE_SHARED  __pgprot(_PAGE_INVALID_NONE)
  286. #define PAGE_NONE_PRIVATE __pgprot(_PAGE_INVALID_NONE)
  287. #define PAGE_RO_SHARED      __pgprot(_PAGE_RO)
  288. #define PAGE_RO_PRIVATE      __pgprot(_PAGE_RO)
  289. #define PAGE_COPY      __pgprot(_PAGE_RO)
  290. #define PAGE_SHARED      __pgprot(0)
  291. #define PAGE_KERNEL      __pgprot(0)
  292.  
  293. /*
  294.  * The S390 can't do page protection for execute, and considers that the
  295.  * same are read. Also, write permissions imply read permissions. This is
  296.  * the closest we can get..
  297.  */
  298.          /*xwr*/
  299. #define __P000  PAGE_NONE_PRIVATE
  300. #define __P001  PAGE_RO_PRIVATE
  301. #define __P010  PAGE_COPY
  302. #define __P011  PAGE_COPY
  303. #define __P100  PAGE_RO_PRIVATE
  304. #define __P101  PAGE_RO_PRIVATE
  305. #define __P110  PAGE_COPY
  306. #define __P111  PAGE_COPY
  307.  
  308. #define __S000  PAGE_NONE_SHARED
  309. #define __S001  PAGE_RO_SHARED
  310. #define __S010  PAGE_SHARED
  311. #define __S011  PAGE_SHARED
  312. #define __S100  PAGE_RO_SHARED
  313. #define __S101  PAGE_RO_SHARED
  314. #define __S110  PAGE_SHARED
  315. #define __S111  PAGE_SHARED
  316.  
  317. /*
  318.  * Certain architectures need to do special things when PTEs
  319.  * within a page table are directly modified.  Thus, the following
  320.  * hook is made available.
  321.  */
  322. static inline void set_pte(pte_t *pteptr, pte_t pteval)
  323. {
  324.     *pteptr = pteval;
  325. }
  326. #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
  327.  
  328. /*
  329.  * pgd/pmd/pte query functions
  330.  */
  331. #ifndef __s390x__
  332.  
  333. static inline int pgd_present(pgd_t pgd) { return 1; }
  334. static inline int pgd_none(pgd_t pgd)    { return 0; }
  335. static inline int pgd_bad(pgd_t pgd)     { return 0; }
  336.  
  337. static inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; }
  338. static inline int pmd_none(pmd_t pmd)    { return pmd_val(pmd) & _PAGE_TABLE_INV; }
  339. static inline int pmd_bad(pmd_t pmd)
  340. {
  341.     return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE;
  342. }
  343.  
  344. #else /* __s390x__ */
  345.  
  346. static inline int pgd_present(pgd_t pgd)
  347. {
  348.     return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY;
  349. }
  350.  
  351. static inline int pgd_none(pgd_t pgd)
  352. {
  353.     return pgd_val(pgd) & _PGD_ENTRY_INV;
  354. }
  355.  
  356. static inline int pgd_bad(pgd_t pgd)
  357. {
  358.     return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY;
  359. }
  360.  
  361. static inline int pmd_present(pmd_t pmd)
  362. {
  363.     return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY;
  364. }
  365.  
  366. static inline int pmd_none(pmd_t pmd)
  367. {
  368.     return pmd_val(pmd) & _PMD_ENTRY_INV;
  369. }
  370.  
  371. static inline int pmd_bad(pmd_t pmd)
  372. {
  373.     return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY;
  374. }
  375.  
  376. #endif /* __s390x__ */
  377.  
  378. static inline int pte_none(pte_t pte)
  379. {
  380.     return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY;
  381. }
  382.  
  383. static inline int pte_present(pte_t pte)
  384. {
  385.     return !(pte_val(pte) & _PAGE_INVALID) ||
  386.         (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE;
  387. }
  388.  
  389. static inline int pte_file(pte_t pte)
  390. {
  391.     return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE;
  392. }
  393.  
  394. #define pte_same(a,b)    (pte_val(a) == pte_val(b))
  395.  
  396. /*
  397.  * query functions pte_write/pte_dirty/pte_young only work if
  398.  * pte_present() is true. Undefined behaviour if not..
  399.  */
  400. static inline int pte_write(pte_t pte)
  401. {
  402.     return (pte_val(pte) & _PAGE_RO) == 0;
  403. }
  404.  
  405. static inline int pte_dirty(pte_t pte)
  406. {
  407.     /* A pte is neither clean nor dirty on s/390. The dirty bit
  408.      * is in the storage key. See page_test_and_clear_dirty for
  409.      * details.
  410.      */
  411.     return 0;
  412. }
  413.  
  414. static inline int pte_young(pte_t pte)
  415. {
  416.     /* A pte is neither young nor old on s/390. The young bit
  417.      * is in the storage key. See page_test_and_clear_young for
  418.      * details.
  419.      */
  420.     return 0;
  421. }
  422.  
  423. static inline int pte_read(pte_t pte)
  424. {
  425.     /* All pages are readable since we don't use the fetch
  426.      * protection bit in the storage key.
  427.      */
  428.     return 1;
  429. }
  430.  
  431. /*
  432.  * pgd/pmd/pte modification functions
  433.  */
  434.  
  435. #ifndef __s390x__
  436.  
  437. static inline void pgd_clear(pgd_t * pgdp)      { }
  438.  
  439. static inline void pmd_clear(pmd_t * pmdp)
  440. {
  441.     pmd_val(pmdp[0]) = _PAGE_TABLE_INV;
  442.     pmd_val(pmdp[1]) = _PAGE_TABLE_INV;
  443.     pmd_val(pmdp[2]) = _PAGE_TABLE_INV;
  444.     pmd_val(pmdp[3]) = _PAGE_TABLE_INV;
  445. }
  446.  
  447. #else /* __s390x__ */
  448.  
  449. static inline void pgd_clear(pgd_t * pgdp)
  450. {
  451.     pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY;
  452. }
  453.  
  454. static inline void pmd_clear(pmd_t * pmdp)
  455. {
  456.     pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
  457.     pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
  458. }
  459.  
  460. #endif /* __s390x__ */
  461.  
  462. static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
  463. {
  464.     pte_val(*ptep) = _PAGE_INVALID_EMPTY;
  465. }
  466.  
  467. /*
  468.  * The following pte modification functions only work if
  469.  * pte_present() is true. Undefined behaviour if not..
  470.  */
  471. static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  472. {
  473.     pte_val(pte) &= PAGE_MASK;
  474.     pte_val(pte) |= pgprot_val(newprot);
  475.     return pte;
  476. }
  477.  
  478. static inline pte_t pte_wrprotect(pte_t pte)
  479. {
  480.     /* Do not clobber _PAGE_INVALID_NONE pages!  */
  481.     if (!(pte_val(pte) & _PAGE_INVALID))
  482.         pte_val(pte) |= _PAGE_RO;
  483.     return pte;
  484. }
  485.  
  486. static inline pte_t pte_mkwrite(pte_t pte)
  487. {
  488.     pte_val(pte) &= ~_PAGE_RO;
  489.     return pte;
  490. }
  491.  
  492. static inline pte_t pte_mkclean(pte_t pte)
  493. {
  494.     /* The only user of pte_mkclean is the fork() code.
  495.        We must *not* clear the *physical* page dirty bit
  496.        just because fork() wants to clear the dirty bit in
  497.        *one* of the page's mappings.  So we just do nothing. */
  498.     return pte;
  499. }
  500.  
  501. static inline pte_t pte_mkdirty(pte_t pte)
  502. {
  503.     /* We do not explicitly set the dirty bit because the
  504.      * sske instruction is slow. It is faster to let the
  505.      * next instruction set the dirty bit.
  506.      */
  507.     return pte;
  508. }
  509.  
  510. static inline pte_t pte_mkold(pte_t pte)
  511. {
  512.     /* S/390 doesn't keep its dirty/referenced bit in the pte.
  513.      * There is no point in clearing the real referenced bit.
  514.      */
  515.     return pte;
  516. }
  517.  
  518. static inline pte_t pte_mkyoung(pte_t pte)
  519. {
  520.     /* S/390 doesn't keep its dirty/referenced bit in the pte.
  521.      * There is no point in setting the real referenced bit.
  522.      */
  523.     return pte;
  524. }
  525.  
  526. static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
  527. {
  528.     return 0;
  529. }
  530.  
  531. static inline int
  532. ptep_clear_flush_young(struct vm_area_struct *vma,
  533.             unsigned long address, pte_t *ptep)
  534. {
  535.     /* No need to flush TLB; bits are in storage key */
  536.     return ptep_test_and_clear_young(vma, address, ptep);
  537. }
  538.  
  539. static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
  540. {
  541.     return 0;
  542. }
  543.  
  544. static inline int
  545. ptep_clear_flush_dirty(struct vm_area_struct *vma,
  546.             unsigned long address, pte_t *ptep)
  547. {
  548.     /* No need to flush TLB; bits are in storage key */
  549.     return ptep_test_and_clear_dirty(vma, address, ptep);
  550. }
  551.  
  552. static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
  553. {
  554.     pte_t pte = *ptep;
  555.     pte_clear(mm, addr, ptep);
  556.     return pte;
  557. }
  558.  
  559. static inline pte_t
  560. ptep_clear_flush(struct vm_area_struct *vma,
  561.          unsigned long address, pte_t *ptep)
  562. {
  563.     pte_t pte = *ptep;
  564. #ifndef __s390x__
  565.     if (!(pte_val(pte) & _PAGE_INVALID)) {
  566.         /* S390 has 1mb segments, we are emulating 4MB segments */
  567.         pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00);
  568.         __asm__ __volatile__ ("ipte %2,%3"
  569.                       : "=m" (*ptep) : "m" (*ptep),
  570.                         "a" (pto), "a" (address) );
  571.     }
  572. #else /* __s390x__ */
  573.     if (!(pte_val(pte) & _PAGE_INVALID)) 
  574.         __asm__ __volatile__ ("ipte %2,%3"
  575.                       : "=m" (*ptep) : "m" (*ptep),
  576.                         "a" (ptep), "a" (address) );
  577. #endif /* __s390x__ */
  578.     pte_val(*ptep) = _PAGE_INVALID_EMPTY;
  579.     return pte;
  580. }
  581.  
  582. static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
  583. {
  584.     pte_t old_pte = *ptep;
  585.     set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
  586. }
  587.  
  588. static inline void
  589. ptep_establish(struct vm_area_struct *vma, 
  590.            unsigned long address, pte_t *ptep,
  591.            pte_t entry)
  592. {
  593.     ptep_clear_flush(vma, address, ptep);
  594.     set_pte(ptep, entry);
  595. }
  596.  
  597. #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
  598.     ptep_establish(__vma, __address, __ptep, __entry)
  599.  
  600. /*
  601.  * Test and clear dirty bit in storage key.
  602.  * We can't clear the changed bit atomically. This is a potential
  603.  * race against modification of the referenced bit. This function
  604.  * should therefore only be called if it is not mapped in any
  605.  * address space.
  606.  */
  607. #define page_test_and_clear_dirty(_page)                  \
  608. ({                                      \
  609.     struct page *__page = (_page);                      \
  610.     unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
  611.     int __skey = page_get_storage_key(__physpage);              \
  612.     if (__skey & _PAGE_CHANGED)                      \
  613.         page_set_storage_key(__physpage, __skey & ~_PAGE_CHANGED);\
  614.     (__skey & _PAGE_CHANGED);                      \
  615. })
  616.  
  617. /*
  618.  * Test and clear referenced bit in storage key.
  619.  */
  620. #define page_test_and_clear_young(page)                      \
  621. ({                                      \
  622.     struct page *__page = (page);                      \
  623.     unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
  624.     int __ccode;                              \
  625.     asm volatile ("rrbe 0,%1\n\t"                      \
  626.               "ipm  %0\n\t"                      \
  627.               "srl  %0,28\n\t"                       \
  628.                       : "=d" (__ccode) : "a" (__physpage) : "cc" );      \
  629.     (__ccode & 2);                              \
  630. })
  631.  
  632. /*
  633.  * Conversion functions: convert a page and protection to a page entry,
  634.  * and a page entry and page directory to the page they refer to.
  635.  */
  636. static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
  637. {
  638.     pte_t __pte;
  639.     pte_val(__pte) = physpage + pgprot_val(pgprot);
  640.     return __pte;
  641. }
  642.  
  643. #define mk_pte(pg, pgprot)                                                \
  644. ({                                                                        \
  645.     struct page *__page = (pg);                                       \
  646.     pgprot_t __pgprot = (pgprot);                      \
  647.     unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
  648.     pte_t __pte = mk_pte_phys(__physpage, __pgprot);                  \
  649.     __pte;                                                            \
  650. })
  651.  
  652. #define pfn_pte(pfn, pgprot)                                              \
  653. ({                                                                        \
  654.     pgprot_t __pgprot = (pgprot);                      \
  655.     unsigned long __physpage = __pa((pfn) << PAGE_SHIFT);             \
  656.     pte_t __pte = mk_pte_phys(__physpage, __pgprot);                  \
  657.     __pte;                                                            \
  658. })
  659.  
  660. #define SetPageUptodate(_page) \
  661.     do {                                      \
  662.         struct page *__page = (_page);                      \
  663.         if (!test_and_set_bit(PG_uptodate, &__page->flags))          \
  664.             page_test_and_clear_dirty(_page);              \
  665.     } while (0)
  666.  
  667. #ifdef __s390x__
  668.  
  669. #define pfn_pmd(pfn, pgprot)                                              \
  670. ({                                                                        \
  671.     pgprot_t __pgprot = (pgprot);                                     \
  672.     unsigned long __physpage = __pa((pfn) << PAGE_SHIFT);             \
  673.     pmd_t __pmd = __pmd(__physpage + pgprot_val(__pgprot));           \
  674.     __pmd;                                                            \
  675. })
  676.  
  677. #endif /* __s390x__ */
  678.  
  679. #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
  680. #define pte_page(x) pfn_to_page(pte_pfn(x))
  681.  
  682. #define pmd_page_kernel(pmd) (pmd_val(pmd) & PAGE_MASK)
  683.  
  684. #define pmd_page(pmd) (mem_map+(pmd_val(pmd) >> PAGE_SHIFT))
  685.  
  686. #define pgd_page_kernel(pgd) (pgd_val(pgd) & PAGE_MASK)
  687.  
  688. /* to find an entry in a page-table-directory */
  689. #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
  690. #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
  691.  
  692. /* to find an entry in a kernel page-table-directory */
  693. #define pgd_offset_k(address) pgd_offset(&init_mm, address)
  694.  
  695. #ifndef __s390x__
  696.  
  697. /* Find an entry in the second-level page table.. */
  698. static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
  699. {
  700.         return (pmd_t *) dir;
  701. }
  702.  
  703. #else /* __s390x__ */
  704.  
  705. /* Find an entry in the second-level page table.. */
  706. #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
  707. #define pmd_offset(dir,addr) \
  708.     ((pmd_t *) pgd_page_kernel(*(dir)) + pmd_index(addr))
  709.  
  710. #endif /* __s390x__ */
  711.  
  712. /* Find an entry in the third-level page table.. */
  713. #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
  714. #define pte_offset_kernel(pmd, address) \
  715.     ((pte_t *) pmd_page_kernel(*(pmd)) + pte_index(address))
  716. #define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
  717. #define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address)
  718. #define pte_unmap(pte) do { } while (0)
  719. #define pte_unmap_nested(pte) do { } while (0)
  720.  
  721. /*
  722.  * 31 bit swap entry format:
  723.  * A page-table entry has some bits we have to treat in a special way.
  724.  * Bits 0, 20 and bit 23 have to be zero, otherwise an specification
  725.  * exception will occur instead of a page translation exception. The
  726.  * specifiation exception has the bad habit not to store necessary
  727.  * information in the lowcore.
  728.  * Bit 21 and bit 22 are the page invalid bit and the page protection
  729.  * bit. We set both to indicate a swapped page.
  730.  * Bit 30 and 31 are used to distinguish the different page types. For
  731.  * a swapped page these bits need to be zero.
  732.  * This leaves the bits 1-19 and bits 24-29 to store type and offset.
  733.  * We use the 5 bits from 25-29 for the type and the 20 bits from 1-19
  734.  * plus 24 for the offset.
  735.  * 0|     offset        |0110|o|type |00|
  736.  * 0 0000000001111111111 2222 2 22222 33
  737.  * 0 1234567890123456789 0123 4 56789 01
  738.  *
  739.  * 64 bit swap entry format:
  740.  * A page-table entry has some bits we have to treat in a special way.
  741.  * Bits 52 and bit 55 have to be zero, otherwise an specification
  742.  * exception will occur instead of a page translation exception. The
  743.  * specifiation exception has the bad habit not to store necessary
  744.  * information in the lowcore.
  745.  * Bit 53 and bit 54 are the page invalid bit and the page protection
  746.  * bit. We set both to indicate a swapped page.
  747.  * Bit 62 and 63 are used to distinguish the different page types. For
  748.  * a swapped page these bits need to be zero.
  749.  * This leaves the bits 0-51 and bits 56-61 to store type and offset.
  750.  * We use the 5 bits from 57-61 for the type and the 53 bits from 0-51
  751.  * plus 56 for the offset.
  752.  * |                      offset                        |0110|o|type |00|
  753.  *  0000000000111111111122222222223333333333444444444455 5555 5 55566 66
  754.  *  0123456789012345678901234567890123456789012345678901 2345 6 78901 23
  755.  */
  756. #ifndef __s390x__
  757. #define __SWP_OFFSET_MASK (~0UL >> 12)
  758. #else
  759. #define __SWP_OFFSET_MASK (~0UL >> 11)
  760. #endif
  761. static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
  762. {
  763.     pte_t pte;
  764.     offset &= __SWP_OFFSET_MASK;
  765.     pte_val(pte) = _PAGE_INVALID_SWAP | ((type & 0x1f) << 2) |
  766.         ((offset & 1UL) << 7) | ((offset & ~1UL) << 11);
  767.     return pte;
  768. }
  769.  
  770. #define __swp_type(entry)    (((entry).val >> 2) & 0x1f)
  771. #define __swp_offset(entry)    (((entry).val >> 11) | (((entry).val >> 7) & 1))
  772. #define __swp_entry(type,offset) ((swp_entry_t) { pte_val(mk_swap_pte((type),(offset))) })
  773.  
  774. #define __pte_to_swp_entry(pte)    ((swp_entry_t) { pte_val(pte) })
  775. #define __swp_entry_to_pte(x)    ((pte_t) { (x).val })
  776.  
  777. #ifndef __s390x__
  778. # define PTE_FILE_MAX_BITS    26
  779. #else /* __s390x__ */
  780. # define PTE_FILE_MAX_BITS    59
  781. #endif /* __s390x__ */
  782.  
  783. #define pte_to_pgoff(__pte) \
  784.     ((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f))
  785.  
  786. #define pgoff_to_pte(__off) \
  787.     ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \
  788.            | _PAGE_INVALID_FILE })
  789.  
  790. #endif /* !__ASSEMBLY__ */
  791.  
  792. #define kern_addr_valid(addr)   (1)
  793.  
  794. /*
  795.  * No page table caches to initialise
  796.  */
  797. #define pgtable_cache_init()    do { } while (0)
  798.  
  799. #define __HAVE_ARCH_PTEP_ESTABLISH
  800. #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
  801. #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
  802. #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
  803. #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
  804. #define __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
  805. #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
  806. #define __HAVE_ARCH_PTEP_CLEAR_FLUSH
  807. #define __HAVE_ARCH_PTEP_SET_WRPROTECT
  808. #define __HAVE_ARCH_PTE_SAME
  809. #define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
  810. #define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
  811. #include <asm-generic/pgtable.h>
  812.  
  813. #endif /* _S390_PAGE_H */
  814.  
  815.