Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mips_kvm_4.11_1' into mips-for-linux-next

MIPS dependencies for KVM

Miscellaneous MIPS architecture changes depended on by the MIPS KVM
changes in the KVM tree.

- Move pgd_alloc() out of header.
- Exports so KVM can access page table management and TLBEX functions.
- Add return errors to protected cache ops.

+116 -54
+1 -15
arch/mips/include/asm/pgalloc.h
··· 43 43 * Initialize a new pgd / pmd table with invalid pointers. 44 44 */ 45 45 extern void pgd_init(unsigned long page); 46 - 47 - static inline pgd_t *pgd_alloc(struct mm_struct *mm) 48 - { 49 - pgd_t *ret, *init; 50 - 51 - ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); 52 - if (ret) { 53 - init = pgd_offset(&init_mm, 0UL); 54 - pgd_init((unsigned long)ret); 55 - memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, 56 - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 57 - } 58 - 59 - return ret; 60 - } 46 + extern pgd_t *pgd_alloc(struct mm_struct *mm); 61 47 62 48 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 63 49 {
+35 -20
arch/mips/include/asm/r4kcache.h
··· 147 147 } 148 148 149 149 #define protected_cache_op(op,addr) \ 150 + ({ \ 151 + int __err = 0; \ 150 152 __asm__ __volatile__( \ 151 153 " .set push \n" \ 152 154 " .set noreorder \n" \ 153 155 " .set "MIPS_ISA_ARCH_LEVEL" \n" \ 154 - "1: cache %0, (%1) \n" \ 156 + "1: cache %1, (%2) \n" \ 155 157 "2: .set pop \n" \ 158 + " .section .fixup,\"ax\" \n" \ 159 + "3: li %0, %3 \n" \ 160 + " j 2b \n" \ 161 + " .previous \n" \ 156 162 " .section __ex_table,\"a\" \n" \ 157 - " "STR(PTR)" 1b, 2b \n" \ 163 + " "STR(PTR)" 1b, 3b \n" \ 158 164 " .previous" \ 159 - : \ 160 - : "i" (op), "r" (addr)) 165 + : "+r" (__err) \ 166 + : "i" (op), "r" (addr), "i" (-EFAULT)); \ 167 + __err; \ 168 + }) 169 + 161 170 162 171 #define protected_cachee_op(op,addr) \ 172 + ({ \ 173 + int __err = 0; \ 163 174 __asm__ __volatile__( \ 164 175 " .set push \n" \ 165 176 " .set noreorder \n" \ 166 177 " .set mips0 \n" \ 167 178 " .set eva \n" \ 168 - "1: cachee %0, (%1) \n" \ 179 + "1: cachee %1, (%2) \n" \ 169 180 "2: .set pop \n" \ 181 + " .section .fixup,\"ax\" \n" \ 182 + "3: li %0, %3 \n" \ 183 + " j 2b \n" \ 184 + " .previous \n" \ 170 185 " .section __ex_table,\"a\" \n" \ 171 - " "STR(PTR)" 1b, 2b \n" \ 186 + " "STR(PTR)" 1b, 3b \n" \ 172 187 " .previous" \ 173 - : \ 174 - : "i" (op), "r" (addr)) 188 + : "+r" (__err) \ 189 + : "i" (op), "r" (addr), "i" (-EFAULT)); \ 190 + __err; \ 191 + }) 175 192 176 193 /* 177 194 * The next two are for badland addresses like signal trampolines. 178 195 */ 179 - static inline void protected_flush_icache_line(unsigned long addr) 196 + static inline int protected_flush_icache_line(unsigned long addr) 180 197 { 181 198 switch (boot_cpu_type()) { 182 199 case CPU_LOONGSON2: 183 - protected_cache_op(Hit_Invalidate_I_Loongson2, addr); 184 - break; 200 + return protected_cache_op(Hit_Invalidate_I_Loongson2, addr); 185 201 186 202 default: 187 203 #ifdef CONFIG_EVA 188 - protected_cachee_op(Hit_Invalidate_I, addr); 204 + return protected_cachee_op(Hit_Invalidate_I, addr); 189 205 #else 190 - protected_cache_op(Hit_Invalidate_I, addr); 206 + return protected_cache_op(Hit_Invalidate_I, addr); 191 207 #endif 192 - break; 193 208 } 194 209 } 195 210 ··· 214 199 * caches. We're talking about one cacheline unnecessarily getting invalidated 215 200 * here so the penalty isn't overly hard. 216 201 */ 217 - static inline void protected_writeback_dcache_line(unsigned long addr) 202 + static inline int protected_writeback_dcache_line(unsigned long addr) 218 203 { 219 204 #ifdef CONFIG_EVA 220 - protected_cachee_op(Hit_Writeback_Inv_D, addr); 205 + return protected_cachee_op(Hit_Writeback_Inv_D, addr); 221 206 #else 222 - protected_cache_op(Hit_Writeback_Inv_D, addr); 207 + return protected_cache_op(Hit_Writeback_Inv_D, addr); 223 208 #endif 224 209 } 225 210 226 - static inline void protected_writeback_scache_line(unsigned long addr) 211 + static inline int protected_writeback_scache_line(unsigned long addr) 227 212 { 228 213 #ifdef CONFIG_EVA 229 - protected_cachee_op(Hit_Writeback_Inv_SD, addr); 214 + return protected_cachee_op(Hit_Writeback_Inv_SD, addr); 230 215 #else 231 - protected_cache_op(Hit_Writeback_Inv_SD, addr); 216 + return protected_cache_op(Hit_Writeback_Inv_SD, addr); 232 217 #endif 233 218 } 234 219
+26
arch/mips/include/asm/tlbex.h
··· 1 + #ifndef __ASM_TLBEX_H 2 + #define __ASM_TLBEX_H 3 + 4 + #include <asm/uasm.h> 5 + 6 + /* 7 + * Write random or indexed TLB entry, and care about the hazards from 8 + * the preceding mtc0 and for the following eret. 9 + */ 10 + enum tlb_write_entry { 11 + tlb_random, 12 + tlb_indexed 13 + }; 14 + 15 + extern int pgd_reg; 16 + 17 + void build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, 18 + unsigned int tmp, unsigned int ptr); 19 + void build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr); 20 + void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr); 21 + void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep); 22 + void build_tlb_write_entry(u32 **p, struct uasm_label **l, 23 + struct uasm_reloc **r, 24 + enum tlb_write_entry wmode); 25 + 26 + #endif /* __ASM_TLBEX_H */
+5
arch/mips/include/asm/uasm.h
··· 9 9 * Copyright (C) 2012, 2013 MIPS Technologies, Inc. All rights reserved. 10 10 */ 11 11 12 + #ifndef __ASM_UASM_H 13 + #define __ASM_UASM_H 14 + 12 15 #include <linux/types.h> 13 16 14 17 #ifdef CONFIG_EXPORT_UASM ··· 312 309 void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1, 313 310 unsigned int reg2, int lid); 314 311 void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); 312 + 313 + #endif /* __ASM_UASM_H */
+1 -1
arch/mips/mm/Makefile
··· 4 4 5 5 obj-y += cache.o dma-default.o extable.o fault.o \ 6 6 gup.o init.o mmap.o page.o page-funcs.o \ 7 - tlbex.o tlbex-fault.o tlb-funcs.o 7 + pgtable.o tlbex.o tlbex-fault.o tlb-funcs.o 8 8 9 9 ifdef CONFIG_CPU_MICROMIPS 10 10 obj-y += uasm-micromips.o
+1
arch/mips/mm/init.c
··· 539 539 pgd_t swapper_pg_dir[_PTRS_PER_PGD] __section(.bss..swapper_pg_dir); 540 540 #ifndef __PAGETABLE_PMD_FOLDED 541 541 pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned_bss; 542 + EXPORT_SYMBOL_GPL(invalid_pmd_table); 542 543 #endif 543 544 pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss; 544 545 EXPORT_SYMBOL(invalid_pte_table);
+2
arch/mips/mm/pgtable-64.c
··· 6 6 * Copyright (C) 1999, 2000 by Silicon Graphics 7 7 * Copyright (C) 2003 by Ralf Baechle 8 8 */ 9 + #include <linux/export.h> 9 10 #include <linux/init.h> 10 11 #include <linux/mm.h> 11 12 #include <asm/fixmap.h> ··· 61 60 p[-1] = pagetable; 62 61 } while (p != end); 63 62 } 63 + EXPORT_SYMBOL_GPL(pmd_init); 64 64 #endif 65 65 66 66 pmd_t mk_pmd(struct page *page, pgprot_t prot)
+25
arch/mips/mm/pgtable.c
··· 1 + /* 2 + * This file is subject to the terms and conditions of the GNU General Public 3 + * License. See the file "COPYING" in the main directory of this archive 4 + * for more details. 5 + */ 6 + #include <linux/export.h> 7 + #include <linux/mm.h> 8 + #include <linux/string.h> 9 + #include <asm/pgalloc.h> 10 + 11 + pgd_t *pgd_alloc(struct mm_struct *mm) 12 + { 13 + pgd_t *ret, *init; 14 + 15 + ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); 16 + if (ret) { 17 + init = pgd_offset(&init_mm, 0UL); 18 + pgd_init((unsigned long)ret); 19 + memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, 20 + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 21 + } 22 + 23 + return ret; 24 + } 25 + EXPORT_SYMBOL_GPL(pgd_alloc);
+20 -18
arch/mips/mm/tlbex.c
··· 22 22 */ 23 23 24 24 #include <linux/bug.h> 25 + #include <linux/export.h> 25 26 #include <linux/kernel.h> 26 27 #include <linux/types.h> 27 28 #include <linux/smp.h> ··· 35 34 #include <asm/war.h> 36 35 #include <asm/uasm.h> 37 36 #include <asm/setup.h> 37 + #include <asm/tlbex.h> 38 38 39 39 static int mips_xpa_disabled; 40 40 ··· 346 344 } 347 345 348 346 static int scratch_reg; 349 - static int pgd_reg; 347 + int pgd_reg; 348 + EXPORT_SYMBOL_GPL(pgd_reg); 350 349 enum vmalloc64_mode {not_refill, refill_scratch, refill_noscratch}; 351 350 352 351 static struct work_registers build_get_work_registers(u32 **p) ··· 499 496 } 500 497 } 501 498 502 - /* 503 - * Write random or indexed TLB entry, and care about the hazards from 504 - * the preceding mtc0 and for the following eret. 505 - */ 506 - enum tlb_write_entry { tlb_random, tlb_indexed }; 507 - 508 - static void build_tlb_write_entry(u32 **p, struct uasm_label **l, 509 - struct uasm_reloc **r, 510 - enum tlb_write_entry wmode) 499 + void build_tlb_write_entry(u32 **p, struct uasm_label **l, 500 + struct uasm_reloc **r, 501 + enum tlb_write_entry wmode) 511 502 { 512 503 void(*tlbw)(u32 **) = NULL; 513 504 ··· 624 627 break; 625 628 } 626 629 } 630 + EXPORT_SYMBOL_GPL(build_tlb_write_entry); 627 631 628 632 static __maybe_unused void build_convert_pte_to_entrylo(u32 **p, 629 633 unsigned int reg) ··· 779 781 * TMP and PTR are scratch. 780 782 * TMP will be clobbered, PTR will hold the pmd entry. 781 783 */ 782 - static void 783 - build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, 784 - unsigned int tmp, unsigned int ptr) 784 + void build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, 785 + unsigned int tmp, unsigned int ptr) 785 786 { 786 787 #ifndef CONFIG_MIPS_PGD_C0_CONTEXT 787 788 long pgdc = (long)pgd_current; ··· 856 859 uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */ 857 860 #endif 858 861 } 862 + EXPORT_SYMBOL_GPL(build_get_pmde64); 859 863 860 864 /* 861 865 * BVADDR is the faulting address, PTR is scratch. ··· 932 934 * TMP and PTR are scratch. 933 935 * TMP will be clobbered, PTR will hold the pgd entry. 934 936 */ 935 - static void __maybe_unused 936 - build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) 937 + void build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) 937 938 { 938 939 if (pgd_reg != -1) { 939 940 /* pgd is in pgd_reg */ ··· 957 960 uasm_i_sll(p, tmp, tmp, PGD_T_LOG2); 958 961 uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */ 959 962 } 963 + EXPORT_SYMBOL_GPL(build_get_pgde32); 960 964 961 965 #endif /* !CONFIG_64BIT */ 962 966 ··· 987 989 uasm_i_andi(p, ctx, ctx, mask); 988 990 } 989 991 990 - static void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) 992 + void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) 991 993 { 992 994 /* 993 995 * Bug workaround for the Nevada. It seems as if under certain ··· 1011 1013 build_adjust_context(p, tmp); 1012 1014 UASM_i_ADDU(p, ptr, ptr, tmp); /* add in offset */ 1013 1015 } 1016 + EXPORT_SYMBOL_GPL(build_get_ptep); 1014 1017 1015 - static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) 1018 + void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) 1016 1019 { 1017 1020 int pte_off_even = 0; 1018 1021 int pte_off_odd = sizeof(pte_t); ··· 1062 1063 UASM_i_MTC0(p, 0, C0_ENTRYLO1); 1063 1064 UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */ 1064 1065 } 1066 + EXPORT_SYMBOL_GPL(build_update_entries); 1065 1067 1066 1068 struct mips_huge_tlb_info { 1067 1069 int huge_pte; ··· 1536 1536 extern u32 handle_tlbl[], handle_tlbl_end[]; 1537 1537 extern u32 handle_tlbs[], handle_tlbs_end[]; 1538 1538 extern u32 handle_tlbm[], handle_tlbm_end[]; 1539 - extern u32 tlbmiss_handler_setup_pgd_start[], tlbmiss_handler_setup_pgd[]; 1539 + extern u32 tlbmiss_handler_setup_pgd_start[]; 1540 + extern u32 tlbmiss_handler_setup_pgd[]; 1541 + EXPORT_SYMBOL_GPL(tlbmiss_handler_setup_pgd); 1540 1542 extern u32 tlbmiss_handler_setup_pgd_end[]; 1541 1543 1542 1544 static void build_setup_pgd(void)