diff options
Diffstat (limited to 'arch/s390/include/asm')
| -rw-r--r-- | arch/s390/include/asm/ccwdev.h | 12 | ||||
| -rw-r--r-- | arch/s390/include/asm/cpu.h | 2 | ||||
| -rw-r--r-- | arch/s390/include/asm/hugetlb.h | 26 | ||||
| -rw-r--r-- | arch/s390/include/asm/lowcore.h | 11 | ||||
| -rw-r--r-- | arch/s390/include/asm/page.h | 8 | ||||
| -rw-r--r-- | arch/s390/include/asm/pgalloc.h | 4 | ||||
| -rw-r--r-- | arch/s390/include/asm/pgtable.h | 60 | ||||
| -rw-r--r-- | arch/s390/include/asm/processor.h | 2 | ||||
| -rw-r--r-- | arch/s390/include/asm/ptrace.h | 3 | ||||
| -rw-r--r-- | arch/s390/include/asm/s390_ext.h | 2 | ||||
| -rw-r--r-- | arch/s390/include/asm/scatterlist.h | 2 | ||||
| -rw-r--r-- | arch/s390/include/asm/setup.h | 3 | ||||
| -rw-r--r-- | arch/s390/include/asm/syscall.h | 4 | ||||
| -rw-r--r-- | arch/s390/include/asm/sysinfo.h | 40 | ||||
| -rw-r--r-- | arch/s390/include/asm/system.h | 51 | ||||
| -rw-r--r-- | arch/s390/include/asm/tlb.h | 13 | ||||
| -rw-r--r-- | arch/s390/include/asm/topology.h | 2 |
17 files changed, 161 insertions, 84 deletions
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index f3ba0fa98de6..e8501115eca8 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h | |||
| @@ -92,6 +92,16 @@ struct ccw_device { | |||
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | /* | 94 | /* |
| 95 | * Possible events used by the path_event notifier. | ||
| 96 | */ | ||
| 97 | #define PE_NONE 0x0 | ||
| 98 | #define PE_PATH_GONE 0x1 /* A path is no longer available. */ | ||
| 99 | #define PE_PATH_AVAILABLE 0x2 /* A path has become available and | ||
| 100 | was successfully verified. */ | ||
| 101 | #define PE_PATHGROUP_ESTABLISHED 0x4 /* A pathgroup was reset and had | ||
| 102 | to be established again. */ | ||
| 103 | |||
| 104 | /* | ||
| 95 | * Possible CIO actions triggered by the unit check handler. | 105 | * Possible CIO actions triggered by the unit check handler. |
| 96 | */ | 106 | */ |
| 97 | enum uc_todo { | 107 | enum uc_todo { |
| @@ -109,6 +119,7 @@ enum uc_todo { | |||
| 109 | * @set_online: called when setting device online | 119 | * @set_online: called when setting device online |
| 110 | * @set_offline: called when setting device offline | 120 | * @set_offline: called when setting device offline |
| 111 | * @notify: notify driver of device state changes | 121 | * @notify: notify driver of device state changes |
| 122 | * @path_event: notify driver of channel path events | ||
| 112 | * @shutdown: called at device shutdown | 123 | * @shutdown: called at device shutdown |
| 113 | * @prepare: prepare for pm state transition | 124 | * @prepare: prepare for pm state transition |
| 114 | * @complete: undo work done in @prepare | 125 | * @complete: undo work done in @prepare |
| @@ -127,6 +138,7 @@ struct ccw_driver { | |||
| 127 | int (*set_online) (struct ccw_device *); | 138 | int (*set_online) (struct ccw_device *); |
| 128 | int (*set_offline) (struct ccw_device *); | 139 | int (*set_offline) (struct ccw_device *); |
| 129 | int (*notify) (struct ccw_device *, int); | 140 | int (*notify) (struct ccw_device *, int); |
| 141 | void (*path_event) (struct ccw_device *, int *); | ||
| 130 | void (*shutdown) (struct ccw_device *); | 142 | void (*shutdown) (struct ccw_device *); |
| 131 | int (*prepare) (struct ccw_device *); | 143 | int (*prepare) (struct ccw_device *); |
| 132 | void (*complete) (struct ccw_device *); | 144 | void (*complete) (struct ccw_device *); |
diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h index 471234b90574..e0b69540216f 100644 --- a/arch/s390/include/asm/cpu.h +++ b/arch/s390/include/asm/cpu.h | |||
| @@ -20,7 +20,7 @@ struct cpuid | |||
| 20 | unsigned int ident : 24; | 20 | unsigned int ident : 24; |
| 21 | unsigned int machine : 16; | 21 | unsigned int machine : 16; |
| 22 | unsigned int unused : 16; | 22 | unsigned int unused : 16; |
| 23 | } __packed; | 23 | } __attribute__ ((packed, aligned(8))); |
| 24 | 24 | ||
| 25 | #endif /* __ASSEMBLY__ */ | 25 | #endif /* __ASSEMBLY__ */ |
| 26 | #endif /* _ASM_S390_CPU_H */ | 26 | #endif /* _ASM_S390_CPU_H */ |
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h index bb8343d157bc..b56403c2df28 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h | |||
| @@ -37,32 +37,6 @@ static inline int prepare_hugepage_range(struct file *file, | |||
| 37 | int arch_prepare_hugepage(struct page *page); | 37 | int arch_prepare_hugepage(struct page *page); |
| 38 | void arch_release_hugepage(struct page *page); | 38 | void arch_release_hugepage(struct page *page); |
| 39 | 39 | ||
| 40 | static inline pte_t pte_mkhuge(pte_t pte) | ||
| 41 | { | ||
| 42 | /* | ||
| 43 | * PROT_NONE needs to be remapped from the pte type to the ste type. | ||
| 44 | * The HW invalid bit is also different for pte and ste. The pte | ||
| 45 | * invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE | ||
| 46 | * bit, so we don't have to clear it. | ||
| 47 | */ | ||
| 48 | if (pte_val(pte) & _PAGE_INVALID) { | ||
| 49 | if (pte_val(pte) & _PAGE_SWT) | ||
| 50 | pte_val(pte) |= _HPAGE_TYPE_NONE; | ||
| 51 | pte_val(pte) |= _SEGMENT_ENTRY_INV; | ||
| 52 | } | ||
| 53 | /* | ||
| 54 | * Clear SW pte bits SWT and SWX, there are no SW bits in a segment | ||
| 55 | * table entry. | ||
| 56 | */ | ||
| 57 | pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX); | ||
| 58 | /* | ||
| 59 | * Also set the change-override bit because we don't need dirty bit | ||
| 60 | * tracking for hugetlbfs pages. | ||
| 61 | */ | ||
| 62 | pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO); | ||
| 63 | return pte; | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline pte_t huge_pte_wrprotect(pte_t pte) | 40 | static inline pte_t huge_pte_wrprotect(pte_t pte) |
| 67 | { | 41 | { |
| 68 | pte_val(pte) |= _PAGE_RO; | 42 | pte_val(pte) |= _PAGE_RO; |
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 0f97ef2d92ac..65e172f8209d 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h | |||
| @@ -150,9 +150,10 @@ struct _lowcore { | |||
| 150 | */ | 150 | */ |
| 151 | __u32 ipib; /* 0x0e00 */ | 151 | __u32 ipib; /* 0x0e00 */ |
| 152 | __u32 ipib_checksum; /* 0x0e04 */ | 152 | __u32 ipib_checksum; /* 0x0e04 */ |
| 153 | __u8 pad_0x0e08[0x0f00-0x0e08]; /* 0x0e08 */ | ||
| 153 | 154 | ||
| 154 | /* Align to the top 1k of prefix area */ | 155 | /* Extended facility list */ |
| 155 | __u8 pad_0x0e08[0x1000-0x0e08]; /* 0x0e08 */ | 156 | __u64 stfle_fac_list[32]; /* 0x0f00 */ |
| 156 | } __packed; | 157 | } __packed; |
| 157 | 158 | ||
| 158 | #else /* CONFIG_32BIT */ | 159 | #else /* CONFIG_32BIT */ |
| @@ -285,7 +286,11 @@ struct _lowcore { | |||
| 285 | */ | 286 | */ |
| 286 | __u64 ipib; /* 0x0e00 */ | 287 | __u64 ipib; /* 0x0e00 */ |
| 287 | __u32 ipib_checksum; /* 0x0e08 */ | 288 | __u32 ipib_checksum; /* 0x0e08 */ |
| 288 | __u8 pad_0x0e0c[0x11b8-0x0e0c]; /* 0x0e0c */ | 289 | __u8 pad_0x0e0c[0x0f00-0x0e0c]; /* 0x0e0c */ |
| 290 | |||
| 291 | /* Extended facility list */ | ||
| 292 | __u64 stfle_fac_list[32]; /* 0x0f00 */ | ||
| 293 | __u8 pad_0x1000[0x11b8-0x1000]; /* 0x1000 */ | ||
| 289 | 294 | ||
| 290 | /* 64 bit extparam used for pfault/diag 250: defined by architecture */ | 295 | /* 64 bit extparam used for pfault/diag 250: defined by architecture */ |
| 291 | __u64 ext_params2; /* 0x11B8 */ | 296 | __u64 ext_params2; /* 0x11B8 */ |
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index af650fb47206..a8729ea7e9ac 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h | |||
| @@ -108,9 +108,13 @@ typedef pte_t *pgtable_t; | |||
| 108 | #define __pgprot(x) ((pgprot_t) { (x) } ) | 108 | #define __pgprot(x) ((pgprot_t) { (x) } ) |
| 109 | 109 | ||
| 110 | static inline void | 110 | static inline void |
| 111 | page_set_storage_key(unsigned long addr, unsigned int skey) | 111 | page_set_storage_key(unsigned long addr, unsigned int skey, int mapped) |
| 112 | { | 112 | { |
| 113 | asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); | 113 | if (!mapped) |
| 114 | asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0" | ||
| 115 | : : "d" (skey), "a" (addr)); | ||
| 116 | else | ||
| 117 | asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); | ||
| 114 | } | 118 | } |
| 115 | 119 | ||
| 116 | static inline unsigned int | 120 | static inline unsigned int |
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index 68940d0bad91..082eb4e50e8b 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h | |||
| @@ -21,9 +21,11 @@ | |||
| 21 | 21 | ||
| 22 | unsigned long *crst_table_alloc(struct mm_struct *, int); | 22 | unsigned long *crst_table_alloc(struct mm_struct *, int); |
| 23 | void crst_table_free(struct mm_struct *, unsigned long *); | 23 | void crst_table_free(struct mm_struct *, unsigned long *); |
| 24 | void crst_table_free_rcu(struct mm_struct *, unsigned long *); | ||
| 24 | 25 | ||
| 25 | unsigned long *page_table_alloc(struct mm_struct *); | 26 | unsigned long *page_table_alloc(struct mm_struct *); |
| 26 | void page_table_free(struct mm_struct *, unsigned long *); | 27 | void page_table_free(struct mm_struct *, unsigned long *); |
| 28 | void page_table_free_rcu(struct mm_struct *, unsigned long *); | ||
| 27 | void disable_noexec(struct mm_struct *, struct task_struct *); | 29 | void disable_noexec(struct mm_struct *, struct task_struct *); |
| 28 | 30 | ||
| 29 | static inline void clear_table(unsigned long *s, unsigned long val, size_t n) | 31 | static inline void clear_table(unsigned long *s, unsigned long val, size_t n) |
| @@ -176,4 +178,6 @@ static inline void pmd_populate(struct mm_struct *mm, | |||
| 176 | #define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte) | 178 | #define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte) |
| 177 | #define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte) | 179 | #define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte) |
| 178 | 180 | ||
| 181 | extern void rcu_table_freelist_finish(void); | ||
| 182 | |||
| 179 | #endif /* _S390_PGALLOC_H */ | 183 | #endif /* _S390_PGALLOC_H */ |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 3157441ee1da..986dc9476c21 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096))); | 38 | extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096))); |
| 39 | extern void paging_init(void); | 39 | extern void paging_init(void); |
| 40 | extern void vmem_map_init(void); | 40 | extern void vmem_map_init(void); |
| 41 | extern void fault_init(void); | ||
| 41 | 42 | ||
| 42 | /* | 43 | /* |
| 43 | * The S390 doesn't have any external MMU info: the kernel page | 44 | * The S390 doesn't have any external MMU info: the kernel page |
| @@ -46,11 +47,27 @@ extern void vmem_map_init(void); | |||
| 46 | #define update_mmu_cache(vma, address, ptep) do { } while (0) | 47 | #define update_mmu_cache(vma, address, ptep) do { } while (0) |
| 47 | 48 | ||
| 48 | /* | 49 | /* |
| 49 | * ZERO_PAGE is a global shared page that is always zero: used | 50 | * ZERO_PAGE is a global shared page that is always zero; used |
| 50 | * for zero-mapped memory areas etc.. | 51 | * for zero-mapped memory areas etc.. |
| 51 | */ | 52 | */ |
| 52 | extern char empty_zero_page[PAGE_SIZE]; | 53 | |
| 53 | #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) | 54 | extern unsigned long empty_zero_page; |
| 55 | extern unsigned long zero_page_mask; | ||
| 56 | |||
| 57 | #define ZERO_PAGE(vaddr) \ | ||
| 58 | (virt_to_page((void *)(empty_zero_page + \ | ||
| 59 | (((unsigned long)(vaddr)) &zero_page_mask)))) | ||
| 60 | |||
| 61 | #define is_zero_pfn is_zero_pfn | ||
| 62 | static inline int is_zero_pfn(unsigned long pfn) | ||
| 63 | { | ||
| 64 | extern unsigned long zero_pfn; | ||
| 65 | unsigned long offset_from_zero_pfn = pfn - zero_pfn; | ||
| 66 | return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT); | ||
| 67 | } | ||
| 68 | |||
| 69 | #define my_zero_pfn(addr) page_to_pfn(ZERO_PAGE(addr)) | ||
| 70 | |||
| 54 | #endif /* !__ASSEMBLY__ */ | 71 | #endif /* !__ASSEMBLY__ */ |
| 55 | 72 | ||
| 56 | /* | 73 | /* |
| @@ -300,6 +317,7 @@ extern unsigned long VMALLOC_START; | |||
| 300 | 317 | ||
| 301 | /* Bits in the segment table entry */ | 318 | /* Bits in the segment table entry */ |
| 302 | #define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */ | 319 | #define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */ |
| 320 | #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ | ||
| 303 | #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ | 321 | #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ |
| 304 | #define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */ | 322 | #define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */ |
| 305 | #define _SEGMENT_ENTRY_PTL 0x0f /* page table length */ | 323 | #define _SEGMENT_ENTRY_PTL 0x0f /* page table length */ |
| @@ -572,7 +590,7 @@ static inline void rcp_unlock(pte_t *ptep) | |||
| 572 | } | 590 | } |
| 573 | 591 | ||
| 574 | /* forward declaration for SetPageUptodate in page-flags.h*/ | 592 | /* forward declaration for SetPageUptodate in page-flags.h*/ |
| 575 | static inline void page_clear_dirty(struct page *page); | 593 | static inline void page_clear_dirty(struct page *page, int mapped); |
| 576 | #include <linux/page-flags.h> | 594 | #include <linux/page-flags.h> |
| 577 | 595 | ||
| 578 | static inline void ptep_rcp_copy(pte_t *ptep) | 596 | static inline void ptep_rcp_copy(pte_t *ptep) |
| @@ -754,6 +772,34 @@ static inline pte_t pte_mkspecial(pte_t pte) | |||
| 754 | return pte; | 772 | return pte; |
| 755 | } | 773 | } |
| 756 | 774 | ||
| 775 | #ifdef CONFIG_HUGETLB_PAGE | ||
| 776 | static inline pte_t pte_mkhuge(pte_t pte) | ||
| 777 | { | ||
| 778 | /* | ||
| 779 | * PROT_NONE needs to be remapped from the pte type to the ste type. | ||
| 780 | * The HW invalid bit is also different for pte and ste. The pte | ||
| 781 | * invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE | ||
| 782 | * bit, so we don't have to clear it. | ||
| 783 | */ | ||
| 784 | if (pte_val(pte) & _PAGE_INVALID) { | ||
| 785 | if (pte_val(pte) & _PAGE_SWT) | ||
| 786 | pte_val(pte) |= _HPAGE_TYPE_NONE; | ||
| 787 | pte_val(pte) |= _SEGMENT_ENTRY_INV; | ||
| 788 | } | ||
| 789 | /* | ||
| 790 | * Clear SW pte bits SWT and SWX, there are no SW bits in a segment | ||
| 791 | * table entry. | ||
| 792 | */ | ||
| 793 | pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX); | ||
| 794 | /* | ||
| 795 | * Also set the change-override bit because we don't need dirty bit | ||
| 796 | * tracking for hugetlbfs pages. | ||
| 797 | */ | ||
| 798 | pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO); | ||
| 799 | return pte; | ||
| 800 | } | ||
| 801 | #endif | ||
| 802 | |||
| 757 | #ifdef CONFIG_PGSTE | 803 | #ifdef CONFIG_PGSTE |
| 758 | /* | 804 | /* |
| 759 | * Get (and clear) the user dirty bit for a PTE. | 805 | * Get (and clear) the user dirty bit for a PTE. |
| @@ -782,7 +828,7 @@ static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm, | |||
| 782 | } | 828 | } |
| 783 | dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste); | 829 | dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste); |
| 784 | if (skey & _PAGE_CHANGED) | 830 | if (skey & _PAGE_CHANGED) |
| 785 | page_clear_dirty(page); | 831 | page_clear_dirty(page, 1); |
| 786 | rcp_unlock(ptep); | 832 | rcp_unlock(ptep); |
| 787 | return dirty; | 833 | return dirty; |
| 788 | } | 834 | } |
| @@ -957,9 +1003,9 @@ static inline int page_test_dirty(struct page *page) | |||
| 957 | } | 1003 | } |
| 958 | 1004 | ||
| 959 | #define __HAVE_ARCH_PAGE_CLEAR_DIRTY | 1005 | #define __HAVE_ARCH_PAGE_CLEAR_DIRTY |
| 960 | static inline void page_clear_dirty(struct page *page) | 1006 | static inline void page_clear_dirty(struct page *page, int mapped) |
| 961 | { | 1007 | { |
| 962 | page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY); | 1008 | page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, mapped); |
| 963 | } | 1009 | } |
| 964 | 1010 | ||
| 965 | /* | 1011 | /* |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 73e259834e10..8d6f87169577 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
| @@ -82,8 +82,6 @@ struct thread_struct { | |||
| 82 | unsigned long prot_addr; /* address of protection-excep. */ | 82 | unsigned long prot_addr; /* address of protection-excep. */ |
| 83 | unsigned int trap_no; | 83 | unsigned int trap_no; |
| 84 | per_struct per_info; | 84 | per_struct per_info; |
| 85 | /* Used to give failing instruction back to user for ieee exceptions */ | ||
| 86 | unsigned long ieee_instruction_pointer; | ||
| 87 | /* pfault_wait is used to block the process on a pfault event */ | 85 | /* pfault_wait is used to block the process on a pfault event */ |
| 88 | unsigned long pfault_wait; | 86 | unsigned long pfault_wait; |
| 89 | }; | 87 | }; |
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index e2c218dc68a6..d9d42b1e46fa 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h | |||
| @@ -481,8 +481,7 @@ struct user_regs_struct | |||
| 481 | * watchpoints. This is the way intel does it. | 481 | * watchpoints. This is the way intel does it. |
| 482 | */ | 482 | */ |
| 483 | per_struct per_info; | 483 | per_struct per_info; |
| 484 | unsigned long ieee_instruction_pointer; | 484 | unsigned long ieee_instruction_pointer; /* obsolete, always 0 */ |
| 485 | /* Used to give failing instruction back to user for ieee exceptions */ | ||
| 486 | }; | 485 | }; |
| 487 | 486 | ||
| 488 | #ifdef __KERNEL__ | 487 | #ifdef __KERNEL__ |
diff --git a/arch/s390/include/asm/s390_ext.h b/arch/s390/include/asm/s390_ext.h index 2afc060266a2..1a9307e70842 100644 --- a/arch/s390/include/asm/s390_ext.h +++ b/arch/s390/include/asm/s390_ext.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 14 | 14 | ||
| 15 | typedef void (*ext_int_handler_t)(__u16 code); | 15 | typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long); |
| 16 | 16 | ||
| 17 | typedef struct ext_int_info_t { | 17 | typedef struct ext_int_info_t { |
| 18 | struct ext_int_info_t *next; | 18 | struct ext_int_info_t *next; |
diff --git a/arch/s390/include/asm/scatterlist.h b/arch/s390/include/asm/scatterlist.h index 35d786fe93ae..6d45ef6c12a7 100644 --- a/arch/s390/include/asm/scatterlist.h +++ b/arch/s390/include/asm/scatterlist.h | |||
| @@ -1 +1,3 @@ | |||
| 1 | #include <asm-generic/scatterlist.h> | 1 | #include <asm-generic/scatterlist.h> |
| 2 | |||
| 3 | #define ARCH_HAS_SG_CHAIN | ||
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 25e831d58e1e..d5e2ef10537d 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
| @@ -73,6 +73,7 @@ extern unsigned int user_mode; | |||
| 73 | #define MACHINE_FLAG_PFMF (1UL << 11) | 73 | #define MACHINE_FLAG_PFMF (1UL << 11) |
| 74 | #define MACHINE_FLAG_LPAR (1UL << 12) | 74 | #define MACHINE_FLAG_LPAR (1UL << 12) |
| 75 | #define MACHINE_FLAG_SPP (1UL << 13) | 75 | #define MACHINE_FLAG_SPP (1UL << 13) |
| 76 | #define MACHINE_FLAG_TOPOLOGY (1UL << 14) | ||
| 76 | 77 | ||
| 77 | #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) | 78 | #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) |
| 78 | #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) | 79 | #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) |
| @@ -90,6 +91,7 @@ extern unsigned int user_mode; | |||
| 90 | #define MACHINE_HAS_HPAGE (0) | 91 | #define MACHINE_HAS_HPAGE (0) |
| 91 | #define MACHINE_HAS_PFMF (0) | 92 | #define MACHINE_HAS_PFMF (0) |
| 92 | #define MACHINE_HAS_SPP (0) | 93 | #define MACHINE_HAS_SPP (0) |
| 94 | #define MACHINE_HAS_TOPOLOGY (0) | ||
| 93 | #else /* __s390x__ */ | 95 | #else /* __s390x__ */ |
| 94 | #define MACHINE_HAS_IEEE (1) | 96 | #define MACHINE_HAS_IEEE (1) |
| 95 | #define MACHINE_HAS_CSP (1) | 97 | #define MACHINE_HAS_CSP (1) |
| @@ -100,6 +102,7 @@ extern unsigned int user_mode; | |||
| 100 | #define MACHINE_HAS_HPAGE (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE) | 102 | #define MACHINE_HAS_HPAGE (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE) |
| 101 | #define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) | 103 | #define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) |
| 102 | #define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) | 104 | #define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) |
| 105 | #define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) | ||
| 103 | #endif /* __s390x__ */ | 106 | #endif /* __s390x__ */ |
| 104 | 107 | ||
| 105 | #define ZFCPDUMP_HSA_SIZE (32UL<<20) | 108 | #define ZFCPDUMP_HSA_SIZE (32UL<<20) |
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h index 8429686951f9..5c0246b955d8 100644 --- a/arch/s390/include/asm/syscall.h +++ b/arch/s390/include/asm/syscall.h | |||
| @@ -65,8 +65,6 @@ static inline void syscall_get_arguments(struct task_struct *task, | |||
| 65 | if (test_tsk_thread_flag(task, TIF_31BIT)) | 65 | if (test_tsk_thread_flag(task, TIF_31BIT)) |
| 66 | mask = 0xffffffff; | 66 | mask = 0xffffffff; |
| 67 | #endif | 67 | #endif |
| 68 | if (i + n == 6) | ||
| 69 | args[--n] = regs->args[0] & mask; | ||
| 70 | while (n-- > 0) | 68 | while (n-- > 0) |
| 71 | if (i + n > 0) | 69 | if (i + n > 0) |
| 72 | args[n] = regs->gprs[2 + i + n] & mask; | 70 | args[n] = regs->gprs[2 + i + n] & mask; |
| @@ -80,8 +78,6 @@ static inline void syscall_set_arguments(struct task_struct *task, | |||
| 80 | const unsigned long *args) | 78 | const unsigned long *args) |
| 81 | { | 79 | { |
| 82 | BUG_ON(i + n > 6); | 80 | BUG_ON(i + n > 6); |
| 83 | if (i + n == 6) | ||
| 84 | regs->args[0] = args[--n]; | ||
| 85 | while (n-- > 0) | 81 | while (n-- > 0) |
| 86 | if (i + n > 0) | 82 | if (i + n > 0) |
| 87 | regs->gprs[2 + i + n] = args[n]; | 83 | regs->gprs[2 + i + n] = args[n]; |
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h index 22bdb2a0ee5f..79d3d6e2e9c5 100644 --- a/arch/s390/include/asm/sysinfo.h +++ b/arch/s390/include/asm/sysinfo.h | |||
| @@ -14,8 +14,13 @@ | |||
| 14 | #ifndef __ASM_S390_SYSINFO_H | 14 | #ifndef __ASM_S390_SYSINFO_H |
| 15 | #define __ASM_S390_SYSINFO_H | 15 | #define __ASM_S390_SYSINFO_H |
| 16 | 16 | ||
| 17 | #include <asm/bitsperlong.h> | ||
| 18 | |||
| 17 | struct sysinfo_1_1_1 { | 19 | struct sysinfo_1_1_1 { |
| 18 | char reserved_0[32]; | 20 | unsigned short :16; |
| 21 | unsigned char ccr; | ||
| 22 | unsigned char cai; | ||
| 23 | char reserved_0[28]; | ||
| 19 | char manufacturer[16]; | 24 | char manufacturer[16]; |
| 20 | char type[4]; | 25 | char type[4]; |
| 21 | char reserved_1[12]; | 26 | char reserved_1[12]; |
| @@ -104,6 +109,39 @@ struct sysinfo_3_2_2 { | |||
| 104 | char reserved_544[3552]; | 109 | char reserved_544[3552]; |
| 105 | }; | 110 | }; |
| 106 | 111 | ||
| 112 | #define TOPOLOGY_CPU_BITS 64 | ||
| 113 | #define TOPOLOGY_NR_MAG 6 | ||
| 114 | |||
| 115 | struct topology_cpu { | ||
| 116 | unsigned char reserved0[4]; | ||
| 117 | unsigned char :6; | ||
| 118 | unsigned char pp:2; | ||
| 119 | unsigned char reserved1; | ||
| 120 | unsigned short origin; | ||
| 121 | unsigned long mask[TOPOLOGY_CPU_BITS / BITS_PER_LONG]; | ||
| 122 | }; | ||
| 123 | |||
| 124 | struct topology_container { | ||
| 125 | unsigned char reserved[7]; | ||
| 126 | unsigned char id; | ||
| 127 | }; | ||
| 128 | |||
| 129 | union topology_entry { | ||
| 130 | unsigned char nl; | ||
| 131 | struct topology_cpu cpu; | ||
| 132 | struct topology_container container; | ||
| 133 | }; | ||
| 134 | |||
| 135 | struct sysinfo_15_1_x { | ||
| 136 | unsigned char reserved0[2]; | ||
| 137 | unsigned short length; | ||
| 138 | unsigned char mag[TOPOLOGY_NR_MAG]; | ||
| 139 | unsigned char reserved1; | ||
| 140 | unsigned char mnest; | ||
| 141 | unsigned char reserved2[4]; | ||
| 142 | union topology_entry tle[0]; | ||
| 143 | }; | ||
| 144 | |||
| 107 | static inline int stsi(void *sysinfo, int fc, int sel1, int sel2) | 145 | static inline int stsi(void *sysinfo, int fc, int sel1, int sel2) |
| 108 | { | 146 | { |
| 109 | register int r0 asm("0") = (fc << 28) | sel1; | 147 | register int r0 asm("0") = (fc << 28) | sel1; |
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 1f2ebc4afd82..3ad16dbf622e 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
| @@ -85,14 +85,16 @@ static inline void restore_access_regs(unsigned int *acrs) | |||
| 85 | asm volatile("lam 0,15,%0" : : "Q" (*acrs)); | 85 | asm volatile("lam 0,15,%0" : : "Q" (*acrs)); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | #define switch_to(prev,next,last) do { \ | 88 | #define switch_to(prev,next,last) do { \ |
| 89 | if (prev == next) \ | 89 | if (prev->mm) { \ |
| 90 | break; \ | 90 | save_fp_regs(&prev->thread.fp_regs); \ |
| 91 | save_fp_regs(&prev->thread.fp_regs); \ | 91 | save_access_regs(&prev->thread.acrs[0]); \ |
| 92 | restore_fp_regs(&next->thread.fp_regs); \ | 92 | } \ |
| 93 | save_access_regs(&prev->thread.acrs[0]); \ | 93 | if (next->mm) { \ |
| 94 | restore_access_regs(&next->thread.acrs[0]); \ | 94 | restore_fp_regs(&next->thread.fp_regs); \ |
| 95 | prev = __switch_to(prev,next); \ | 95 | restore_access_regs(&next->thread.acrs[0]); \ |
| 96 | } \ | ||
| 97 | prev = __switch_to(prev,next); \ | ||
| 96 | } while (0) | 98 | } while (0) |
| 97 | 99 | ||
| 98 | extern void account_vtime(struct task_struct *, struct task_struct *); | 100 | extern void account_vtime(struct task_struct *, struct task_struct *); |
| @@ -418,30 +420,21 @@ extern void smp_ctl_clear_bit(int cr, int bit); | |||
| 418 | 420 | ||
| 419 | #endif /* CONFIG_SMP */ | 421 | #endif /* CONFIG_SMP */ |
| 420 | 422 | ||
| 421 | static inline unsigned int stfl(void) | 423 | #define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */ |
| 422 | { | ||
| 423 | asm volatile( | ||
| 424 | " .insn s,0xb2b10000,0(0)\n" /* stfl */ | ||
| 425 | "0:\n" | ||
| 426 | EX_TABLE(0b,0b)); | ||
| 427 | return S390_lowcore.stfl_fac_list; | ||
| 428 | } | ||
| 429 | 424 | ||
| 430 | static inline int __stfle(unsigned long long *list, int doublewords) | 425 | /* |
| 426 | * The test_facility function uses the bit odering where the MSB is bit 0. | ||
| 427 | * That makes it easier to query facility bits with the bit number as | ||
| 428 | * documented in the Principles of Operation. | ||
| 429 | */ | ||
| 430 | static inline int test_facility(unsigned long nr) | ||
| 431 | { | 431 | { |
| 432 | typedef struct { unsigned long long _[doublewords]; } addrtype; | 432 | unsigned char *ptr; |
| 433 | register unsigned long __nr asm("0") = doublewords - 1; | ||
| 434 | |||
| 435 | asm volatile(".insn s,0xb2b00000,%0" /* stfle */ | ||
| 436 | : "=m" (*(addrtype *) list), "+d" (__nr) : : "cc"); | ||
| 437 | return __nr + 1; | ||
| 438 | } | ||
| 439 | 433 | ||
| 440 | static inline int stfle(unsigned long long *list, int doublewords) | 434 | if (nr >= MAX_FACILITY_BIT) |
| 441 | { | 435 | return 0; |
| 442 | if (!(stfl() & (1UL << 24))) | 436 | ptr = (unsigned char *) &S390_lowcore.stfle_fac_list + (nr >> 3); |
| 443 | return -EOPNOTSUPP; | 437 | return (*ptr & (0x80 >> (nr & 7))) != 0; |
| 444 | return __stfle(list, doublewords); | ||
| 445 | } | 438 | } |
| 446 | 439 | ||
| 447 | static inline unsigned short stap(void) | 440 | static inline unsigned short stap(void) |
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index fd1c00d08bf5..f1f644f2240a 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h | |||
| @@ -64,10 +64,9 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb, | |||
| 64 | if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS)) | 64 | if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS)) |
| 65 | __tlb_flush_mm(tlb->mm); | 65 | __tlb_flush_mm(tlb->mm); |
| 66 | while (tlb->nr_ptes > 0) | 66 | while (tlb->nr_ptes > 0) |
| 67 | pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); | 67 | page_table_free_rcu(tlb->mm, tlb->array[--tlb->nr_ptes]); |
| 68 | while (tlb->nr_pxds < TLB_NR_PTRS) | 68 | while (tlb->nr_pxds < TLB_NR_PTRS) |
| 69 | /* pgd_free frees the pointer as region or segment table */ | 69 | crst_table_free_rcu(tlb->mm, tlb->array[tlb->nr_pxds++]); |
| 70 | pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]); | ||
| 71 | } | 70 | } |
| 72 | 71 | ||
| 73 | static inline void tlb_finish_mmu(struct mmu_gather *tlb, | 72 | static inline void tlb_finish_mmu(struct mmu_gather *tlb, |
| @@ -75,6 +74,8 @@ static inline void tlb_finish_mmu(struct mmu_gather *tlb, | |||
| 75 | { | 74 | { |
| 76 | tlb_flush_mmu(tlb, start, end); | 75 | tlb_flush_mmu(tlb, start, end); |
| 77 | 76 | ||
| 77 | rcu_table_freelist_finish(); | ||
| 78 | |||
| 78 | /* keep the page table cache within bounds */ | 79 | /* keep the page table cache within bounds */ |
| 79 | check_pgt_cache(); | 80 | check_pgt_cache(); |
| 80 | 81 | ||
| @@ -103,7 +104,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | |||
| 103 | if (tlb->nr_ptes >= tlb->nr_pxds) | 104 | if (tlb->nr_ptes >= tlb->nr_pxds) |
| 104 | tlb_flush_mmu(tlb, 0, 0); | 105 | tlb_flush_mmu(tlb, 0, 0); |
| 105 | } else | 106 | } else |
| 106 | pte_free(tlb->mm, pte); | 107 | page_table_free(tlb->mm, (unsigned long *) pte); |
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | /* | 110 | /* |
| @@ -124,7 +125,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, | |||
| 124 | if (tlb->nr_ptes >= tlb->nr_pxds) | 125 | if (tlb->nr_ptes >= tlb->nr_pxds) |
| 125 | tlb_flush_mmu(tlb, 0, 0); | 126 | tlb_flush_mmu(tlb, 0, 0); |
| 126 | } else | 127 | } else |
| 127 | pmd_free(tlb->mm, pmd); | 128 | crst_table_free(tlb->mm, (unsigned long *) pmd); |
| 128 | #endif | 129 | #endif |
| 129 | } | 130 | } |
| 130 | 131 | ||
| @@ -146,7 +147,7 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, | |||
| 146 | if (tlb->nr_ptes >= tlb->nr_pxds) | 147 | if (tlb->nr_ptes >= tlb->nr_pxds) |
| 147 | tlb_flush_mmu(tlb, 0, 0); | 148 | tlb_flush_mmu(tlb, 0, 0); |
| 148 | } else | 149 | } else |
| 149 | pud_free(tlb->mm, pud); | 150 | crst_table_free(tlb->mm, (unsigned long *) pud); |
| 150 | #endif | 151 | #endif |
| 151 | } | 152 | } |
| 152 | 153 | ||
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 051107a2c5e2..c5338834ddbd 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #define _ASM_S390_TOPOLOGY_H | 2 | #define _ASM_S390_TOPOLOGY_H |
| 3 | 3 | ||
| 4 | #include <linux/cpumask.h> | 4 | #include <linux/cpumask.h> |
| 5 | #include <asm/sysinfo.h> | ||
| 5 | 6 | ||
| 6 | extern unsigned char cpu_core_id[NR_CPUS]; | 7 | extern unsigned char cpu_core_id[NR_CPUS]; |
| 7 | extern cpumask_t cpu_core_map[NR_CPUS]; | 8 | extern cpumask_t cpu_core_map[NR_CPUS]; |
| @@ -32,6 +33,7 @@ static inline const struct cpumask *cpu_book_mask(unsigned int cpu) | |||
| 32 | 33 | ||
| 33 | int topology_set_cpu_management(int fc); | 34 | int topology_set_cpu_management(int fc); |
| 34 | void topology_schedule_update(void); | 35 | void topology_schedule_update(void); |
| 36 | void store_topology(struct sysinfo_15_1_x *info); | ||
| 35 | 37 | ||
| 36 | #define POLARIZATION_UNKNWN (-1) | 38 | #define POLARIZATION_UNKNWN (-1) |
| 37 | #define POLARIZATION_HRZ (0) | 39 | #define POLARIZATION_HRZ (0) |
