pgtable.h revision a53c8fab3f87c995c30ac226a03af95361243144
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  S390 version
3a53c8fab3f87c995c30ac226a03af95361243144Heiko Carstens *    Copyright IBM Corp. 1999, 2000
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    Author(s): Hartmut Penner (hp@de.ibm.com)
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *               Ulrich Weigand (weigand@de.ibm.com)
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *               Martin Schwidefsky (schwidefsky@de.ibm.com)
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Derived from "include/asm-i386/pgtable.h"
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _ASM_S390_PGTABLE_H
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _ASM_S390_PGTABLE_H
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The Linux memory management assumes a three-level page table setup. For
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * s390 31 bit we "fold" the mid level into the top-level page table, so
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that we physically have the same two-level page table as the s390 mmu
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * expects in 31 bit mode. For s390 64 bit we use three of the five levels
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the hardware provides (region first and region second tables are not
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * used).
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The "pgd_xxx()" functions are trivial for a folded two-level
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * setup: the pgd is never bad, and a pmd always exists (as it's folded
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * into the pgd entry)
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file contains the functions and defines necessary to modify and use
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the S390 page table tree.
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __ASSEMBLY__
309789db08c020193ae18826c3aa48bd24296f7848Heiko Carstens#include <linux/sched.h>
312dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens#include <linux/mm_types.h>
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/bug.h>
33b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#include <asm/page.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void paging_init(void);
372b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstensextern void vmem_map_init(void);
3892f842eac7ee321c8a0749aba2513541b4ac226fMartin Schwidefskyextern void fault_init(void);
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The S390 doesn't have any external MMU info: the kernel page
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * tables contain all the necessary information.
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
444b3073e1c53a256275f1079c0fbfbe85883d9275Russell King#define update_mmu_cache(vma, address, ptep)     do { } while (0)
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
47238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky * ZERO_PAGE is a global shared page that is always zero; used
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for zero-mapped memory areas etc..
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
50238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky
51238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefskyextern unsigned long empty_zero_page;
52238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefskyextern unsigned long zero_page_mask;
53238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky
54238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky#define ZERO_PAGE(vaddr) \
55238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky	(virt_to_page((void *)(empty_zero_page + \
56238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky	 (((unsigned long)(vaddr)) &zero_page_mask))))
57238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky
58238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky#define is_zero_pfn is_zero_pfn
59238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefskystatic inline int is_zero_pfn(unsigned long pfn)
60238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky{
61238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky	extern unsigned long zero_pfn;
62238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky	unsigned long offset_from_zero_pfn = pfn - zero_pfn;
63238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky	return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT);
64238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky}
65238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky
66238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky#define my_zero_pfn(addr)	page_to_pfn(ZERO_PAGE(addr))
67238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* !__ASSEMBLY__ */
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PMD_SHIFT determines the size of the area a second-level page
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * table can map
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PGDIR_SHIFT determines what a third-level page table entry can map
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
75f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifndef CONFIG_64BIT
76146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky# define PMD_SHIFT	20
77146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky# define PUD_SHIFT	20
78146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky# define PGDIR_SHIFT	20
79f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#else /* CONFIG_64BIT */
80146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky# define PMD_SHIFT	20
81190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky# define PUD_SHIFT	31
825a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky# define PGDIR_SHIFT	42
83f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#endif /* CONFIG_64BIT */
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PMD_SIZE        (1UL << PMD_SHIFT)
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PMD_MASK        (~(PMD_SIZE-1))
87190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define PUD_SIZE	(1UL << PUD_SHIFT)
88190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define PUD_MASK	(~(PUD_SIZE-1))
895a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
905a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define PGDIR_MASK	(~(PGDIR_SIZE-1))
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * entries per page directory level: the S390 is two-level, so
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we don't really have any PMD directory physically.
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for S390 segment-table entries are combined to one PGD
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that leads to 1024 pte per pgd
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
98146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky#define PTRS_PER_PTE	256
99f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifndef CONFIG_64BIT
100146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky#define PTRS_PER_PMD	1
1015a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define PTRS_PER_PUD	1
102f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#else /* CONFIG_64BIT */
103146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky#define PTRS_PER_PMD	2048
1045a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define PTRS_PER_PUD	2048
105f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#endif /* CONFIG_64BIT */
106146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky#define PTRS_PER_PGD	2048
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
108d455a3696c72283923e6870e9e4fe1daa861d7cdHugh Dickins#define FIRST_USER_ADDRESS  0
109d455a3696c72283923e6870e9e4fe1daa861d7cdHugh Dickins
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pte_ERROR(e) \
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e))
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pmd_ERROR(e) \
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e))
114190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_ERROR(e) \
115190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky	printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e))
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pgd_ERROR(e) \
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e))
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __ASSEMBLY__
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1215fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * The vmalloc area will always be on the topmost area of the kernel
1227d3f661e5757e84f1fb2e10093cfa2f7b057bc2fMartin Schwidefsky * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
1235fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * which should be enough for any sane case.
1245fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * By putting vmalloc at the top, we maximise the gap between physical
1255fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * memory and vmalloc to catch misplaced memory accesses. As a side
1265fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * effect, this also makes sure that 64 bit module code cannot be used
1275fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * as system call address.
1288b62bc9642300471737bc3b77b2a4a2ead46dedbHeiko Carstens */
129239a64255fae8933d95273b5b92545949ca4e743Heiko Carstensextern unsigned long VMALLOC_START;
13014045ebf1e1156d966a796cacad91028e01797e5Martin Schwidefskyextern unsigned long VMALLOC_END;
13114045ebf1e1156d966a796cacad91028e01797e5Martin Schwidefskyextern struct page *vmemmap;
132239a64255fae8933d95273b5b92545949ca4e743Heiko Carstens
13314045ebf1e1156d966a796cacad91028e01797e5Martin Schwidefsky#define VMEM_MAX_PHYS ((unsigned long) vmemmap)
1345fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 31 bit pagetable entry of S390 has following format:
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  |   PFRA          |    |  OS  |
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0                   0IP0
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 00000000001111111111222222222233
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 01234567890123456789012345678901
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Page-Invalid Bit:    Page is not available for address-translation
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Page-Protection Bit: Store access not possible for page
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 31 bit segmenttable entry of S390 has following format:
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  |   P-table origin      |  |PTL
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0                         IC
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 00000000001111111111222222222233
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 01234567890123456789012345678901
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Segment-Invalid Bit:    Segment is not available for address-translation
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * C Common-Segment Bit:     Segment is not private (PoP 3-30)
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PTL Page-Table-Length:    Page-table length (PTL+1*16 entries -> up to 256)
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The 31 bit segmenttable origin of S390 has following format:
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  |S-table origin   |     | STL |
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * X                   **GPS
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 00000000001111111111222222222233
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 01234567890123456789012345678901
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * X Space-Switch event:
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * G Segment-Invalid Bit:     *
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Private-Space Bit:       Segment is not private (PoP 3-30)
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * S Storage-Alteration:
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STL Segment-Table-Length:  Segment-table length (STL+1*16 entries -> up to 2048)
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 64 bit pagetable entry of S390 has following format:
1696a985c6194017de2c062916ad1cd00dee0302c40Christian Borntraeger * |			 PFRA			      |0IPC|  OS  |
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0000000000111111111122222222223333333333444444444455555555556666
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0123456789012345678901234567890123456789012345678901234567890123
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Page-Invalid Bit:    Page is not available for address-translation
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Page-Protection Bit: Store access not possible for page
1756a985c6194017de2c062916ad1cd00dee0302c40Christian Borntraeger * C Change-bit override: HW is not required to set change bit
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 64 bit segmenttable entry of S390 has following format:
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * |        P-table origin                              |      TT
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0000000000111111111122222222223333333333444444444455555555556666
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0123456789012345678901234567890123456789012345678901234567890123
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Segment-Invalid Bit:    Segment is not available for address-translation
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * C Common-Segment Bit:     Segment is not private (PoP 3-30)
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Page-Protection Bit: Store access not possible for page
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TT Type 00
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 64 bit region table entry of S390 has following format:
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * |        S-table origin                             |   TF  TTTL
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0000000000111111111122222222223333333333444444444455555555556666
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0123456789012345678901234567890123456789012345678901234567890123
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Segment-Invalid Bit:    Segment is not available for address-translation
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TT Type 01
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TF
195190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky * TL Table length
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The 64 bit regiontable origin of S390 has following format:
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * |      region table origon                          |       DTTL
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0000000000111111111122222222223333333333444444444455555555556666
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0123456789012345678901234567890123456789012345678901234567890123
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * X Space-Switch event:
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * G Segment-Invalid Bit:
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Private-Space Bit:
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * S Storage-Alteration:
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * R Real space
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TL Table-Length:
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A storage key has the following format:
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | ACC |F|R|C|0|
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  0   3 4 5 6 7
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ACC: access key
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * F  : fetch protection bit
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * R  : referenced bit
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * C  : changed bit
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Hardware bits in the page table entry */
2196a985c6194017de2c062916ad1cd00dee0302c40Christian Borntraeger#define _PAGE_CO	0x100		/* HW Change-bit override */
220833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_RO	0x200		/* HW read-only bit  */
221833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_INVALID	0x400		/* HW invalid bit    */
2223610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky
2233610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Software bits in the page table entry */
224833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_SWT	0x001		/* SW pte type bit t */
225833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_SWX	0x002		/* SW pte type bit x */
226b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#define _PAGE_SWC	0x004		/* SW pte changed bit (for KVM) */
227b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#define _PAGE_SWR	0x008		/* SW pte referenced bit (for KVM) */
228b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#define _PAGE_SPECIAL	0x010		/* SW associated with special page */
229a08cb629f546d1cecebe955392197f226e58dbe1Nick Piggin#define __HAVE_ARCH_PTE_SPECIAL
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231138c9021ca68d6f8a6fac3418995fee102a3cc22Nick Piggin/* Set of bits not changed in pte_modify */
232b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_SPECIAL | _PAGE_SWC | _PAGE_SWR)
233138c9021ca68d6f8a6fac3418995fee102a3cc22Nick Piggin
234833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky/* Six different types of pages. */
2359282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define _PAGE_TYPE_EMPTY	0x400
2369282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define _PAGE_TYPE_NONE		0x401
237833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_TYPE_SWAP		0x403
238833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_TYPE_FILE		0x601	/* bit 0x002 is used for offset !! */
2399282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define _PAGE_TYPE_RO		0x200
2409282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define _PAGE_TYPE_RW		0x000
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
242833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky/*
24353492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer * Only four types for huge pages, using the invalid bit and protection bit
24453492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer * of a segment table entry.
24553492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer */
24653492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _HPAGE_TYPE_EMPTY	0x020	/* _SEGMENT_ENTRY_INV */
24753492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _HPAGE_TYPE_NONE	0x220
24853492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _HPAGE_TYPE_RO		0x200	/* _SEGMENT_ENTRY_RO  */
24953492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _HPAGE_TYPE_RW		0x000
25053492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer
25153492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer/*
252833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * PTE type bits are rather complicated. handle_pte_fault uses pte_present,
253833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * pte_none and pte_file to find out the pte type WITHOUT holding the page
254833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * table lock. ptep_clear_flush on the other hand uses ptep_clear_flush to
255833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * invalidate a given pte. ipte sets the hw invalid bit and clears all tlbs
256833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * for the page. The page table entry is set to _PAGE_TYPE_EMPTY afterwards.
257833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * This change is done while holding the lock, but the intermediate step
258833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * of a previously valid pte with the hw invalid bit set can be observed by
259833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * handle_pte_fault. That makes it necessary that all valid pte types with
260833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * the hw invalid bit set must be distinguishable from the four pte types
261833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * empty, none, swap and file.
262833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky *
263833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky *			irxt  ipte  irxt
264833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_EMPTY	1000   ->   1000
265833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_NONE	1001   ->   1001
266833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_SWAP	1011   ->   1011
267833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_FILE	11?1   ->   11?1
268833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_RO	0100   ->   1100
269833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_RW	0000   ->   1000
270833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky *
271c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaefer * pte_none is true for bits combinations 1000, 1010, 1100, 1110
272833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * pte_present is true for bits combinations 0000, 0010, 0100, 0110, 1001
273833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * pte_file is true for bits combinations 1101, 1111
274c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaefer * swap pte is 1011 and 0001, 0011, 0101, 0111 are invalid.
275833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky */
276833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky
277f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifndef CONFIG_64BIT
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2793610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Bits in the segment table address-space-control-element */
2803610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_SPACE_SWITCH	0x80000000UL	/* space switch event	    */
2813610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_ORIGIN_MASK	0x7ffff000UL	/* segment table origin	    */
2823610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_PRIVATE_SPACE	0x100	/* private space control	    */
2833610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_ALT_EVENT		0x80	/* storage alteration event control */
2843610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TABLE_LENGTH	0x7f	/* 128 x 64 entries = 8k	    */
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2863610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Bits in the segment table entry */
2873610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_ORIGIN	0x7fffffc0UL	/* page table origin	    */
28880217147a3d80c8a4e48f06e2f6e965455f3fe2aMartin Schwidefsky#define _SEGMENT_ENTRY_RO	0x200	/* page protection bit		    */
2893610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_INV	0x20	/* invalid segment table entry	    */
2903610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_COMMON	0x10	/* common segment bit		    */
2913610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_PTL	0x0f	/* page table length		    */
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2933610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY		(_SEGMENT_ENTRY_PTL)
2943610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_EMPTY	(_SEGMENT_ENTRY_INV)
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2966c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky/* Page status table bits for virtualization */
2976c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_ACC_BITS	0xf0000000UL
2986c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_FP_BIT	0x08000000UL
2996c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_PCL_BIT	0x00800000UL
3006c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_HR_BIT	0x00400000UL
3016c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_HC_BIT	0x00200000UL
3026c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_GR_BIT	0x00040000UL
3036c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_GC_BIT	0x00020000UL
3046c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky
3056c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky/* User dirty / referenced bit for KVM's migration feature */
3066c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define KVM_UR_BIT	0x00008000UL
3076c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define KVM_UC_BIT	0x00004000UL
3086c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky
309f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#else /* CONFIG_64BIT */
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3113610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Bits in the segment/region table address-space-control-element */
3123610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_ORIGIN		~0xfffUL/* segment table origin		    */
3133610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_PRIVATE_SPACE	0x100	/* private space control	    */
3143610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_ALT_EVENT		0x80	/* storage alteration event control */
3153610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_SPACE_SWITCH	0x40	/* space switch event		    */
3163610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_REAL_SPACE	0x20	/* real space control		    */
3173610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_MASK		0x0c	/* asce table type mask		    */
3183610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_REGION1	0x0c	/* region first table type	    */
3193610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_REGION2	0x08	/* region second table type	    */
3203610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_REGION3	0x04	/* region third table type	    */
3213610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_SEGMENT	0x00	/* segment table type		    */
3223610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TABLE_LENGTH	0x03	/* region table length		    */
3233610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky
3243610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Bits in the region table entry */
3253610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_ORIGIN	~0xfffUL/* region/segment table origin	    */
3263610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_INV	0x20	/* invalid region table entry	    */
3273610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_TYPE_MASK	0x0c	/* region/segment table type mask   */
3283610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_TYPE_R1	0x0c	/* region first table type	    */
3293610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_TYPE_R2	0x08	/* region second table type	    */
3303610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_TYPE_R3	0x04	/* region third table type	    */
3313610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_LENGTH	0x03	/* region third length		    */
3323610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky
3333610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION1_ENTRY		(_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_LENGTH)
3343610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION1_ENTRY_EMPTY	(_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INV)
3353610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION2_ENTRY		(_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH)
3363610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION2_ENTRY_EMPTY	(_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INV)
3373610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION3_ENTRY		(_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH)
3383610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION3_ENTRY_EMPTY	(_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV)
3393610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Bits in the segment table entry */
3413610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_ORIGIN	~0x7ffUL/* segment table origin		    */
3423610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_RO	0x200	/* page protection bit		    */
3433610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_INV	0x20	/* invalid segment table entry	    */
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3453610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY		(0)
3463610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_EMPTY	(_SEGMENT_ENTRY_INV)
3473610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky
34853492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _SEGMENT_ENTRY_LARGE	0x400	/* STE-format control, large page   */
34953492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _SEGMENT_ENTRY_CO	0x100	/* change-recording override   */
35053492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer
3516c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky/* Page status table bits for virtualization */
3526c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_ACC_BITS	0xf000000000000000UL
3536c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_FP_BIT	0x0800000000000000UL
3546c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_PCL_BIT	0x0080000000000000UL
3556c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_HR_BIT	0x0040000000000000UL
3566c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_HC_BIT	0x0020000000000000UL
3576c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_GR_BIT	0x0004000000000000UL
3586c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define RCP_GC_BIT	0x0002000000000000UL
3596c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky
3606c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky/* User dirty / referenced bit for KVM's migration feature */
3616c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define KVM_UR_BIT	0x0000800000000000UL
3626c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky#define KVM_UC_BIT	0x0000400000000000UL
3636c61cfe91be53b444abc1da2dbab14efa77706c0Martin Schwidefsky
364f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#endif /* CONFIG_64BIT */
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3673610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky * A user page table pointer has the space-switch-event bit, the
3683610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky * private-space-control bit and the storage-alteration-event-control
3693610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky * bit set. A kernel page table pointer doesn't need them.
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3713610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_USER_BITS		(_ASCE_SPACE_SWITCH | _ASCE_PRIVATE_SPACE | \
3723610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky				 _ASCE_ALT_EVENT)
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3759282ed929758b82f448a40d3c17319d794970624Gerald Schaefer * Page protection definitions.
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3779282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_NONE	__pgprot(_PAGE_TYPE_NONE)
3789282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_RO		__pgprot(_PAGE_TYPE_RO)
3799282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_RW		__pgprot(_PAGE_TYPE_RW)
3809282ed929758b82f448a40d3c17319d794970624Gerald Schaefer
3819282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_KERNEL	PAGE_RW
3829282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_COPY	PAGE_RO
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
385043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky * On s390 the page table entry has an invalid bit and a read-only bit.
386043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky * Read permission implies execute permission and write permission
387043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky * implies read permission.
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds         /*xwr*/
3909282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __P000	PAGE_NONE
3919282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __P001	PAGE_RO
3929282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __P010	PAGE_RO
3939282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __P011	PAGE_RO
394043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __P100	PAGE_RO
395043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __P101	PAGE_RO
396043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __P110	PAGE_RO
397043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __P111	PAGE_RO
3989282ed929758b82f448a40d3c17319d794970624Gerald Schaefer
3999282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __S000	PAGE_NONE
4009282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __S001	PAGE_RO
4019282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __S010	PAGE_RW
4029282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __S011	PAGE_RW
403043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __S100	PAGE_RO
404043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __S101	PAGE_RO
405043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __S110	PAGE_RW
406043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __S111	PAGE_RW
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
408b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline int mm_exclusive(struct mm_struct *mm)
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
410b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return likely(mm == current->active_mm &&
411b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		      atomic_read(&mm->context.attach_count) <= 1);
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
414b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline int mm_has_pgste(struct mm_struct *mm)
415b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
416b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#ifdef CONFIG_PGSTE
417b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (unlikely(mm->context.has_pgste))
418b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		return 1;
419b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#endif
420b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return 0;
421b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pgd/pmd/pte query functions
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
425f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifndef CONFIG_64BIT
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4274448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pgd_present(pgd_t pgd) { return 1; }
4284448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pgd_none(pgd_t pgd)    { return 0; }
4294448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pgd_bad(pgd_t pgd)     { return 0; }
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
431190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_present(pud_t pud) { return 1; }
432190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_none(pud_t pud)	 { return 0; }
433190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_bad(pud_t pud)	 { return 0; }
434190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky
435f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#else /* CONFIG_64BIT */
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4375a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline int pgd_present(pgd_t pgd)
4385a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{
4396252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2)
4406252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		return 1;
4415a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky	return (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) != 0UL;
4425a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky}
4435a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky
4445a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline int pgd_none(pgd_t pgd)
4455a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{
4466252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2)
4476252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		return 0;
4485a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky	return (pgd_val(pgd) & _REGION_ENTRY_INV) != 0UL;
4495a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky}
4505a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky
4515a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline int pgd_bad(pgd_t pgd)
4525a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{
4536252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	/*
4546252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	 * With dynamic page table levels the pgd can be a region table
4556252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	 * entry or a segment table entry. Check for the bit that are
4566252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	 * invalid for either table entry.
4576252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	 */
4585a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky	unsigned long mask =
4596252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV &
4605a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky		~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH;
4615a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky	return (pgd_val(pgd) & mask) != 0;
4625a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky}
463190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky
464190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_present(pud_t pud)
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4666252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3)
4676252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		return 1;
4680d01792300c4d7425eabac9095c603cdb411d2a5Martin Schwidefsky	return (pud_val(pud) & _REGION_ENTRY_ORIGIN) != 0UL;
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_none(pud_t pud)
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4736252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3)
4746252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		return 0;
4750d01792300c4d7425eabac9095c603cdb411d2a5Martin Schwidefsky	return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL;
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
478190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_bad(pud_t pud)
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4806252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	/*
4816252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	 * With dynamic page table levels the pud can be a region table
4826252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	 * entry or a segment table entry. Check for the bit that are
4836252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	 * invalid for either table entry.
4846252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	 */
4855a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky	unsigned long mask =
4866252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV &
4875a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky		~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH;
4885a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky	return (pud_val(pud) & mask) != 0;
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
491f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#endif /* CONFIG_64BIT */
4923610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky
4934448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pmd_present(pmd_t pmd)
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4950d01792300c4d7425eabac9095c603cdb411d2a5Martin Schwidefsky	return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL;
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4984448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pmd_none(pmd_t pmd)
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5000d01792300c4d7425eabac9095c603cdb411d2a5Martin Schwidefsky	return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL;
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5034448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pmd_bad(pmd_t pmd)
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5053610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky	unsigned long mask = ~_SEGMENT_ENTRY_ORIGIN & ~_SEGMENT_ENTRY_INV;
5063610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky	return (pmd_val(pmd) & mask) != _SEGMENT_ENTRY;
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5094448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_none(pte_t pte)
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
511833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky	return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT);
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5144448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_present(pte_t pte)
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
516833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky	unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT | _PAGE_SWX;
517833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky	return (pte_val(pte) & mask) == _PAGE_TYPE_NONE ||
518833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky		(!(pte_val(pte) & _PAGE_INVALID) &&
519833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky		 !(pte_val(pte) & _PAGE_SWT));
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5224448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_file(pte_t pte)
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
524833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky	unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT;
525833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky	return (pte_val(pte) & mask) == _PAGE_TYPE_FILE;
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5287e675137a8e1a4d45822746456dd389b65745bf6Nick Pigginstatic inline int pte_special(pte_t pte)
5297e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin{
530a08cb629f546d1cecebe955392197f226e58dbe1Nick Piggin	return (pte_val(pte) & _PAGE_SPECIAL);
5317e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin}
5327e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin
533ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTE_SAME
534b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline int pte_same(pte_t a, pte_t b)
535b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
536b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return pte_val(a) == pte_val(b);
537b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
539b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline pgste_t pgste_get_lock(pte_t *ptep)
5405b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger{
541b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	unsigned long new = 0;
5425b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#ifdef CONFIG_PGSTE
543b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	unsigned long old;
544b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
5455b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger	preempt_disable();
546b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	asm(
547b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		"	lg	%0,%2\n"
548b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		"0:	lgr	%1,%0\n"
549b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		"	nihh	%0,0xff7f\n"	/* clear RCP_PCL_BIT in old */
550b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		"	oihh	%1,0x0080\n"	/* set RCP_PCL_BIT in new */
551b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		"	csg	%0,%1,%2\n"
552b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		"	jl	0b\n"
553b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		: "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE])
554b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		: "Q" (ptep[PTRS_PER_PTE]) : "cc");
5555b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#endif
556b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return __pgste(new);
5575b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger}
5585b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger
559b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
5605b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger{
5615b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#ifdef CONFIG_PGSTE
562b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	asm(
563b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		"	nihh	%1,0xff7f\n"	/* clear RCP_PCL_BIT */
564b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		"	stg	%1,%0\n"
565b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		: "=Q" (ptep[PTRS_PER_PTE])
566b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		: "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) : "cc");
5675b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger	preempt_enable();
5685b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#endif
5695b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger}
5705b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger
571b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
5725b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger{
5735b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#ifdef CONFIG_PGSTE
574a43a9d93d40a69eceeb4e4a4c860cc20186d475cHeiko Carstens	unsigned long address, bits;
575b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	unsigned char skey;
576b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
57709b538833b85521d937a06faf61e6a3273253cc0Martin Schwidefsky	if (!pte_present(*ptep))
57809b538833b85521d937a06faf61e6a3273253cc0Martin Schwidefsky		return pgste;
579a43a9d93d40a69eceeb4e4a4c860cc20186d475cHeiko Carstens	address = pte_val(*ptep) & PAGE_MASK;
580a43a9d93d40a69eceeb4e4a4c860cc20186d475cHeiko Carstens	skey = page_get_storage_key(address);
581b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
582b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Clear page changed & referenced bit in the storage key */
5837c81878b34dd1b75dec5c8b68951d1439854d358Carsten Otte	if (bits & _PAGE_CHANGED)
5847c81878b34dd1b75dec5c8b68951d1439854d358Carsten Otte		page_set_storage_key(address, skey ^ bits, 1);
5857c81878b34dd1b75dec5c8b68951d1439854d358Carsten Otte	else if (bits)
5867c81878b34dd1b75dec5c8b68951d1439854d358Carsten Otte		page_reset_referenced(address);
587b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Transfer page changed & referenced bit to guest bits in pgste */
588b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_val(pgste) |= bits << 48;		/* RCP_GR_BIT & RCP_GC_BIT */
589b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Get host changed & referenced bits from pgste */
590b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	bits |= (pgste_val(pgste) & (RCP_HR_BIT | RCP_HC_BIT)) >> 52;
591b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Clear host bits in pgste. */
592b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_val(pgste) &= ~(RCP_HR_BIT | RCP_HC_BIT);
593b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_val(pgste) &= ~(RCP_ACC_BITS | RCP_FP_BIT);
594b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Copy page access key and fetch protection bit to pgste */
595b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_val(pgste) |=
596b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		(unsigned long) (skey & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56;
597b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Transfer changed and referenced to kvm user bits */
598b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_val(pgste) |= bits << 45;		/* KVM_UR_BIT & KVM_UC_BIT */
599b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Transfer changed & referenced to pte sofware bits */
600b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_val(*ptep) |= bits << 1;		/* _PAGE_SWR & _PAGE_SWC */
601b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#endif
602b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return pgste;
603b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
604b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
605b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
606b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste)
607b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
608b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#ifdef CONFIG_PGSTE
609b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	int young;
610b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
61109b538833b85521d937a06faf61e6a3273253cc0Martin Schwidefsky	if (!pte_present(*ptep))
61209b538833b85521d937a06faf61e6a3273253cc0Martin Schwidefsky		return pgste;
613b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK);
614b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Transfer page referenced bit to pte software bit (host view) */
615b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (young || (pgste_val(pgste) & RCP_HR_BIT))
616b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pte_val(*ptep) |= _PAGE_SWR;
617b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Clear host referenced bit in pgste. */
618b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_val(pgste) &= ~RCP_HR_BIT;
619b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Transfer page referenced bit to guest bit in pgste */
620b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_val(pgste) |= (unsigned long) young << 50; /* set RCP_GR_BIT */
621b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#endif
622b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return pgste;
623b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
624b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
625b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
62609b538833b85521d937a06faf61e6a3273253cc0Martin Schwidefskystatic inline void pgste_set_pte(pte_t *ptep, pgste_t pgste, pte_t entry)
627b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
628b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#ifdef CONFIG_PGSTE
629a43a9d93d40a69eceeb4e4a4c860cc20186d475cHeiko Carstens	unsigned long address;
630b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	unsigned long okey, nkey;
631b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
63209b538833b85521d937a06faf61e6a3273253cc0Martin Schwidefsky	if (!pte_present(entry))
63309b538833b85521d937a06faf61e6a3273253cc0Martin Schwidefsky		return;
63409b538833b85521d937a06faf61e6a3273253cc0Martin Schwidefsky	address = pte_val(entry) & PAGE_MASK;
635a43a9d93d40a69eceeb4e4a4c860cc20186d475cHeiko Carstens	okey = nkey = page_get_storage_key(address);
636b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT);
637b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	/* Set page access key and fetch protection bit from pgste */
638b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56;
639b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (okey != nkey)
640a43a9d93d40a69eceeb4e4a4c860cc20186d475cHeiko Carstens		page_set_storage_key(address, nkey, 1);
6415b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#endif
6425b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger}
6435b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger
644e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky/**
645e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * struct gmap_struct - guest address space
646e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * @mm: pointer to the parent mm_struct
647e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * @table: pointer to the page directory
648480e5926ce3bb61ec229be2dab08bdce8abb8d2eChristian Borntraeger * @asce: address space control element for gmap page table
649e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * @crst_list: list of all crst tables used in the guest address space
650e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky */
651e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskystruct gmap {
652e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky	struct list_head list;
653e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky	struct mm_struct *mm;
654e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky	unsigned long *table;
655480e5926ce3bb61ec229be2dab08bdce8abb8d2eChristian Borntraeger	unsigned long asce;
656e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky	struct list_head crst_list;
657e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky};
658e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky
659e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky/**
660e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * struct gmap_rmap - reverse mapping for segment table entries
661e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * @next: pointer to the next gmap_rmap structure in the list
662e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * @entry: pointer to a segment table entry
663e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky */
664e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskystruct gmap_rmap {
665e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky	struct list_head list;
666e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky	unsigned long *entry;
667e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky};
668e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky
669e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky/**
670e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * struct gmap_pgtable - gmap information attached to a page table
671e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * @vmaddr: address of the 1MB segment in the process virtual memory
672e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky * @mapper: list of segment table entries maping a page table
673e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky */
674e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskystruct gmap_pgtable {
675e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky	unsigned long vmaddr;
676e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky	struct list_head mapper;
677e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky};
678e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky
679e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskystruct gmap *gmap_alloc(struct mm_struct *mm);
680e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskyvoid gmap_free(struct gmap *gmap);
681e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskyvoid gmap_enable(struct gmap *gmap);
682e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskyvoid gmap_disable(struct gmap *gmap);
683e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskyint gmap_map_segment(struct gmap *gmap, unsigned long from,
684e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky		     unsigned long to, unsigned long length);
685e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskyint gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len);
686499069e1a421e2a85e76846c3237f00f1a5cb435Carsten Otteunsigned long __gmap_fault(unsigned long address, struct gmap *);
687e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefskyunsigned long gmap_fault(unsigned long address, struct gmap *);
688388186bc920d9200202e4d25de66fa95b1b8fc68Christian Borntraegervoid gmap_discard(unsigned long from, unsigned long to, struct gmap *);
689e5992f2e6c3829cd43dbc4438ee13dcd6506f7f3Martin Schwidefsky
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
691b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky * Certain architectures need to do special things when PTEs
692b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky * within a page table are directly modified.  Thus, the following
693b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky * hook is made available.
694b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky */
695b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
696b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky			      pte_t *ptep, pte_t entry)
697b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
698b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_t pgste;
699b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
700b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(mm)) {
701b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_get_lock(ptep);
70209b538833b85521d937a06faf61e6a3273253cc0Martin Schwidefsky		pgste_set_pte(ptep, pgste, entry);
703b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		*ptep = entry;
704b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_set_unlock(ptep, pgste);
705b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	} else
706b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		*ptep = entry;
707b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
708b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
709b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky/*
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * query functions pte_write/pte_dirty/pte_young only work if
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pte_present() is true. Undefined behaviour if not..
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
7134448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_write(pte_t pte)
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (pte_val(pte) & _PAGE_RO) == 0;
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7184448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_dirty(pte_t pte)
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
720b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#ifdef CONFIG_PGSTE
721b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (pte_val(pte) & _PAGE_SWC)
722b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		return 1;
723b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#endif
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7274448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_young(pte_t pte)
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
729b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#ifdef CONFIG_PGSTE
730b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (pte_val(pte) & _PAGE_SWR)
731b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		return 1;
732b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#endif
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pgd/pmd/pte modification functions
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
740b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline void pgd_clear(pgd_t *pgd)
7415a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{
742f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifdef CONFIG_64BIT
7436252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2)
7446252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		pgd_val(*pgd) = _REGION2_ENTRY_EMPTY;
745b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#endif
7465a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky}
7475a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky
748b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline void pud_clear(pud_t *pud)
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
750f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifdef CONFIG_64BIT
7516252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
7526252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		pud_val(*pud) = _REGION3_ENTRY_EMPTY;
753b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#endif
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
756b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline void pmd_clear(pmd_t *pmdp)
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7583610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky	pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY;
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7614448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7639282ed929758b82f448a40d3c17319d794970624Gerald Schaefer	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The following pte modification functions only work if
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pte_present() is true. Undefined behaviour if not..
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
7704448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
772138c9021ca68d6f8a6fac3418995fee102a3cc22Nick Piggin	pte_val(pte) &= _PAGE_CHG_MASK;
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pte_val(pte) |= pgprot_val(newprot);
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pte;
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7774448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_wrprotect(pte_t pte)
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7799282ed929758b82f448a40d3c17319d794970624Gerald Schaefer	/* Do not clobber _PAGE_TYPE_NONE pages!  */
7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!(pte_val(pte) & _PAGE_INVALID))
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pte_val(pte) |= _PAGE_RO;
7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pte;
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7854448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkwrite(pte_t pte)
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pte_val(pte) &= ~_PAGE_RO;
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pte;
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7914448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkclean(pte_t pte)
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
793b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#ifdef CONFIG_PGSTE
794b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_val(pte) &= ~_PAGE_SWC;
795b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#endif
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pte;
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7994448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkdirty(pte_t pte)
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pte;
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8044448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkold(pte_t pte)
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
806b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#ifdef CONFIG_PGSTE
807b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_val(pte) &= ~_PAGE_SWR;
808b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#endif
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pte;
8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8124448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkyoung(pte_t pte)
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pte;
8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8177e675137a8e1a4d45822746456dd389b65745bf6Nick Pigginstatic inline pte_t pte_mkspecial(pte_t pte)
8187e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin{
819a08cb629f546d1cecebe955392197f226e58dbe1Nick Piggin	pte_val(pte) |= _PAGE_SPECIAL;
8207e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin	return pte;
8217e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin}
8227e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin
82384afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens#ifdef CONFIG_HUGETLB_PAGE
82484afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstensstatic inline pte_t pte_mkhuge(pte_t pte)
82584afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens{
82684afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	/*
82784afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 * PROT_NONE needs to be remapped from the pte type to the ste type.
82884afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 * The HW invalid bit is also different for pte and ste. The pte
82984afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 * invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE
83084afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 * bit, so we don't have to clear it.
83184afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 */
83284afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	if (pte_val(pte) & _PAGE_INVALID) {
83384afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens		if (pte_val(pte) & _PAGE_SWT)
83484afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens			pte_val(pte) |= _HPAGE_TYPE_NONE;
83584afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens		pte_val(pte) |= _SEGMENT_ENTRY_INV;
83684afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	}
83784afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	/*
83884afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 * Clear SW pte bits SWT and SWX, there are no SW bits in a segment
83984afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 * table entry.
84084afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 */
84184afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX);
84284afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	/*
84384afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 * Also set the change-override bit because we don't need dirty bit
84484afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 * tracking for hugetlbfs pages.
84584afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	 */
84684afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO);
84784afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens	return pte;
84884afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens}
84984afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens#endif
85084afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens
85115e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke/*
852b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky * Get (and clear) the user dirty bit for a pte.
85315e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke */
854b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline int ptep_test_and_clear_user_dirty(struct mm_struct *mm,
855b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky						 pte_t *ptep)
85615e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke{
857b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_t pgste;
858b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	int dirty = 0;
859b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
860b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(mm)) {
861b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_get_lock(ptep);
862b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_update_all(ptep, pgste);
863b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		dirty = !!(pgste_val(pgste) & KVM_UC_BIT);
864b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_val(pgste) &= ~KVM_UC_BIT;
865b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_set_unlock(ptep, pgste);
866b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		return dirty;
86715e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke	}
86815e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke	return dirty;
86915e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke}
870b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
871b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky/*
872b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky * Get (and clear) the user referenced bit for a pte.
873b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky */
874b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline int ptep_test_and_clear_user_young(struct mm_struct *mm,
875b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky						 pte_t *ptep)
876b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
877b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_t pgste;
878b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	int young = 0;
879b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
880b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(mm)) {
881b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_get_lock(ptep);
882b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_update_young(ptep, pgste);
883b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		young = !!(pgste_val(pgste) & KVM_UR_BIT);
884b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_val(pgste) &= ~KVM_UR_BIT;
885b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_set_unlock(ptep, pgste);
886b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	}
887b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return young;
888b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
88915e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke
890ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
891ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefskystatic inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
892ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky					    unsigned long addr, pte_t *ptep)
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
894b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_t pgste;
895b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_t pte;
896b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
897b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(vma->vm_mm)) {
898b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_get_lock(ptep);
899b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_update_young(ptep, pgste);
900b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pte = *ptep;
901b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		*ptep = pte_mkold(pte);
902b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_set_unlock(ptep, pgste);
903b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		return pte_young(pte);
904b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	}
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
908ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
909ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefskystatic inline int ptep_clear_flush_young(struct vm_area_struct *vma,
910ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky					 unsigned long address, pte_t *ptep)
9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9125b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger	/* No need to flush TLB
9135b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger	 * On s390 reference bits are in storage key and never in TLB
9145b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger	 * With virtualization we handle the reference bit, without we
9155b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger	 * we can simply return */
9165b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger	return ptep_test_and_clear_young(vma, address, ptep);
9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9199282ed929758b82f448a40d3c17319d794970624Gerald Schaeferstatic inline void __ptep_ipte(unsigned long address, pte_t *ptep)
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9219282ed929758b82f448a40d3c17319d794970624Gerald Schaefer	if (!(pte_val(*ptep) & _PAGE_INVALID)) {
922f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifndef CONFIG_64BIT
923146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky		/* pto must point to the start of the segment table */
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00);
9259282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#else
9269282ed929758b82f448a40d3c17319d794970624Gerald Schaefer		/* ipte in zarch mode can do the math */
9279282ed929758b82f448a40d3c17319d794970624Gerald Schaefer		pte_t *pto = ptep;
9289282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#endif
92994c12cc7d196bab34aaa98d38521549fa1e5ef76Martin Schwidefsky		asm volatile(
93094c12cc7d196bab34aaa98d38521549fa1e5ef76Martin Schwidefsky			"	ipte	%2,%3"
93194c12cc7d196bab34aaa98d38521549fa1e5ef76Martin Schwidefsky			: "=m" (*ptep) : "m" (*ptep),
93294c12cc7d196bab34aaa98d38521549fa1e5ef76Martin Schwidefsky			  "a" (pto), "a" (address));
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9349282ed929758b82f448a40d3c17319d794970624Gerald Schaefer}
9359282ed929758b82f448a40d3c17319d794970624Gerald Schaefer
936ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky/*
937ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * This is hard to understand. ptep_get_and_clear and ptep_clear_flush
938ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * both clear the TLB for the unmapped pte. The reason is that
939ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * ptep_get_and_clear is used in common code (e.g. change_pte_range)
940ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * to modify an active pte. The sequence is
941ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky *   1) ptep_get_and_clear
942ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky *   2) set_pte_at
943ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky *   3) flush_tlb_range
944ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * On s390 the tlb needs to get flushed with the modification of the pte
945ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * if the pte is active. The only way how this can be implemented is to
946ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * have ptep_get_and_clear do the tlb flush. In exchange flush_tlb_range
947ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * is a nop.
948ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky */
949ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
950b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline pte_t ptep_get_and_clear(struct mm_struct *mm,
951b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky				       unsigned long address, pte_t *ptep)
952b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
953b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_t pgste;
954b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_t pte;
955b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
956b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	mm->context.flush_mm = 1;
957b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(mm))
958b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_get_lock(ptep);
959b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
960b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte = *ptep;
961b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (!mm_exclusive(mm))
962b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		__ptep_ipte(address, ptep);
963b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
964b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
965b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(mm)) {
966b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_update_all(&pte, pgste);
967b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_set_unlock(ptep, pgste);
968b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	}
969b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return pte;
970b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
971b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
972b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky#define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
973b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline pte_t ptep_modify_prot_start(struct mm_struct *mm,
974b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky					   unsigned long address,
975b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky					   pte_t *ptep)
976b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
977b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_t pte;
978b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
979b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	mm->context.flush_mm = 1;
980b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(mm))
981b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_get_lock(ptep);
982b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
983b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte = *ptep;
984b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (!mm_exclusive(mm))
985b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		__ptep_ipte(address, ptep);
986b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return pte;
987b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
988b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
989b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline void ptep_modify_prot_commit(struct mm_struct *mm,
990b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky					   unsigned long address,
991b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky					   pte_t *ptep, pte_t pte)
992b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
993b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	*ptep = pte;
994b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(mm))
995b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_set_unlock(ptep, *(pgste_t *)(ptep + PTRS_PER_PTE));
996b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
997ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky
998ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
999f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefskystatic inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
1000f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky				     unsigned long address, pte_t *ptep)
1001f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky{
1002b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_t pgste;
1003b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_t pte;
1004b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1005b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(vma->vm_mm))
1006b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_get_lock(ptep);
1007b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1008b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte = *ptep;
1009b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	__ptep_ipte(address, ptep);
1010b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
1011b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1012b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(vma->vm_mm)) {
1013b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_update_all(&pte, pgste);
1014b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_set_unlock(ptep, pgste);
1015b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	}
10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pte;
10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1019ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky/*
1020ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * The batched pte unmap code uses ptep_get_and_clear_full to clear the
1021ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * ptes. Here an optimization is possible. tlb_gather_mmu flushes all
1022ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * tlbs of an mm if it can guarantee that the ptes of the mm_struct
1023ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * cannot be accessed while the batched unmap is running. In this case
1024ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * full==1 and a simple pte_clear is enough. See tlb.h.
1025ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky */
1026ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
1027ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefskystatic inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
1028b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky					    unsigned long address,
1029ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky					    pte_t *ptep, int full)
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1031b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_t pgste;
1032b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_t pte;
1033b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1034b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(mm))
1035b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_get_lock(ptep);
1036ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky
1037b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte = *ptep;
1038b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (!full)
1039b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		__ptep_ipte(address, ptep);
1040b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
1041b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1042b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(mm)) {
1043b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_update_all(&pte, pgste);
1044b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_set_unlock(ptep, pgste);
1045b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	}
1046ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky	return pte;
10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1049ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_SET_WRPROTECT
1050b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline pte_t ptep_set_wrprotect(struct mm_struct *mm,
1051b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky				       unsigned long address, pte_t *ptep)
1052b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
1053b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_t pgste;
1054b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pte_t pte = *ptep;
1055b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1056b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (pte_write(pte)) {
1057b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		mm->context.flush_mm = 1;
1058b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		if (mm_has_pgste(mm))
1059b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky			pgste = pgste_get_lock(ptep);
1060b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1061b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		if (!mm_exclusive(mm))
1062b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky			__ptep_ipte(address, ptep);
1063b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		*ptep = pte_wrprotect(pte);
1064b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1065b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		if (mm_has_pgste(mm))
1066b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky			pgste_set_unlock(ptep, pgste);
1067b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	}
1068b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return pte;
1069b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
1070ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky
1071ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
1072b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefskystatic inline int ptep_set_access_flags(struct vm_area_struct *vma,
1073b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky					unsigned long address, pte_t *ptep,
1074b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky					pte_t entry, int dirty)
1075b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky{
1076b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	pgste_t pgste;
1077b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1078b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (pte_same(*ptep, entry))
1079b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		return 0;
1080b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(vma->vm_mm))
1081b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste = pgste_get_lock(ptep);
1082b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1083b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	__ptep_ipte(address, ptep);
1084b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	*ptep = entry;
1085b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky
1086b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	if (mm_has_pgste(vma->vm_mm))
1087b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky		pgste_set_unlock(ptep, pgste);
1088b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky	return 1;
1089b2fa47e6bf5148aa6dbf22ec79f18141b421eebaMartin Schwidefsky}
10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Conversion functions: convert a page and protection to a page entry,
10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and a page entry and page directory to the page they refer to.
10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pte_t __pte;
10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pte_val(__pte) = physpage + pgprot_val(pgprot);
10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return __pte;
11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11022dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstensstatic inline pte_t mk_pte(struct page *page, pgprot_t pgprot)
11032dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens{
11040b2b6e1ddce4696cb7afcbb15a654fe95428a498Heiko Carstens	unsigned long physpage = page_to_phys(page);
11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11062dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens	return mk_pte_phys(physpage, pgprot);
11072dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens}
11082dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens
1109190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
1110190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
1111190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
1112190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1114190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
1115190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pgd_offset_k(address) pgd_offset(&init_mm, address)
11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1117f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifndef CONFIG_64BIT
11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1119190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
1120190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_deref(pmd) ({ BUG(); 0UL; })
1121190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pgd_deref(pmd) ({ BUG(); 0UL; })
112246a82b2d5591335277ed2930611f6acb4ce654edDave McCracken
1123190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_offset(pgd, address) ((pud_t *) pgd)
1124190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address))
11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1126f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#else /* CONFIG_64BIT */
11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1128190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
1129190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN)
11305a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define pgd_deref(pgd) (pgd_val(pgd) & _REGION_ENTRY_ORIGIN)
11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11325a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
11335a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{
11346252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	pud_t *pud = (pud_t *) pgd;
11356252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2)
11366252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		pud = (pud_t *) pgd_deref(*pgd);
11375a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky	return pud  + pud_index(address);
11385a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky}
11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1140190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11426252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	pmd_t *pmd = (pmd_t *) pud;
11436252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky	if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
11446252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky		pmd = (pmd_t *) pud_deref(*pud);
1145190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky	return pmd + pmd_index(address);
11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1148f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#endif /* CONFIG_64BIT */
11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1150190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot))
1151190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
1152190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_page(x) pfn_to_page(pte_pfn(x))
11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1154190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1156190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky/* Find an entry in the lowest level page table.. */
1157190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr))
1158190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_offset_kernel(pmd, address) pte_offset(pmd,address)
11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pte_unmap(pte) do { } while (0)
11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31 bit swap entry format:
11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A page-table entry has some bits we have to treat in a special way.
11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bits 0, 20 and bit 23 have to be zero, otherwise an specification
11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * exception will occur instead of a page translation exception. The
11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * specifiation exception has the bad habit not to store necessary
11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * information in the lowcore.
11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 21 and bit 22 are the page invalid bit and the page protection
11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit. We set both to indicate a swapped page.
11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 30 and 31 are used to distinguish the different page types. For
11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a swapped page these bits need to be zero.
11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This leaves the bits 1-19 and bits 24-29 to store type and offset.
11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We use the 5 bits from 25-29 for the type and the 20 bits from 1-19
11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * plus 24 for the offset.
11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0|     offset        |0110|o|type |00|
11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 0000000001111111111 2222 2 22222 33
11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 1234567890123456789 0123 4 56789 01
11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 64 bit swap entry format:
11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A page-table entry has some bits we have to treat in a special way.
11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bits 52 and bit 55 have to be zero, otherwise an specification
11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * exception will occur instead of a page translation exception. The
11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * specifiation exception has the bad habit not to store necessary
11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * information in the lowcore.
11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 53 and bit 54 are the page invalid bit and the page protection
11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit. We set both to indicate a swapped page.
11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 62 and 63 are used to distinguish the different page types. For
11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a swapped page these bits need to be zero.
11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This leaves the bits 0-51 and bits 56-61 to store type and offset.
11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We use the 5 bits from 57-61 for the type and the 53 bits from 0-51
11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * plus 56 for the offset.
11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * |                      offset                        |0110|o|type |00|
11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  0000000000111111111122222222223333333333444444444455 5555 5 55566 66
11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  0123456789012345678901234567890123456789012345678901 2345 6 78901 23
11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1197f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifndef CONFIG_64BIT
11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __SWP_OFFSET_MASK (~0UL >> 12)
11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __SWP_OFFSET_MASK (~0UL >> 11)
12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
12024448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pte_t pte;
12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	offset &= __SWP_OFFSET_MASK;
12069282ed929758b82f448a40d3c17319d794970624Gerald Schaefer	pte_val(pte) = _PAGE_TYPE_SWAP | ((type & 0x1f) << 2) |
12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		((offset & 1UL) << 7) | ((offset & ~1UL) << 11);
12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pte;
12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __swp_type(entry)	(((entry).val >> 2) & 0x1f)
12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __swp_offset(entry)	(((entry).val >> 11) | (((entry).val >> 7) & 1))
12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __swp_entry(type,offset) ((swp_entry_t) { pte_val(mk_swap_pte((type),(offset))) })
12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1218f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#ifndef CONFIG_64BIT
12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define PTE_FILE_MAX_BITS	26
1220f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#else /* CONFIG_64BIT */
12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define PTE_FILE_MAX_BITS	59
1222f4815ac6c935b8e441fe12504d62e0e8ff7f7ce5Heiko Carstens#endif /* CONFIG_64BIT */
12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pte_to_pgoff(__pte) \
12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f))
12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pgoff_to_pte(__off) \
12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \
12299282ed929758b82f448a40d3c17319d794970624Gerald Schaefer		   | _PAGE_TYPE_FILE })
12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* !__ASSEMBLY__ */
12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define kern_addr_valid(addr)   (1)
12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
123517f345808563d2f425b2b15d60c4a5b00112e9ebHeiko Carstensextern int vmem_add_mapping(unsigned long start, unsigned long size);
123617f345808563d2f425b2b15d60c4a5b00112e9ebHeiko Carstensextern int vmem_remove_mapping(unsigned long start, unsigned long size);
1237402b08622d9ac6e32e25289573272e0f21bb58a7Carsten Otteextern int s390_enable_sie(void);
1238f4eb07c17df2e6cf9bd58bfcd9cc9e05e9489d07Heiko Carstens
12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * No page table caches to initialise
12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pgtable_cache_init()	do { } while (0)
12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm-generic/pgtable.h>
12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* _S390_PAGE_H */
1247