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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'fixes-3.9-late' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull late parisc fixes from Helge Deller:
"I know it's *very* late in the 3.9 release cycle, but since there
aren't that many people testing the parisc linux kernel, a few (for
our port) critical issues just showed up a few days back for the first
time.

What's in it?
- add missing __ucmpdi2 symbol, which is required for btrfs on 32bit
kernel.
- change kunmap() macro to static inline function. This fixes a
debian/gcc-4.4 build error.
- add locking when doing PTE updates. This fixes random userspace
crashes.
- disable (optional) -mlong-calls compiler option for modules, else
modules can't be loaded at runtime.
- a smart patch by Will Deacon which fixes 64bit put_user() warnings
on 32bit kernel."

* 'fixes-3.9-late' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
parisc: use spin_lock_irqsave/spin_unlock_irqrestore for PTE updates
parisc: disable -mlong-calls compiler option for kernel modules
parisc: uaccess: fix compiler warnings caused by __put_user casting
parisc: Change kunmap macro to static inline function
parisc: Provide __ucmpdi2 to resolve undefined references in 32 bit builds.

+69 -42
+4 -2
arch/parisc/Makefile
··· 65 65 endif 66 66 67 67 # Use long jumps instead of long branches (needed if your linker fails to 68 - # link a too big vmlinux executable) 69 - cflags-$(CONFIG_MLONGCALLS) += -mlong-calls 68 + # link a too big vmlinux executable). Not enabled for building modules. 69 + ifdef CONFIG_MLONGCALLS 70 + KBUILD_CFLAGS_KERNEL += -mlong-calls 71 + endif 70 72 71 73 # select which processor to optimise for 72 74 cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100
+4 -1
arch/parisc/include/asm/cacheflush.h
··· 140 140 return page_address(page); 141 141 } 142 142 143 - #define kunmap(page) kunmap_parisc(page_address(page)) 143 + static inline void kunmap(struct page *page) 144 + { 145 + kunmap_parisc(page_address(page)); 146 + } 144 147 145 148 static inline void *kmap_atomic(struct page *page) 146 149 {
+27 -24
arch/parisc/include/asm/pgtable.h
··· 16 16 #include <asm/processor.h> 17 17 #include <asm/cache.h> 18 18 19 + extern spinlock_t pa_dbit_lock; 20 + 19 21 /* 20 22 * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel 21 23 * memory. For the return value to be meaningful, ADDR must be >= ··· 46 44 47 45 #define set_pte_at(mm, addr, ptep, pteval) \ 48 46 do { \ 47 + unsigned long flags; \ 48 + spin_lock_irqsave(&pa_dbit_lock, flags); \ 49 49 set_pte(ptep, pteval); \ 50 50 purge_tlb_entries(mm, addr); \ 51 + spin_unlock_irqrestore(&pa_dbit_lock, flags); \ 51 52 } while (0) 52 53 53 54 #endif /* !__ASSEMBLY__ */ ··· 440 435 441 436 static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) 442 437 { 443 - #ifdef CONFIG_SMP 438 + pte_t pte; 439 + unsigned long flags; 440 + 444 441 if (!pte_young(*ptep)) 445 442 return 0; 446 - return test_and_clear_bit(xlate_pabit(_PAGE_ACCESSED_BIT), &pte_val(*ptep)); 447 - #else 448 - pte_t pte = *ptep; 449 - if (!pte_young(pte)) 450 - return 0; 451 - set_pte_at(vma->vm_mm, addr, ptep, pte_mkold(pte)); 452 - return 1; 453 - #endif 454 - } 455 443 456 - extern spinlock_t pa_dbit_lock; 444 + spin_lock_irqsave(&pa_dbit_lock, flags); 445 + pte = *ptep; 446 + if (!pte_young(pte)) { 447 + spin_unlock_irqrestore(&pa_dbit_lock, flags); 448 + return 0; 449 + } 450 + set_pte(ptep, pte_mkold(pte)); 451 + purge_tlb_entries(vma->vm_mm, addr); 452 + spin_unlock_irqrestore(&pa_dbit_lock, flags); 453 + return 1; 454 + } 457 455 458 456 struct mm_struct; 459 457 static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 460 458 { 461 459 pte_t old_pte; 460 + unsigned long flags; 462 461 463 - spin_lock(&pa_dbit_lock); 462 + spin_lock_irqsave(&pa_dbit_lock, flags); 464 463 old_pte = *ptep; 465 464 pte_clear(mm,addr,ptep); 466 - spin_unlock(&pa_dbit_lock); 465 + purge_tlb_entries(mm, addr); 466 + spin_unlock_irqrestore(&pa_dbit_lock, flags); 467 467 468 468 return old_pte; 469 469 } 470 470 471 471 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 472 472 { 473 - #ifdef CONFIG_SMP 474 - unsigned long new, old; 475 - 476 - do { 477 - old = pte_val(*ptep); 478 - new = pte_val(pte_wrprotect(__pte (old))); 479 - } while (cmpxchg((unsigned long *) ptep, old, new) != old); 473 + unsigned long flags; 474 + spin_lock_irqsave(&pa_dbit_lock, flags); 475 + set_pte(ptep, pte_wrprotect(*ptep)); 480 476 purge_tlb_entries(mm, addr); 481 - #else 482 - pte_t old_pte = *ptep; 483 - set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); 484 - #endif 477 + spin_unlock_irqrestore(&pa_dbit_lock, flags); 485 478 } 486 479 487 480 #define pte_same(A,B) (pte_val(A) == pte_val(B))
+4 -10
arch/parisc/include/asm/uaccess.h
··· 181 181 #if !defined(CONFIG_64BIT) 182 182 183 183 #define __put_kernel_asm64(__val,ptr) do { \ 184 - u64 __val64 = (u64)(__val); \ 185 - u32 hi = (__val64) >> 32; \ 186 - u32 lo = (__val64) & 0xffffffff; \ 187 184 __asm__ __volatile__ ( \ 188 185 "\n1:\tstw %2,0(%1)" \ 189 - "\n2:\tstw %3,4(%1)\n\t" \ 186 + "\n2:\tstw %R2,4(%1)\n\t" \ 190 187 ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ 191 188 ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ 192 189 : "=r"(__pu_err) \ 193 - : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \ 190 + : "r"(ptr), "r"(__val), "0"(__pu_err) \ 194 191 : "r1"); \ 195 192 } while (0) 196 193 197 194 #define __put_user_asm64(__val,ptr) do { \ 198 - u64 __val64 = (u64)(__val); \ 199 - u32 hi = (__val64) >> 32; \ 200 - u32 lo = (__val64) & 0xffffffff; \ 201 195 __asm__ __volatile__ ( \ 202 196 "\n1:\tstw %2,0(%%sr3,%1)" \ 203 - "\n2:\tstw %3,4(%%sr3,%1)\n\t" \ 197 + "\n2:\tstw %R2,4(%%sr3,%1)\n\t" \ 204 198 ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ 205 199 ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ 206 200 : "=r"(__pu_err) \ 207 - : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \ 201 + : "r"(ptr), "r"(__val), "0"(__pu_err) \ 208 202 : "r1"); \ 209 203 } while (0) 210 204
+1 -4
arch/parisc/kernel/cache.c
··· 421 421 /* Note: purge_tlb_entries can be called at startup with 422 422 no context. */ 423 423 424 - /* Disable preemption while we play with %sr1. */ 425 - preempt_disable(); 426 - mtsp(mm->context, 1); 427 424 purge_tlb_start(flags); 425 + mtsp(mm->context, 1); 428 426 pdtlb(addr); 429 427 pitlb(addr); 430 428 purge_tlb_end(flags); 431 - preempt_enable(); 432 429 } 433 430 EXPORT_SYMBOL(purge_tlb_entries); 434 431
+2
arch/parisc/kernel/parisc_ksyms.c
··· 120 120 extern void __ashldi3(void); 121 121 extern void __lshrdi3(void); 122 122 extern void __muldi3(void); 123 + extern void __ucmpdi2(void); 123 124 124 125 EXPORT_SYMBOL(__ashrdi3); 125 126 EXPORT_SYMBOL(__ashldi3); 126 127 EXPORT_SYMBOL(__lshrdi3); 127 128 EXPORT_SYMBOL(__muldi3); 129 + EXPORT_SYMBOL(__ucmpdi2); 128 130 129 131 asmlinkage void * __canonicalize_funcptr_for_compare(void *); 130 132 EXPORT_SYMBOL(__canonicalize_funcptr_for_compare);
+2 -1
arch/parisc/lib/Makefile
··· 2 2 # Makefile for parisc-specific library files 3 3 # 4 4 5 - lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o 5 + lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o \ 6 + ucmpdi2.o 6 7 7 8 obj-y := iomap.o
+25
arch/parisc/lib/ucmpdi2.c
··· 1 + #include <linux/module.h> 2 + 3 + union ull_union { 4 + unsigned long long ull; 5 + struct { 6 + unsigned int high; 7 + unsigned int low; 8 + } ui; 9 + }; 10 + 11 + int __ucmpdi2(unsigned long long a, unsigned long long b) 12 + { 13 + union ull_union au = {.ull = a}; 14 + union ull_union bu = {.ull = b}; 15 + 16 + if (au.ui.high < bu.ui.high) 17 + return 0; 18 + else if (au.ui.high > bu.ui.high) 19 + return 2; 20 + if (au.ui.low < bu.ui.low) 21 + return 0; 22 + else if (au.ui.low > bu.ui.low) 23 + return 2; 24 + return 1; 25 + }