pgtable.h revision 043d07084b5347a26eab0a07aa13a4a929ad9e71
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * include/asm-s390/pgtable.h 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * S390 version 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author(s): Hartmut Penner (hp@de.ibm.com) 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Ulrich Weigand (weigand@de.ibm.com) 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Martin Schwidefsky (schwidefsky@de.ibm.com) 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Derived from "include/asm-i386/pgtable.h" 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _ASM_S390_PGTABLE_H 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _ASM_S390_PGTABLE_H 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The Linux memory management assumes a three-level page table setup. For 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * s390 31 bit we "fold" the mid level into the top-level page table, so 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that we physically have the same two-level page table as the s390 mmu 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * expects in 31 bit mode. For s390 64 bit we use three of the five levels 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the hardware provides (region first and region second tables are not 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * used). 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The "pgd_xxx()" functions are trivial for a folded two-level 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * setup: the pgd is never bad, and a pmd always exists (as it's folded 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * into the pgd entry) 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file contains the functions and defines necessary to modify and use 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the S390 page table tree. 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __ASSEMBLY__ 329789db08c020193ae18826c3aa48bd24296f7848Heiko Carstens#include <linux/sched.h> 332dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens#include <linux/mm_types.h> 345b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#include <asm/bitops.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/bug.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/processor.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096))); 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void paging_init(void); 402b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstensextern void vmem_map_init(void); 4192f842eac7ee321c8a0749aba2513541b4ac226fMartin Schwidefskyextern void fault_init(void); 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The S390 doesn't have any external MMU info: the kernel page 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * tables contain all the necessary information. 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 474b3073e1c53a256275f1079c0fbfbe85883d9275Russell King#define update_mmu_cache(vma, address, ptep) do { } while (0) 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 50238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky * ZERO_PAGE is a global shared page that is always zero; used 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for zero-mapped memory areas etc.. 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 53238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky 54238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefskyextern unsigned long empty_zero_page; 55238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefskyextern unsigned long zero_page_mask; 56238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky 57238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky#define ZERO_PAGE(vaddr) \ 58238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky (virt_to_page((void *)(empty_zero_page + \ 59238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky (((unsigned long)(vaddr)) &zero_page_mask)))) 60238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky 61238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky#define is_zero_pfn is_zero_pfn 62238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefskystatic inline int is_zero_pfn(unsigned long pfn) 63238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky{ 64238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky extern unsigned long zero_pfn; 65238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky unsigned long offset_from_zero_pfn = pfn - zero_pfn; 66238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT); 67238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky} 68238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky 69238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky#define my_zero_pfn(addr) page_to_pfn(ZERO_PAGE(addr)) 70238ec4efeee4461d5cff2ed3e5a15a3ab850959bMartin Schwidefsky 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* !__ASSEMBLY__ */ 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PMD_SHIFT determines the size of the area a second-level page 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * table can map 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PGDIR_SHIFT determines what a third-level page table entry can map 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __s390x__ 79146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky# define PMD_SHIFT 20 80146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky# define PUD_SHIFT 20 81146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky# define PGDIR_SHIFT 20 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* __s390x__ */ 83146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky# define PMD_SHIFT 20 84190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky# define PUD_SHIFT 31 855a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky# define PGDIR_SHIFT 42 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __s390x__ */ 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PMD_SIZE (1UL << PMD_SHIFT) 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PMD_MASK (~(PMD_SIZE-1)) 90190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define PUD_SIZE (1UL << PUD_SHIFT) 91190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define PUD_MASK (~(PUD_SIZE-1)) 925a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define PGDIR_SIZE (1UL << PGDIR_SHIFT) 935a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define PGDIR_MASK (~(PGDIR_SIZE-1)) 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * entries per page directory level: the S390 is two-level, so 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we don't really have any PMD directory physically. 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for S390 segment-table entries are combined to one PGD 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that leads to 1024 pte per pgd 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 101146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky#define PTRS_PER_PTE 256 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __s390x__ 103146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky#define PTRS_PER_PMD 1 1045a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define PTRS_PER_PUD 1 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* __s390x__ */ 106146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky#define PTRS_PER_PMD 2048 1075a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define PTRS_PER_PUD 2048 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __s390x__ */ 109146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky#define PTRS_PER_PGD 2048 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111d455a3696c72283923e6870e9e4fe1daa861d7cdHugh Dickins#define FIRST_USER_ADDRESS 0 112d455a3696c72283923e6870e9e4fe1daa861d7cdHugh Dickins 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pte_ERROR(e) \ 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e)) 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pmd_ERROR(e) \ 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e)) 117190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_ERROR(e) \ 118190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e)) 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pgd_ERROR(e) \ 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e)) 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __ASSEMBLY__ 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1245fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * The vmalloc area will always be on the topmost area of the kernel 1257d3f661e5757e84f1fb2e10093cfa2f7b057bc2fMartin Schwidefsky * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc, 1265fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * which should be enough for any sane case. 1275fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * By putting vmalloc at the top, we maximise the gap between physical 1285fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * memory and vmalloc to catch misplaced memory accesses. As a side 1295fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * effect, this also makes sure that 64 bit module code cannot be used 1305fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger * as system call address. 1318b62bc9642300471737bc3b77b2a4a2ead46dedbHeiko Carstens */ 132239a64255fae8933d95273b5b92545949ca4e743Heiko Carstens 133239a64255fae8933d95273b5b92545949ca4e743Heiko Carstensextern unsigned long VMALLOC_START; 134239a64255fae8933d95273b5b92545949ca4e743Heiko Carstens 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __s390x__ 136239a64255fae8933d95273b5b92545949ca4e743Heiko Carstens#define VMALLOC_SIZE (96UL << 20) 1375fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger#define VMALLOC_END 0x7e000000UL 1380189103c69f47712a0c542a8bc28ff46ebe53a8aHeiko Carstens#define VMEM_MAP_END 0x80000000UL 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* __s390x__ */ 1407d3f661e5757e84f1fb2e10093cfa2f7b057bc2fMartin Schwidefsky#define VMALLOC_SIZE (128UL << 30) 1417d3f661e5757e84f1fb2e10093cfa2f7b057bc2fMartin Schwidefsky#define VMALLOC_END 0x3e000000000UL 1420189103c69f47712a0c542a8bc28ff46ebe53a8aHeiko Carstens#define VMEM_MAP_END 0x40000000000UL 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __s390x__ */ 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1450189103c69f47712a0c542a8bc28ff46ebe53a8aHeiko Carstens/* 1460189103c69f47712a0c542a8bc28ff46ebe53a8aHeiko Carstens * VMEM_MAX_PHYS is the highest physical address that can be added to the 1:1 1470189103c69f47712a0c542a8bc28ff46ebe53a8aHeiko Carstens * mapping. This needs to be calculated at compile time since the size of the 1480189103c69f47712a0c542a8bc28ff46ebe53a8aHeiko Carstens * VMEM_MAP is static but the size of struct page can change. 1490189103c69f47712a0c542a8bc28ff46ebe53a8aHeiko Carstens */ 150522d8dc08b16deb51c128d544ab1cb9c621c950eMartin Schwidefsky#define VMEM_MAX_PAGES ((VMEM_MAP_END - VMALLOC_END) / sizeof(struct page)) 151522d8dc08b16deb51c128d544ab1cb9c621c950eMartin Schwidefsky#define VMEM_MAX_PFN min(VMALLOC_START >> PAGE_SHIFT, VMEM_MAX_PAGES) 152522d8dc08b16deb51c128d544ab1cb9c621c950eMartin Schwidefsky#define VMEM_MAX_PHYS ((VMEM_MAX_PFN << PAGE_SHIFT) & ~((16 << 20) - 1)) 15317f345808563d2f425b2b15d60c4a5b00112e9ebHeiko Carstens#define vmemmap ((struct page *) VMALLOC_END) 1545fd9c6e214547a32d3da6ee4284c79004d667bc8Christian Borntraeger 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 31 bit pagetable entry of S390 has following format: 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | PFRA | | OS | 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 0IP0 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 00000000001111111111222222222233 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 01234567890123456789012345678901 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Page-Invalid Bit: Page is not available for address-translation 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Page-Protection Bit: Store access not possible for page 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 31 bit segmenttable entry of S390 has following format: 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | P-table origin | |PTL 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 IC 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 00000000001111111111222222222233 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 01234567890123456789012345678901 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Segment-Invalid Bit: Segment is not available for address-translation 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * C Common-Segment Bit: Segment is not private (PoP 3-30) 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PTL Page-Table-Length: Page-table length (PTL+1*16 entries -> up to 256) 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The 31 bit segmenttable origin of S390 has following format: 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * |S-table origin | | STL | 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * X **GPS 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 00000000001111111111222222222233 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 01234567890123456789012345678901 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * X Space-Switch event: 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * G Segment-Invalid Bit: * 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Private-Space Bit: Segment is not private (PoP 3-30) 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * S Storage-Alteration: 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STL Segment-Table-Length: Segment-table length (STL+1*16 entries -> up to 2048) 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 64 bit pagetable entry of S390 has following format: 1896a985c6194017de2c062916ad1cd00dee0302c40Christian Borntraeger * | PFRA |0IPC| OS | 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0000000000111111111122222222223333333333444444444455555555556666 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0123456789012345678901234567890123456789012345678901234567890123 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Page-Invalid Bit: Page is not available for address-translation 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Page-Protection Bit: Store access not possible for page 1956a985c6194017de2c062916ad1cd00dee0302c40Christian Borntraeger * C Change-bit override: HW is not required to set change bit 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 64 bit segmenttable entry of S390 has following format: 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | P-table origin | TT 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0000000000111111111122222222223333333333444444444455555555556666 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0123456789012345678901234567890123456789012345678901234567890123 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Segment-Invalid Bit: Segment is not available for address-translation 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * C Common-Segment Bit: Segment is not private (PoP 3-30) 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Page-Protection Bit: Store access not possible for page 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TT Type 00 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A 64 bit region table entry of S390 has following format: 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | S-table origin | TF TTTL 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0000000000111111111122222222223333333333444444444455555555556666 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0123456789012345678901234567890123456789012345678901234567890123 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I Segment-Invalid Bit: Segment is not available for address-translation 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TT Type 01 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TF 215190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky * TL Table length 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The 64 bit regiontable origin of S390 has following format: 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | region table origon | DTTL 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0000000000111111111122222222223333333333444444444455555555556666 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0123456789012345678901234567890123456789012345678901234567890123 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * X Space-Switch event: 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * G Segment-Invalid Bit: 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * P Private-Space Bit: 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * S Storage-Alteration: 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * R Real space 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TL Table-Length: 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A storage key has the following format: 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | ACC |F|R|C|0| 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 3 4 5 6 7 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ACC: access key 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * F : fetch protection bit 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * R : referenced bit 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * C : changed bit 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Hardware bits in the page table entry */ 2396a985c6194017de2c062916ad1cd00dee0302c40Christian Borntraeger#define _PAGE_CO 0x100 /* HW Change-bit override */ 240833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_RO 0x200 /* HW read-only bit */ 241833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_INVALID 0x400 /* HW invalid bit */ 2423610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky 2433610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Software bits in the page table entry */ 244833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_SWT 0x001 /* SW pte type bit t */ 245833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_SWX 0x002 /* SW pte type bit x */ 246a08cb629f546d1cecebe955392197f226e58dbe1Nick Piggin#define _PAGE_SPECIAL 0x004 /* SW associated with special page */ 247a08cb629f546d1cecebe955392197f226e58dbe1Nick Piggin#define __HAVE_ARCH_PTE_SPECIAL 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 249138c9021ca68d6f8a6fac3418995fee102a3cc22Nick Piggin/* Set of bits not changed in pte_modify */ 250138c9021ca68d6f8a6fac3418995fee102a3cc22Nick Piggin#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_SPECIAL) 251138c9021ca68d6f8a6fac3418995fee102a3cc22Nick Piggin 252833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky/* Six different types of pages. */ 2539282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define _PAGE_TYPE_EMPTY 0x400 2549282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define _PAGE_TYPE_NONE 0x401 255833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_TYPE_SWAP 0x403 256833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky#define _PAGE_TYPE_FILE 0x601 /* bit 0x002 is used for offset !! */ 2579282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define _PAGE_TYPE_RO 0x200 2589282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define _PAGE_TYPE_RW 0x000 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 260833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky/* 26153492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer * Only four types for huge pages, using the invalid bit and protection bit 26253492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer * of a segment table entry. 26353492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer */ 26453492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _HPAGE_TYPE_EMPTY 0x020 /* _SEGMENT_ENTRY_INV */ 26553492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _HPAGE_TYPE_NONE 0x220 26653492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _HPAGE_TYPE_RO 0x200 /* _SEGMENT_ENTRY_RO */ 26753492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _HPAGE_TYPE_RW 0x000 26853492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer 26953492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer/* 270833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * PTE type bits are rather complicated. handle_pte_fault uses pte_present, 271833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * pte_none and pte_file to find out the pte type WITHOUT holding the page 272833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * table lock. ptep_clear_flush on the other hand uses ptep_clear_flush to 273833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * invalidate a given pte. ipte sets the hw invalid bit and clears all tlbs 274833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * for the page. The page table entry is set to _PAGE_TYPE_EMPTY afterwards. 275833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * This change is done while holding the lock, but the intermediate step 276833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * of a previously valid pte with the hw invalid bit set can be observed by 277833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * handle_pte_fault. That makes it necessary that all valid pte types with 278833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * the hw invalid bit set must be distinguishable from the four pte types 279833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * empty, none, swap and file. 280833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * 281833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * irxt ipte irxt 282833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_EMPTY 1000 -> 1000 283833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_NONE 1001 -> 1001 284833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_SWAP 1011 -> 1011 285833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_FILE 11?1 -> 11?1 286833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_RO 0100 -> 1100 287833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * _PAGE_TYPE_RW 0000 -> 1000 288833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * 289c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaefer * pte_none is true for bits combinations 1000, 1010, 1100, 1110 290833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * pte_present is true for bits combinations 0000, 0010, 0100, 0110, 1001 291833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky * pte_file is true for bits combinations 1101, 1111 292c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaefer * swap pte is 1011 and 0001, 0011, 0101, 0111 are invalid. 293833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky */ 294833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky 2955b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger/* Page status table bits for virtualization */ 2965b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#define RCP_PCL_BIT 55 2975b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#define RCP_HR_BIT 54 2985b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#define RCP_HC_BIT 53 2995b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#define RCP_GR_BIT 50 3005b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#define RCP_GC_BIT 49 3015b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger 30215e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke/* User dirty bit for KVM's migration feature */ 30315e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke#define KVM_UD_BIT 47 30415e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __s390x__ 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3073610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Bits in the segment table address-space-control-element */ 3083610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_SPACE_SWITCH 0x80000000UL /* space switch event */ 3093610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_ORIGIN_MASK 0x7ffff000UL /* segment table origin */ 3103610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_PRIVATE_SPACE 0x100 /* private space control */ 3113610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */ 3123610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TABLE_LENGTH 0x7f /* 128 x 64 entries = 8k */ 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3143610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Bits in the segment table entry */ 3153610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */ 31680217147a3d80c8a4e48f06e2f6e965455f3fe2aMartin Schwidefsky#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ 3173610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ 3183610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */ 3193610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_PTL 0x0f /* page table length */ 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3213610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY (_SEGMENT_ENTRY_PTL) 3223610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INV) 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* __s390x__ */ 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3263610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Bits in the segment/region table address-space-control-element */ 3273610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_ORIGIN ~0xfffUL/* segment table origin */ 3283610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_PRIVATE_SPACE 0x100 /* private space control */ 3293610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */ 3303610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_SPACE_SWITCH 0x40 /* space switch event */ 3313610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_REAL_SPACE 0x20 /* real space control */ 3323610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_MASK 0x0c /* asce table type mask */ 3333610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_REGION1 0x0c /* region first table type */ 3343610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_REGION2 0x08 /* region second table type */ 3353610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_REGION3 0x04 /* region third table type */ 3363610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TYPE_SEGMENT 0x00 /* segment table type */ 3373610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_TABLE_LENGTH 0x03 /* region table length */ 3383610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky 3393610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Bits in the region table entry */ 3403610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_ORIGIN ~0xfffUL/* region/segment table origin */ 3413610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_INV 0x20 /* invalid region table entry */ 3423610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ 3433610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ 3443610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */ 3453610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_TYPE_R3 0x04 /* region third table type */ 3463610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION_ENTRY_LENGTH 0x03 /* region third length */ 3473610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky 3483610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION1_ENTRY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_LENGTH) 3493610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION1_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INV) 3503610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION2_ENTRY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH) 3513610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION2_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INV) 3523610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH) 3533610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV) 3543610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Bits in the segment table entry */ 3563610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ 3573610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ 3583610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3603610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY (0) 3613610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INV) 3623610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky 36353492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _SEGMENT_ENTRY_LARGE 0x400 /* STE-format control, large page */ 36453492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer#define _SEGMENT_ENTRY_CO 0x100 /* change-recording override */ 36553492b1de46a7576170e865062ffcfc93bb5650bGerald Schaefer 3663610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#endif /* __s390x__ */ 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3693610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky * A user page table pointer has the space-switch-event bit, the 3703610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky * private-space-control bit and the storage-alteration-event-control 3713610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky * bit set. A kernel page table pointer doesn't need them. 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3733610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#define _ASCE_USER_BITS (_ASCE_SPACE_SWITCH | _ASCE_PRIVATE_SPACE | \ 3743610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky _ASCE_ALT_EVENT) 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3763610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky/* Bits int the storage key */ 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _PAGE_CHANGED 0x02 /* HW changed bit */ 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _PAGE_REFERENCED 0x04 /* HW referenced bit */ 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3819282ed929758b82f448a40d3c17319d794970624Gerald Schaefer * Page protection definitions. 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3839282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_NONE __pgprot(_PAGE_TYPE_NONE) 3849282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_RO __pgprot(_PAGE_TYPE_RO) 3859282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_RW __pgprot(_PAGE_TYPE_RW) 3869282ed929758b82f448a40d3c17319d794970624Gerald Schaefer 3879282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_KERNEL PAGE_RW 3889282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define PAGE_COPY PAGE_RO 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 391043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky * On s390 the page table entry has an invalid bit and a read-only bit. 392043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky * Read permission implies execute permission and write permission 393043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky * implies read permission. 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /*xwr*/ 3969282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __P000 PAGE_NONE 3979282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __P001 PAGE_RO 3989282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __P010 PAGE_RO 3999282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __P011 PAGE_RO 400043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __P100 PAGE_RO 401043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __P101 PAGE_RO 402043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __P110 PAGE_RO 403043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __P111 PAGE_RO 4049282ed929758b82f448a40d3c17319d794970624Gerald Schaefer 4059282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __S000 PAGE_NONE 4069282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __S001 PAGE_RO 4079282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __S010 PAGE_RW 4089282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#define __S011 PAGE_RW 409043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __S100 PAGE_RO 410043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __S101 PAGE_RO 411043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __S110 PAGE_RW 412043d07084b5347a26eab0a07aa13a4a929ad9e71Martin Schwidefsky#define __S111 PAGE_RW 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Certain architectures need to do special things when PTEs 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * within a page table are directly modified. Thus, the following 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hook is made available. 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 419ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefskystatic inline void set_pte_at(struct mm_struct *mm, unsigned long addr, 420146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky pte_t *ptep, pte_t entry) 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 422146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky *ptep = entry; 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pgd/pmd/pte query functions 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __s390x__ 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4304448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pgd_present(pgd_t pgd) { return 1; } 4314448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pgd_none(pgd_t pgd) { return 0; } 4324448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pgd_bad(pgd_t pgd) { return 0; } 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 434190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_present(pud_t pud) { return 1; } 435190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_none(pud_t pud) { return 0; } 436190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_bad(pud_t pud) { return 0; } 437190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* __s390x__ */ 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4405a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline int pgd_present(pgd_t pgd) 4415a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{ 4426252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) 4436252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky return 1; 4445a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky return (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) != 0UL; 4455a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky} 4465a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky 4475a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline int pgd_none(pgd_t pgd) 4485a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{ 4496252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) 4506252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky return 0; 4515a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky return (pgd_val(pgd) & _REGION_ENTRY_INV) != 0UL; 4525a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky} 4535a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky 4545a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline int pgd_bad(pgd_t pgd) 4555a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{ 4566252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky /* 4576252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky * With dynamic page table levels the pgd can be a region table 4586252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky * entry or a segment table entry. Check for the bit that are 4596252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky * invalid for either table entry. 4606252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky */ 4615a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky unsigned long mask = 4626252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV & 4635a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; 4645a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky return (pgd_val(pgd) & mask) != 0; 4655a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky} 466190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky 467190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_present(pud_t pud) 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4696252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) 4706252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky return 1; 4710d01792300c4d7425eabac9095c603cdb411d2a5Martin Schwidefsky return (pud_val(pud) & _REGION_ENTRY_ORIGIN) != 0UL; 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 474190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_none(pud_t pud) 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4766252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) 4776252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky return 0; 4780d01792300c4d7425eabac9095c603cdb411d2a5Martin Schwidefsky return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline int pud_bad(pud_t pud) 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4836252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky /* 4846252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky * With dynamic page table levels the pud can be a region table 4856252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky * entry or a segment table entry. Check for the bit that are 4866252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky * invalid for either table entry. 4876252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky */ 4885a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky unsigned long mask = 4896252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV & 4905a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; 4915a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky return (pud_val(pud) & mask) != 0; 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4943610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky#endif /* __s390x__ */ 4953610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky 4964448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pmd_present(pmd_t pmd) 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4980d01792300c4d7425eabac9095c603cdb411d2a5Martin Schwidefsky return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5014448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pmd_none(pmd_t pmd) 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5030d01792300c4d7425eabac9095c603cdb411d2a5Martin Schwidefsky return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5064448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pmd_bad(pmd_t pmd) 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5083610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky unsigned long mask = ~_SEGMENT_ENTRY_ORIGIN & ~_SEGMENT_ENTRY_INV; 5093610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky return (pmd_val(pmd) & mask) != _SEGMENT_ENTRY; 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5124448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_none(pte_t pte) 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 514833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT); 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5174448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_present(pte_t pte) 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 519833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT | _PAGE_SWX; 520833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky return (pte_val(pte) & mask) == _PAGE_TYPE_NONE || 521833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky (!(pte_val(pte) & _PAGE_INVALID) && 522833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky !(pte_val(pte) & _PAGE_SWT)); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5254448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_file(pte_t pte) 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 527833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT; 528833774849d50a59f58e9bdfc3d9c88e682b3596dMartin Schwidefsky return (pte_val(pte) & mask) == _PAGE_TYPE_FILE; 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5317e675137a8e1a4d45822746456dd389b65745bf6Nick Pigginstatic inline int pte_special(pte_t pte) 5327e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin{ 533a08cb629f546d1cecebe955392197f226e58dbe1Nick Piggin return (pte_val(pte) & _PAGE_SPECIAL); 5347e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin} 5357e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin 536ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTE_SAME 537ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define pte_same(a,b) (pte_val(a) == pte_val(b)) 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5395b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraegerstatic inline void rcp_lock(pte_t *ptep) 5405b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger{ 5415b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#ifdef CONFIG_PGSTE 5425b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); 5435b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger preempt_disable(); 5445b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger while (test_and_set_bit(RCP_PCL_BIT, pgste)) 5455b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger ; 5465b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#endif 5475b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger} 5485b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger 5495b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraegerstatic inline void rcp_unlock(pte_t *ptep) 5505b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger{ 5515b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#ifdef CONFIG_PGSTE 5525b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); 5535b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger clear_bit(RCP_PCL_BIT, pgste); 5545b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger preempt_enable(); 5555b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#endif 5565b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger} 5575b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger 5585b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger/* forward declaration for SetPageUptodate in page-flags.h*/ 559e2b8d7af0e3a9234de06606f9151f28cf847a8d6Martin Schwidefskystatic inline void page_clear_dirty(struct page *page, int mapped); 5605b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#include <linux/page-flags.h> 5615b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger 5625b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraegerstatic inline void ptep_rcp_copy(pte_t *ptep) 5635b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger{ 5645b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#ifdef CONFIG_PGSTE 5655b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger struct page *page = virt_to_page(pte_val(*ptep)); 5665b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger unsigned int skey; 5675b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); 5685b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger 5695b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger skey = page_get_storage_key(page_to_phys(page)); 57015e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke if (skey & _PAGE_CHANGED) { 571c71799c1f404c6e4f34fa64e6be39cd6149e5019Heiko Carstens set_bit_simple(RCP_GC_BIT, pgste); 57215e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke set_bit_simple(KVM_UD_BIT, pgste); 57315e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke } 5745b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger if (skey & _PAGE_REFERENCED) 575c71799c1f404c6e4f34fa64e6be39cd6149e5019Heiko Carstens set_bit_simple(RCP_GR_BIT, pgste); 57615e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) { 5775b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger SetPageDirty(page); 57815e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke set_bit_simple(KVM_UD_BIT, pgste); 57915e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke } 580c71799c1f404c6e4f34fa64e6be39cd6149e5019Heiko Carstens if (test_and_clear_bit_simple(RCP_HR_BIT, pgste)) 5815b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger SetPageReferenced(page); 5825b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#endif 5835b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger} 5845b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * query functions pte_write/pte_dirty/pte_young only work if 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pte_present() is true. Undefined behaviour if not.. 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5894448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_write(pte_t pte) 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (pte_val(pte) & _PAGE_RO) == 0; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5944448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_dirty(pte_t pte) 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* A pte is neither clean nor dirty on s/390. The dirty bit 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is in the storage key. See page_test_and_clear_dirty for 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * details. 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6034448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int pte_young(pte_t pte) 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* A pte is neither young nor old on s/390. The young bit 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is in the storage key. See page_test_and_clear_young for 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * details. 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pgd/pmd/pte modification functions 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __s390x__ 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 618190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pgd_clear(pgd) do { } while (0) 619190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_clear(pud) do { } while (0) 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* __s390x__ */ 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6235a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline void pgd_clear_kernel(pgd_t * pgd) 6245a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{ 6256252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) 6266252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky pgd_val(*pgd) = _REGION2_ENTRY_EMPTY; 6275a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky} 6285a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky 6295a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline void pgd_clear(pgd_t * pgd) 6305a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{ 6315a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky pgd_clear_kernel(pgd); 6325a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky} 633190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky 634190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline void pud_clear_kernel(pud_t *pud) 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6366252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) 6376252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky pud_val(*pud) = _REGION3_ENTRY_EMPTY; 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6406252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefskystatic inline void pud_clear(pud_t *pud) 641c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaefer{ 642190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky pud_clear_kernel(pud); 643c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaefer} 644146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky#endif /* __s390x__ */ 645146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky 646c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaeferstatic inline void pmd_clear_kernel(pmd_t * pmdp) 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6483610cce87af0693603db171d5b6f6735f5e3dc5bMartin Schwidefsky pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY; 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefskystatic inline void pmd_clear(pmd_t *pmd) 652c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaefer{ 653146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky pmd_clear_kernel(pmd); 654c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaefer} 655c1821c2e9711adc3cd298a16b7237c92a2cee78dGerald Schaefer 6564448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6589282ed929758b82f448a40d3c17319d794970624Gerald Schaefer pte_val(*ptep) = _PAGE_TYPE_EMPTY; 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The following pte modification functions only work if 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pte_present() is true. Undefined behaviour if not.. 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6654448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 667138c9021ca68d6f8a6fac3418995fee102a3cc22Nick Piggin pte_val(pte) &= _PAGE_CHG_MASK; 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pte_val(pte) |= pgprot_val(newprot); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pte; 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6724448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_wrprotect(pte_t pte) 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6749282ed929758b82f448a40d3c17319d794970624Gerald Schaefer /* Do not clobber _PAGE_TYPE_NONE pages! */ 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(pte_val(pte) & _PAGE_INVALID)) 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pte_val(pte) |= _PAGE_RO; 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pte; 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6804448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkwrite(pte_t pte) 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pte_val(pte) &= ~_PAGE_RO; 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pte; 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6864448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkclean(pte_t pte) 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The only user of pte_mkclean is the fork() code. 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds We must *not* clear the *physical* page dirty bit 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds just because fork() wants to clear the dirty bit in 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *one* of the page's mappings. So we just do nothing. */ 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pte; 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6954448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkdirty(pte_t pte) 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We do not explicitly set the dirty bit because the 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sske instruction is slow. It is faster to let the 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * next instruction set the dirty bit. 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pte; 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7044448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkold(pte_t pte) 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* S/390 doesn't keep its dirty/referenced bit in the pte. 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * There is no point in clearing the real referenced bit. 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pte; 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7124448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t pte_mkyoung(pte_t pte) 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* S/390 doesn't keep its dirty/referenced bit in the pte. 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * There is no point in setting the real referenced bit. 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pte; 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7207e675137a8e1a4d45822746456dd389b65745bf6Nick Pigginstatic inline pte_t pte_mkspecial(pte_t pte) 7217e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin{ 722a08cb629f546d1cecebe955392197f226e58dbe1Nick Piggin pte_val(pte) |= _PAGE_SPECIAL; 7237e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin return pte; 7247e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin} 7257e675137a8e1a4d45822746456dd389b65745bf6Nick Piggin 72684afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens#ifdef CONFIG_HUGETLB_PAGE 72784afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstensstatic inline pte_t pte_mkhuge(pte_t pte) 72884afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens{ 72984afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens /* 73084afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens * PROT_NONE needs to be remapped from the pte type to the ste type. 73184afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens * The HW invalid bit is also different for pte and ste. The pte 73284afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens * invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE 73384afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens * bit, so we don't have to clear it. 73484afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens */ 73584afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens if (pte_val(pte) & _PAGE_INVALID) { 73684afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens if (pte_val(pte) & _PAGE_SWT) 73784afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens pte_val(pte) |= _HPAGE_TYPE_NONE; 73884afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens pte_val(pte) |= _SEGMENT_ENTRY_INV; 73984afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens } 74084afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens /* 74184afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens * Clear SW pte bits SWT and SWX, there are no SW bits in a segment 74284afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens * table entry. 74384afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens */ 74484afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX); 74584afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens /* 74684afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens * Also set the change-override bit because we don't need dirty bit 74784afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens * tracking for hugetlbfs pages. 74884afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens */ 74984afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO); 75084afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens return pte; 75184afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens} 75284afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens#endif 75384afdcee620b1640f2a145c07febae4ed68947f9Heiko Carstens 75415e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke#ifdef CONFIG_PGSTE 75515e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke/* 75615e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke * Get (and clear) the user dirty bit for a PTE. 75715e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke */ 75815e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funkestatic inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm, 75915e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke pte_t *ptep) 76015e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke{ 76115e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke int dirty; 76215e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke unsigned long *pgste; 76315e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke struct page *page; 76415e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke unsigned int skey; 76515e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke 766250cf776f74b5932a1977d0489cae9206e2351ddChristian Borntraeger if (!mm->context.has_pgste) 76715e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke return -EINVAL; 76815e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke rcp_lock(ptep); 76915e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke pgste = (unsigned long *) (ptep + PTRS_PER_PTE); 77015e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke page = virt_to_page(pte_val(*ptep)); 77115e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke skey = page_get_storage_key(page_to_phys(page)); 77215e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke if (skey & _PAGE_CHANGED) { 77315e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke set_bit_simple(RCP_GC_BIT, pgste); 77415e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke set_bit_simple(KVM_UD_BIT, pgste); 77515e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke } 77615e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) { 77715e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke SetPageDirty(page); 77815e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke set_bit_simple(KVM_UD_BIT, pgste); 77915e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke } 78015e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste); 78115e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke if (skey & _PAGE_CHANGED) 782e2b8d7af0e3a9234de06606f9151f28cf847a8d6Martin Schwidefsky page_clear_dirty(page, 1); 78315e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke rcp_unlock(ptep); 78415e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke return dirty; 78515e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke} 78615e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke#endif 78715e86b0c752d50e910b2cca6e83ce74c4440d06cFlorian Funke 788ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG 789ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefskystatic inline int ptep_test_and_clear_young(struct vm_area_struct *vma, 790ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky unsigned long addr, pte_t *ptep) 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7925b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#ifdef CONFIG_PGSTE 7935b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger unsigned long physpage; 7945b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger int young; 7955b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger unsigned long *pgste; 7965b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger 797250cf776f74b5932a1977d0489cae9206e2351ddChristian Borntraeger if (!vma->vm_mm->context.has_pgste) 7985b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger return 0; 7995b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger physpage = pte_val(*ptep) & PAGE_MASK; 8005b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger pgste = (unsigned long *) (ptep + PTRS_PER_PTE); 8015b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger 8025b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger young = ((page_get_storage_key(physpage) & _PAGE_REFERENCED) != 0); 8035b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger rcp_lock(ptep); 8045b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger if (young) 805c71799c1f404c6e4f34fa64e6be39cd6149e5019Heiko Carstens set_bit_simple(RCP_GR_BIT, pgste); 806c71799c1f404c6e4f34fa64e6be39cd6149e5019Heiko Carstens young |= test_and_clear_bit_simple(RCP_HR_BIT, pgste); 8075b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger rcp_unlock(ptep); 8085b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger return young; 8095b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#endif 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 813ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH 814ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefskystatic inline int ptep_clear_flush_young(struct vm_area_struct *vma, 815ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky unsigned long address, pte_t *ptep) 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8175b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger /* No need to flush TLB 8185b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger * On s390 reference bits are in storage key and never in TLB 8195b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger * With virtualization we handle the reference bit, without we 8205b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger * we can simply return */ 8215b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#ifdef CONFIG_PGSTE 8225b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger return ptep_test_and_clear_young(vma, address, ptep); 8235b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger#endif 824ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky return 0; 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8279282ed929758b82f448a40d3c17319d794970624Gerald Schaeferstatic inline void __ptep_ipte(unsigned long address, pte_t *ptep) 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8299282ed929758b82f448a40d3c17319d794970624Gerald Schaefer if (!(pte_val(*ptep) & _PAGE_INVALID)) { 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __s390x__ 831146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky /* pto must point to the start of the segment table */ 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); 8339282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#else 8349282ed929758b82f448a40d3c17319d794970624Gerald Schaefer /* ipte in zarch mode can do the math */ 8359282ed929758b82f448a40d3c17319d794970624Gerald Schaefer pte_t *pto = ptep; 8369282ed929758b82f448a40d3c17319d794970624Gerald Schaefer#endif 83794c12cc7d196bab34aaa98d38521549fa1e5ef76Martin Schwidefsky asm volatile( 83894c12cc7d196bab34aaa98d38521549fa1e5ef76Martin Schwidefsky " ipte %2,%3" 83994c12cc7d196bab34aaa98d38521549fa1e5ef76Martin Schwidefsky : "=m" (*ptep) : "m" (*ptep), 84094c12cc7d196bab34aaa98d38521549fa1e5ef76Martin Schwidefsky "a" (pto), "a" (address)); 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8429282ed929758b82f448a40d3c17319d794970624Gerald Schaefer} 8439282ed929758b82f448a40d3c17319d794970624Gerald Schaefer 844146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefskystatic inline void ptep_invalidate(struct mm_struct *mm, 845146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky unsigned long address, pte_t *ptep) 8469282ed929758b82f448a40d3c17319d794970624Gerald Schaefer{ 847250cf776f74b5932a1977d0489cae9206e2351ddChristian Borntraeger if (mm->context.has_pgste) { 8485b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger rcp_lock(ptep); 8495b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger __ptep_ipte(address, ptep); 8505b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger ptep_rcp_copy(ptep); 8515b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger pte_val(*ptep) = _PAGE_TYPE_EMPTY; 8525b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger rcp_unlock(ptep); 8535b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger return; 8545b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger } 8559282ed929758b82f448a40d3c17319d794970624Gerald Schaefer __ptep_ipte(address, ptep); 8565b7baf05783b1ac97a510243d7e82293416a7cf6Christian Borntraeger pte_val(*ptep) = _PAGE_TYPE_EMPTY; 857f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky} 858f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky 859ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky/* 860ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * This is hard to understand. ptep_get_and_clear and ptep_clear_flush 861ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * both clear the TLB for the unmapped pte. The reason is that 862ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * ptep_get_and_clear is used in common code (e.g. change_pte_range) 863ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * to modify an active pte. The sequence is 864ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * 1) ptep_get_and_clear 865ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * 2) set_pte_at 866ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * 3) flush_tlb_range 867ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * On s390 the tlb needs to get flushed with the modification of the pte 868ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * if the pte is active. The only way how this can be implemented is to 869ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * have ptep_get_and_clear do the tlb flush. In exchange flush_tlb_range 870ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * is a nop. 871ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky */ 872ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_GET_AND_CLEAR 873ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define ptep_get_and_clear(__mm, __address, __ptep) \ 874ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky({ \ 875ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky pte_t __pte = *(__ptep); \ 876050eef364ad700590a605a0749f825cab4834b1eMartin Schwidefsky (__mm)->context.flush_mm = 1; \ 877050eef364ad700590a605a0749f825cab4834b1eMartin Schwidefsky if (atomic_read(&(__mm)->context.attach_count) > 1 || \ 878ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky (__mm) != current->active_mm) \ 879146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky ptep_invalidate(__mm, __address, __ptep); \ 880ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky else \ 881ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky pte_clear((__mm), (__address), (__ptep)); \ 882ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky __pte; \ 883ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky}) 884ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky 885ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_CLEAR_FLUSH 886f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefskystatic inline pte_t ptep_clear_flush(struct vm_area_struct *vma, 887f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky unsigned long address, pte_t *ptep) 888f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky{ 889f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky pte_t pte = *ptep; 890146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky ptep_invalidate(vma->vm_mm, address, ptep); 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pte; 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 894ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky/* 895ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * The batched pte unmap code uses ptep_get_and_clear_full to clear the 896ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * ptes. Here an optimization is possible. tlb_gather_mmu flushes all 897ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * tlbs of an mm if it can guarantee that the ptes of the mm_struct 898ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * cannot be accessed while the batched unmap is running. In this case 899ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky * full==1 and a simple pte_clear is enough. See tlb.h. 900ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky */ 901ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL 902ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefskystatic inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, 903ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky unsigned long addr, 904ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky pte_t *ptep, int full) 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 906ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky pte_t pte = *ptep; 907ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky 908ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky if (full) 909ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky pte_clear(mm, addr, ptep); 910ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky else 911146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky ptep_invalidate(mm, addr, ptep); 912ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky return pte; 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 915ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_SET_WRPROTECT 916ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define ptep_set_wrprotect(__mm, __addr, __ptep) \ 917ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky({ \ 918ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky pte_t __pte = *(__ptep); \ 919ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky if (pte_write(__pte)) { \ 920050eef364ad700590a605a0749f825cab4834b1eMartin Schwidefsky (__mm)->context.flush_mm = 1; \ 921050eef364ad700590a605a0749f825cab4834b1eMartin Schwidefsky if (atomic_read(&(__mm)->context.attach_count) > 1 || \ 922ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky (__mm) != current->active_mm) \ 923146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky ptep_invalidate(__mm, __addr, __ptep); \ 924ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \ 925ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky } \ 926ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky}) 927ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky 928ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS 929f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky#define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \ 930f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky({ \ 931f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky int __changed = !pte_same(*(__ptep), __entry); \ 932f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky if (__changed) { \ 933146e4b3c8b92071b18f0b2e6f47165bad4f9e825Martin Schwidefsky ptep_invalidate((__vma)->vm_mm, __addr, __ptep); \ 934f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky set_pte_at((__vma)->vm_mm, __addr, __ptep, __entry); \ 935f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky } \ 936f0e47c229b489e37ba7e4159ef7f9cf9ccd44e19Martin Schwidefsky __changed; \ 9378dab5241d06bfc9ee141ea78c56cde5070d7460dBenjamin Herrenschmidt}) 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Test and clear dirty bit in storage key. 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We can't clear the changed bit atomically. This is a potential 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * race against modification of the referenced bit. This function 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * should therefore only be called if it is not mapped in any 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * address space. 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 946ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PAGE_TEST_DIRTY 9476c210482ae4a9a5bb9377ad250feaacec3faa3cdMartin Schwidefskystatic inline int page_test_dirty(struct page *page) 9482dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens{ 9496c210482ae4a9a5bb9377ad250feaacec3faa3cdMartin Schwidefsky return (page_get_storage_key(page_to_phys(page)) & _PAGE_CHANGED) != 0; 9506c210482ae4a9a5bb9377ad250feaacec3faa3cdMartin Schwidefsky} 9512dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens 952ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PAGE_CLEAR_DIRTY 953e2b8d7af0e3a9234de06606f9151f28cf847a8d6Martin Schwidefskystatic inline void page_clear_dirty(struct page *page, int mapped) 9546c210482ae4a9a5bb9377ad250feaacec3faa3cdMartin Schwidefsky{ 955e2b8d7af0e3a9234de06606f9151f28cf847a8d6Martin Schwidefsky page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, mapped); 9562dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens} 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Test and clear referenced bit in storage key. 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 961ba8a9229ab9e80278c28ad68b15053f65b2b0a7cMartin Schwidefsky#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG 9622dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstensstatic inline int page_test_and_clear_young(struct page *page) 9632dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens{ 9640b2b6e1ddce4696cb7afcbb15a654fe95428a498Heiko Carstens unsigned long physpage = page_to_phys(page); 9652dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens int ccode; 9662dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens 9670b2b6e1ddce4696cb7afcbb15a654fe95428a498Heiko Carstens asm volatile( 9680b2b6e1ddce4696cb7afcbb15a654fe95428a498Heiko Carstens " rrbe 0,%1\n" 9690b2b6e1ddce4696cb7afcbb15a654fe95428a498Heiko Carstens " ipm %0\n" 9700b2b6e1ddce4696cb7afcbb15a654fe95428a498Heiko Carstens " srl %0,28\n" 9712dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens : "=d" (ccode) : "a" (physpage) : "cc" ); 9722dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens return ccode & 2; 9732dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens} 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Conversion functions: convert a page and protection to a page entry, 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and a page entry and page directory to the page they refer to. 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pte_t __pte; 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pte_val(__pte) = physpage + pgprot_val(pgprot); 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return __pte; 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9862dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstensstatic inline pte_t mk_pte(struct page *page, pgprot_t pgprot) 9872dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens{ 9880b2b6e1ddce4696cb7afcbb15a654fe95428a498Heiko Carstens unsigned long physpage = page_to_phys(page); 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9902dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens return mk_pte_phys(physpage, pgprot); 9912dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens} 9922dcea57ae19275451a756a2d5bf96b329487b0e0Heiko Carstens 993190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) 994190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) 995190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) 996190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 998190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) 999190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pgd_offset_k(address) pgd_offset(&init_mm, address) 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#ifndef __s390x__ 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1003190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) 1004190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_deref(pmd) ({ BUG(); 0UL; }) 1005190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pgd_deref(pmd) ({ BUG(); 0UL; }) 100646a82b2d5591335277ed2930611f6acb4ce654edDave McCracken 1007190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_offset(pgd, address) ((pud_t *) pgd) 1008190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address)) 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1010190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#else /* __s390x__ */ 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1012190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) 1013190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN) 10145a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky#define pgd_deref(pgd) (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10165a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefskystatic inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) 10175a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky{ 10186252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky pud_t *pud = (pud_t *) pgd; 10196252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) 10206252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky pud = (pud_t *) pgd_deref(*pgd); 10215a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky return pud + pud_index(address); 10225a216a20837c5f5fa1ca4b8ae8991ffd96b08e6fMartin Schwidefsky} 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1024190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefskystatic inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10266252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky pmd_t *pmd = (pmd_t *) pud; 10276252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) 10286252d702c5311ce916caf75ed82e5c8245171c92Martin Schwidefsky pmd = (pmd_t *) pud_deref(*pud); 1029190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky return pmd + pmd_index(address); 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1032190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#endif /* __s390x__ */ 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1034190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot)) 1035190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) 1036190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_page(x) pfn_to_page(pte_pfn(x)) 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1038190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1040190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky/* Find an entry in the lowest level page table.. */ 1041190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr)) 1042190a1d722a59725706daf832bc8a511ed62f249dMartin Schwidefsky#define pte_offset_kernel(pmd, address) pte_offset(pmd,address) 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address) 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pte_unmap(pte) do { } while (0) 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31 bit swap entry format: 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A page-table entry has some bits we have to treat in a special way. 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bits 0, 20 and bit 23 have to be zero, otherwise an specification 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * exception will occur instead of a page translation exception. The 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * specifiation exception has the bad habit not to store necessary 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * information in the lowcore. 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 21 and bit 22 are the page invalid bit and the page protection 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit. We set both to indicate a swapped page. 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 30 and 31 are used to distinguish the different page types. For 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a swapped page these bits need to be zero. 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This leaves the bits 1-19 and bits 24-29 to store type and offset. 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We use the 5 bits from 25-29 for the type and the 20 bits from 1-19 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * plus 24 for the offset. 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0| offset |0110|o|type |00| 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 0000000001111111111 2222 2 22222 33 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 1234567890123456789 0123 4 56789 01 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 64 bit swap entry format: 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A page-table entry has some bits we have to treat in a special way. 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bits 52 and bit 55 have to be zero, otherwise an specification 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * exception will occur instead of a page translation exception. The 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * specifiation exception has the bad habit not to store necessary 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * information in the lowcore. 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 53 and bit 54 are the page invalid bit and the page protection 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit. We set both to indicate a swapped page. 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 62 and 63 are used to distinguish the different page types. For 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a swapped page these bits need to be zero. 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This leaves the bits 0-51 and bits 56-61 to store type and offset. 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We use the 5 bits from 57-61 for the type and the 53 bits from 0-51 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * plus 56 for the offset. 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | offset |0110|o|type |00| 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0000000000111111111122222222223333333333444444444455 5555 5 55566 66 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0123456789012345678901234567890123456789012345678901 2345 6 78901 23 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __s390x__ 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __SWP_OFFSET_MASK (~0UL >> 12) 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __SWP_OFFSET_MASK (~0UL >> 11) 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 10864448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pte_t pte; 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds offset &= __SWP_OFFSET_MASK; 10909282ed929758b82f448a40d3c17319d794970624Gerald Schaefer pte_val(pte) = _PAGE_TYPE_SWAP | ((type & 0x1f) << 2) | 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((offset & 1UL) << 7) | ((offset & ~1UL) << 11); 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pte; 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __swp_type(entry) (((entry).val >> 2) & 0x1f) 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __swp_offset(entry) (((entry).val >> 11) | (((entry).val >> 7) & 1)) 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __swp_entry(type,offset) ((swp_entry_t) { pte_val(mk_swap_pte((type),(offset))) }) 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __s390x__ 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define PTE_FILE_MAX_BITS 26 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* __s390x__ */ 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define PTE_FILE_MAX_BITS 59 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __s390x__ */ 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pte_to_pgoff(__pte) \ 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f)) 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pgoff_to_pte(__off) \ 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \ 11139282ed929758b82f448a40d3c17319d794970624Gerald Schaefer | _PAGE_TYPE_FILE }) 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* !__ASSEMBLY__ */ 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define kern_addr_valid(addr) (1) 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111917f345808563d2f425b2b15d60c4a5b00112e9ebHeiko Carstensextern int vmem_add_mapping(unsigned long start, unsigned long size); 112017f345808563d2f425b2b15d60c4a5b00112e9ebHeiko Carstensextern int vmem_remove_mapping(unsigned long start, unsigned long size); 1121402b08622d9ac6e32e25289573272e0f21bb58a7Carsten Otteextern int s390_enable_sie(void); 1122f4eb07c17df2e6cf9bd58bfcd9cc9e05e9489d07Heiko Carstens 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * No page table caches to initialise 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pgtable_cache_init() do { } while (0) 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm-generic/pgtable.h> 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* _S390_PAGE_H */ 1131