diff options
30 files changed, 337 insertions, 284 deletions
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile index c9ac5f5fa9e..532e7ef1edb 100644 --- a/arch/ppc/boot/images/Makefile +++ b/arch/ppc/boot/images/Makefile @@ -6,12 +6,17 @@ MKIMAGE := $(srctree)/scripts/mkuboot.sh extra-y := vmlinux.bin vmlinux.gz +# two make processes may write to vmlinux.gz at the same time with make -j +quiet_cmd_mygzip = GZIP $@ +cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@ + + OBJCOPYFLAGS_vmlinux.bin := -O binary $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE - $(call if_changed,gzip) + $(call if_changed,mygzip) quiet_cmd_uimage = UIMAGE $@ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \ diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/ppc64/kernel/cpu_setup_power4.S index 42fc08cf87a..0482c063c26 100644 --- a/arch/ppc64/kernel/cpu_setup_power4.S +++ b/arch/ppc64/kernel/cpu_setup_power4.S @@ -31,10 +31,13 @@ _GLOBAL(__970_cpu_preinit) */ mfspr r0,SPRN_PVR srwi r0,r0,16 - cmpwi cr0,r0,0x39 - cmpwi cr1,r0,0x3c - cror 4*cr0+eq,4*cr0+eq,4*cr1+eq + cmpwi r0,0x39 + beq 1f + cmpwi r0,0x3c + beq 1f + cmpwi r0,0x44 bnelr +1: /* Make sure HID4:rm_ci is off before MMU is turned off, that large * pages are enabled with HID4:61 and clear HID5:DCBZ_size and @@ -133,12 +136,14 @@ _GLOBAL(__save_cpu_setup) /* We only deal with 970 for now */ mfspr r0,SPRN_PVR srwi r0,r0,16 - cmpwi cr0,r0,0x39 - cmpwi cr1,r0,0x3c - cror 4*cr0+eq,4*cr0+eq,4*cr1+eq - bne 1f - - /* Save HID0,1,4 and 5 */ + cmpwi r0,0x39 + beq 1f + cmpwi r0,0x3c + beq 1f + cmpwi r0,0x44 + bne 2f + +1: /* Save HID0,1,4 and 5 */ mfspr r3,SPRN_HID0 std r3,CS_HID0(r5) mfspr r3,SPRN_HID1 @@ -148,7 +153,7 @@ _GLOBAL(__save_cpu_setup) mfspr r3,SPRN_HID5 std r3,CS_HID5(r5) -1: +2: mtcr r7 blr @@ -165,12 +170,14 @@ _GLOBAL(__restore_cpu_setup) /* We only deal with 970 for now */ mfspr r0,SPRN_PVR srwi r0,r0,16 - cmpwi cr0,r0,0x39 - cmpwi cr1,r0,0x3c - cror 4*cr0+eq,4*cr0+eq,4*cr1+eq - bne 1f + cmpwi r0,0x39 + beq 1f + cmpwi r0,0x3c + beq 1f + cmpwi r0,0x44 + bnelr - /* Before accessing memory, we make sure rm_ci is clear */ +1: /* Before accessing memory, we make sure rm_ci is clear */ li r0,0 mfspr r3,SPRN_HID4 rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ @@ -223,6 +230,5 @@ _GLOBAL(__restore_cpu_setup) mtspr SPRN_HID5,r3 sync isync -1: blr diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c index 8d4c46f6f0b..77cec42f952 100644 --- a/arch/ppc64/kernel/cputable.c +++ b/arch/ppc64/kernel/cputable.c @@ -183,6 +183,21 @@ struct cpu_spec cpu_specs[] = { .cpu_setup = __setup_cpu_ppc970, .firmware_features = COMMON_PPC64_FW, }, + { /* PPC970MP */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00440000, + .cpu_name = "PPC970MP", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, + .cpu_user_features = COMMON_USER_PPC64 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_ppc970, + .firmware_features = COMMON_PPC64_FW, + }, { /* Power5 */ .pvr_mask = 0xffff0000, .pvr_value = 0x003a0000, diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/ppc64/kernel/iSeries_htab.c index aa9e8fdd1a4..b0250ae4a72 100644 --- a/arch/ppc64/kernel/iSeries_htab.c +++ b/arch/ppc64/kernel/iSeries_htab.c @@ -38,11 +38,12 @@ static inline void iSeries_hunlock(unsigned long slot) } static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, - unsigned long prpn, int secondary, - unsigned long hpteflags, int bolted, int large) + unsigned long prpn, unsigned long vflags, + unsigned long rflags) { long slot; - HPTE lhpte; + hpte_t lhpte; + int secondary = 0; /* * The hypervisor tries both primary and secondary. @@ -50,13 +51,13 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, * it means we have already tried both primary and secondary, * so we return failure immediately. */ - if (secondary) + if (vflags & HPTE_V_SECONDARY) return -1; iSeries_hlock(hpte_group); slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT); - BUG_ON(lhpte.dw0.dw0.v); + BUG_ON(lhpte.v & HPTE_V_VALID); if (slot == -1) { /* No available entry found in either group */ iSeries_hunlock(hpte_group); @@ -64,19 +65,13 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, } if (slot < 0) { /* MSB set means secondary group */ + vflags |= HPTE_V_VALID; secondary = 1; slot &= 0x7fffffffffffffff; } - lhpte.dw1.dword1 = 0; - lhpte.dw1.dw1.rpn = physRpn_to_absRpn(prpn); - lhpte.dw1.flags.flags = hpteflags; - - lhpte.dw0.dword0 = 0; - lhpte.dw0.dw0.avpn = va >> 23; - lhpte.dw0.dw0.h = secondary; - lhpte.dw0.dw0.bolted = bolted; - lhpte.dw0.dw0.v = 1; + lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID; + lhpte.r = (physRpn_to_absRpn(prpn) << HPTE_R_RPN_SHIFT) | rflags; /* Now fill in the actual HPTE */ HvCallHpt_addValidate(slot, secondary, &lhpte); @@ -88,20 +83,17 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, static unsigned long iSeries_hpte_getword0(unsigned long slot) { - unsigned long dword0; - HPTE hpte; + hpte_t hpte; HvCallHpt_get(&hpte, slot); - dword0 = hpte.dw0.dword0; - - return dword0; + return hpte.v; } static long iSeries_hpte_remove(unsigned long hpte_group) { unsigned long slot_offset; int i; - HPTE lhpte; + unsigned long hpte_v; /* Pick a random slot to start at */ slot_offset = mftb() & 0x7; @@ -109,10 +101,9 @@ static long iSeries_hpte_remove(unsigned long hpte_group) iSeries_hlock(hpte_group); for (i = 0; i < HPTES_PER_GROUP; i++) { - lhpte.dw0.dword0 = - iSeries_hpte_getword0(hpte_group + slot_offset); + hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset); - if (!lhpte.dw0.dw0.bolted) { + if (! (hpte_v & HPTE_V_BOLTED)) { HvCallHpt_invalidateSetSwBitsGet(hpte_group + slot_offset, 0, 0); iSeries_hunlock(hpte_group); @@ -137,13 +128,13 @@ static long iSeries_hpte_remove(unsigned long hpte_group) static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, unsigned long va, int large, int local) { - HPTE hpte; + hpte_t hpte; unsigned long avpn = va >> 23; iSeries_hlock(slot); HvCallHpt_get(&hpte, slot); - if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) { + if ((HPTE_V_AVPN_VAL(hpte.v) == avpn) && (hpte.v & HPTE_V_VALID)) { /* * Hypervisor expects bits as NPPP, which is * different from how they are mapped in our PP. @@ -167,7 +158,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, */ static long iSeries_hpte_find(unsigned long vpn) { - HPTE hpte; + hpte_t hpte; long slot; /* @@ -177,7 +168,7 @@ static long iSeries_hpte_find(unsigned long vpn) * 0x80000000xxxxxxxx : Entry found in secondary group, slot x */ slot = HvCallHpt_findValid(&hpte, vpn); - if (hpte.dw0.dw0.v) { + if (hpte.v & HPTE_V_VALID) { if (slot < 0) { slot &= 0x7fffffffffffffff; slot = -slot; @@ -212,7 +203,7 @@ static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea) static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, int large, int local) { - HPTE lhpte; + unsigned long hpte_v; unsigned long avpn = va >> 23; unsigned long flags; @@ -220,9 +211,9 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, iSeries_hlock(slot); - lhpte.dw0.dword0 = iSeries_hpte_getword0(slot); + hpte_v = iSeries_hpte_getword0(slot); - if ((lhpte.dw0.dw0.avpn == avpn) && lhpte.dw0.dw0.v) + if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID)) HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0); iSeries_hunlock(slot); diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 077c82fc9f3..a649edbb23b 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -503,7 +503,7 @@ static void __init build_iSeries_Memory_Map(void) /* Fill in the hashed page table hash mask */ num_ptegs = hptSizePages * - (PAGE_SIZE / (sizeof(HPTE) * HPTES_PER_GROUP)); + (PAGE_SIZE / (sizeof(hpte_t) * HPTES_PER_GROUP)); htab_hash_mask = num_ptegs - 1; /* @@ -618,25 +618,23 @@ static void __init setup_iSeries_cache_sizes(void) static void iSeries_make_pte(unsigned long va, unsigned long pa, int mode) { - HPTE local_hpte, rhpte; + hpte_t local_hpte, rhpte; unsigned long hash, vpn; long slot; vpn = va >> PAGE_SHIFT; hash = hpt_hash(vpn, 0); - local_hpte.dw1.dword1 = pa | mode; - local_hpte.dw0.dword0 = 0; - local_hpte.dw0.dw0.avpn = va >> 23; - local_hpte.dw0.dw0.bolted = 1; /* bolted */ - local_hpte.dw0.dw0.v = 1; + local_hpte.r = pa | mode; + local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT) + | HPTE_V_BOLTED | HPTE_V_VALID; slot = HvCallHpt_findValid(&rhpte, vpn); if (slot < 0) { /* Must find space in primary group */ panic("hash_page: hpte already exists\n"); } - HvCallHpt_addValidate(slot, 0, (HPTE *)&local_hpte ); + HvCallHpt_addValidate(slot, 0, &local_hpte); } /* @@ -646,7 +644,7 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) { unsigned long pa; unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX; - HPTE hpte; + hpte_t hpte; for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) { unsigned long ea = (unsigned long)__va(pa); @@ -659,7 +657,7 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) if (!in_kernel_text(ea)) mode_rw |= HW_NO_EXEC; - if (hpte.dw0.dw0.v) { + if (hpte.v & HPTE_V_VALID) { /* HPTE exists, so just bolt it */ HvCallHpt_setSwBits(slot, 0x10, 0); /* And make sure the pp bits are correct */ diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c index 6534812db43..74dd144dcce 100644 --- a/arch/ppc64/kernel/pSeries_lpar.c +++ b/arch/ppc64/kernel/pSeries_lpar.c @@ -277,31 +277,20 @@ void vpa_init(int cpu) long pSeries_lpar_hpte_insert(unsigned long hpte_group, unsigned long va, unsigned long prpn, - int secondary, unsigned long hpteflags, - int bolted, int large) + unsigned long vflags, unsigned long rflags) { unsigned long arpn = physRpn_to_absRpn(prpn); unsigned long lpar_rc; unsigned long flags; unsigned long slot; - HPTE lhpte; + unsigned long hpte_v, hpte_r; unsigned long dummy0, dummy1; - /* Fill in the local HPTE with absolute rpn, avpn and flags */ - lhpte.dw1.dword1 = 0; - lhpte.dw1.dw1.rpn = arpn; - lhpte.dw1.flags.flags = hpteflags; + hpte_v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | vflags | HPTE_V_VALID; + if (vflags & HPTE_V_LARGE) + hpte_v &= ~(1UL << HPTE_V_AVPN_SHIFT); - lhpte.dw0.dword0 = 0; - lhpte.dw0.dw0.avpn = va >> 23; - lhpte.dw0.dw0.h = secondary; - lhpte.dw0.dw0.bolted = bolted; - lhpte.dw0.dw0.v = 1; - - if (large) { - lhpte.dw0.dw0.l = 1; - lhpte.dw0.dw0.avpn &= ~0x1UL; - } + hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags; /* Now fill in the actual HPTE */ /* Set CEC cookie to 0 */ @@ -312,11 +301,11 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group, flags = 0; /* XXX why is this here? - Anton */ - if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) - lhpte.dw1.flags.flags &= ~_PAGE_COHERENT; + if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) + hpte_r &= ~_PAGE_COHERENT; - lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, lhpte.dw0.dword0, - lhpte.dw1.dword1, &slot, &dummy0, &dummy1); + lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v, + hpte_r, &slot, &dummy0, &dummy1); if (unlikely(lpar_rc == H_PTEG_Full)) return -1; @@ -332,7 +321,7 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group, /* Because of iSeries, we have to pass down the secondary * bucket bit here as well */ - return (slot & 7) | (secondary << 3); + return (slot & 7) | (!!(vflags & HPTE_V_SECONDARY) << 3); } static DEFINE_SPINLOCK(pSeries_lpar_tlbie_lock); @@ -427,22 +416,18 @@ static long pSeries_lpar_hpte_find(unsigned long vpn) unsigned long hash; unsigned long i, j; long slot; - union { - unsigned long dword0; - Hpte_dword0 dw0; - } hpte_dw0; - Hpte_dword0 dw0; + unsigned long hpte_v; hash = hpt_hash(vpn, 0); for (j = 0; j < 2; j++) { slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; for (i = 0; i < HPTES_PER_GROUP; i++) { - hpte_dw0.dword0 = pSeries_lpar_hpte_getword0(slot); - dw0 = hpte_dw0.dw0; + hpte_v = pSeries_lpar_hpte_getword0(slot); - if ((dw0.avpn == (vpn >> 11)) && dw0.v && - (dw0.h == j)) { + if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11)) + && (hpte_v & HPTE_V_VALID) + && (!!(hpte_v & HPTE_V_SECONDARY) == j)) { /* HPTE matches */ if (j) slot = -slot; diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S index c23d46956dd..fbff24827ae 100644 --- a/arch/ppc64/mm/hash_low.S +++ b/arch/ppc64/mm/hash_low.S @@ -170,9 +170,7 @@ htab_insert_pte: /* Call ppc_md.hpte_insert */ ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */ mr r4,r29 /* Retreive va */ - li r6,0 /* primary slot */ - li r8,0 /* not bolted and not large */ - li r9,0 + li r6,0 /* no vflags */ _GLOBAL(htab_call_hpte_insert1) bl . /* Will be patched by htab_finish_init() */ cmpdi 0,r3,0 @@ -192,9 +190,7 @@ _GLOBAL(htab_call_hpte_insert1) /* Call ppc_md.hpte_insert */ ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */ mr r4,r29 /* Retreive va */ - li r6,1 /* secondary slot */ - li r8,0 /* not bolted and not large */ - li r9,0 + li r6,HPTE_V_SECONDARY@l /* secondary slot */ _GLOBAL(htab_call_hpte_insert2) bl . /* Will be patched by htab_finish_init() */ cmpdi 0,r3,0 diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 4fec05817d6..a6abd3a979b 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c @@ -27,9 +27,9 @@ static DEFINE_SPINLOCK(native_tlbie_lock); -static inline void native_lock_hpte(HPTE *hptep) +static inline void native_lock_hpte(hpte_t *hptep) { - unsigned long *word = &hptep->dw0.dword0; + unsigned long *word = &hptep->v; while (1) { if (!test_and_set_bit(HPTE_LOCK_BIT, word)) @@ -39,32 +39,28 @@ static inline void native_lock_hpte(HPTE *hptep) } } -static inline void native_unlock_hpte(HPTE *hptep) +static inline void native_unlock_hpte(hpte_t *hptep) { - unsigned long *word = &hptep->dw0.dword0; + unsigned long *word = &hptep->v; asm volatile("lwsync":::"memory"); clear_bit(HPTE_LOCK_BIT, word); } long native_hpte_insert(unsigned long hpte_group, unsigned long va, - unsigned long prpn, int secondary, - unsigned long hpteflags, int bolted, int large) + unsigned long prpn, unsigned long vflags, + unsigned long rflags) { unsigned long arpn = physRpn_to_absRpn(prpn); - HPTE *hptep = htab_address + hpte_group; - Hpte_dword0 dw0; - HPTE lhpte; + hpte_t *hptep = htab_address + hpte_group; + unsigned long hpte_v, hpte_r; int i; for (i = 0; i < HPTES_PER_GROUP; i++) { - dw0 = hptep->dw0.dw0; - - if (!dw0.v) { + if (! (hptep->v & HPTE_V_VALID)) { /* retry with lock held */ native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; - if (!dw0.v) + if (! (hptep->v & HPTE_V_VALID)) break; native_unlock_hpte(hptep); } @@ -75,56 +71,45 @@ long native_hpte_insert(unsigned long hpte_group, unsigned long va, if (i == HPTES_PER_GROUP) return -1; - lhpte.dw1.dword1 = 0; - lhpte.dw1.dw1.rpn = arpn; - lhpte.dw1.flags.flags = hpteflags; - - lhpte.dw0.dword0 = 0; - lhpte.dw0.dw0.avpn = va >> 23; - lhpte.dw0.dw0.h = secondary; - lhpte.dw0.dw0.bolted = bolted; - lhpte.dw0.dw0.v = 1; - - if (large) { - lhpte.dw0.dw0.l = 1; - lhpte.dw0.dw0.avpn &= ~0x1UL; - } - - hptep->dw1.dword1 = lhpte.dw1.dword1; + hpte_v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID; + if (vflags & HPTE_V_LARGE) + va &= ~(1UL << HPTE_V_AVPN_SHIFT); + hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags; + hptep->r = hpte_r; /* Guarantee the second dword is visible before the valid bit */ __asm__ __volatile__ ("eieio" : : : "memory"); - /* * Now set the first dword including the valid bit * NOTE: this also unlocks the hpte */ - hptep->dw0.dword0 = lhpte.dw0.dword0; + hptep->v = hpte_v; __asm__ __volatile__ ("ptesync" : : : "memory"); - return i | (secondary << 3); + return i | (!!(vflags & HPTE_V_SECONDARY) << 3); } static long native_hpte_remove(unsigned long hpte_group) { - HPTE *hptep; - Hpte_dword0 dw0; + hpte_t *hptep; int i; int slot_offset; + unsigned long hpte_v; /* pick a random entry to start at */ slot_offset = mftb() & 0x7; for (i = 0; i < HPTES_PER_GROUP; i++) { hptep = htab_address + hpte_group + slot_offset; - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; - if (dw0.v && !dw0.bolted) { + if ((hpte_v & HPTE_V_VALID) && !(hpte_v & HPTE_V_BOLTED)) { /* retry with lock held */ native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; - if (dw0.v && !dw0.bolted) + hpte_v = hptep->v; + if ((hpte_v & HPTE_V_VALID) + && !(hpte_v & HPTE_V_BOLTED)) break; native_unlock_hpte(hptep); } @@ -137,15 +122,15 @@ static long native_hpte_remove(unsigned long hpte_group) return -1; /* Invalidate the hpte. NOTE: this also unlocks it */ - hptep->dw0.dword0 = 0; + hptep->v = 0; return i; } -static inline void set_pp_bit(unsigned long pp, HPTE *addr) +static inline void set_pp_bit(unsigned long pp, hpte_t *addr) { unsigned long old; - unsigned long *p = &addr->dw1.dword1; + unsigned long *p = &addr->r; __asm__ __volatile__( "1: ldarx %0,0,%3\n\ @@ -163,11 +148,11 @@ static inline void set_pp_bit(unsigned long pp, HPTE *addr) */ static long native_hpte_find(unsigned long vpn) { - HPTE *hptep; + hpte_t *hptep; unsigned long hash; unsigned long i, j; long slot; - Hpte_dword0 dw0; + unsigned long hpte_v; hash = hpt_hash(vpn, 0); @@ -175,10 +160,11 @@ static long native_hpte_find(unsigned long vpn) slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; for (i = 0; i < HPTES_PER_GROUP; i++) { hptep = htab_address + slot; - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; - if ((dw0.avpn == (vpn >> 11)) && dw0.v && - (dw0.h == j)) { + if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11)) + && (hpte_v & HPTE_V_VALID) + && ( !!(hpte_v & HPTE_V_SECONDARY) == j)) { /* HPTE matches */ if (j) slot = -slot; @@ -195,20 +181,21 @@ static long native_hpte_find(unsigned long vpn) static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, unsigned long va, int large, int local) { - HPTE *hptep = htab_address + slot; - Hpte_dword0 dw0; + hpte_t *hptep = htab_address + slot; + unsigned long hpte_v; unsigned long avpn = va >> 23; int ret = 0; if (large) - avpn &= ~0x1UL; + avpn &= ~1; native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; /* Even if we miss, we need to invalidate the TLB */ - if ((dw0.avpn != avpn) || !dw0.v) { + if ((HPTE_V_AVPN_VAL(hpte_v) != avpn) + || !(hpte_v & HPTE_V_VALID)) { native_unlock_hpte(hptep); ret = -1; } else { @@ -244,7 +231,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea) { unsigned long vsid, va, vpn, flags = 0; long slot; - HPTE *hptep; + hpte_t *hptep; int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); vsid = get_kernel_vsid(ea); @@ -269,26 +256,27 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea) static void native_hpte_invalidate(unsigned long slot, unsigned long va, int large, int local) { - HPTE *hptep = htab_address + slot; - Hpte_dword0 dw0; + hpte_t *hptep = htab_address + slot; + unsigned long hpte_v; unsigned long avpn = va >> 23; unsigned long flags; int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (large) - avpn &= ~0x1UL; + avpn &= ~1; local_irq_save(flags); native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; /* Even if we miss, we need to invalidate the TLB */ - if ((dw0.avpn != avpn) || !dw0.v) { + if ((HPTE_V_AVPN_VAL(hpte_v) != avpn) + || !(hpte_v & HPTE_V_VALID)) { native_unlock_hpte(hptep); } else { /* Invalidate the hpte. NOTE: this also unlocks it */ - hptep->dw0.dword0 = 0; + hptep->v = 0; } /* Invalidate the tlb */ @@ -315,8 +303,8 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va, static void native_hpte_clear(void) { unsigned long slot, slots, flags; - HPTE *hptep = htab_address; - Hpte_dword0 dw0; + hpte_t *hptep = htab_address; + unsigned long hpte_v; unsigned long pteg_count; pteg_count = htab_hash_mask + 1; @@ -336,11 +324,11 @@ static void native_hpte_clear(void) * running, right? and for crash dump, we probably * don't want to wait for a maybe bad cpu. */ - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; - if (dw0.v) { - hptep->dw0.dword0 = 0; - tlbie(slot2va(dw0.avpn, dw0.l, dw0.h, slot), dw0.l); + if (hpte_v & HPTE_V_VALID) { + hptep->v = 0; + tlbie(slot2va(hpte_v, slot), hpte_v & HPTE_V_LARGE); } } @@ -353,8 +341,8 @@ static void native_flush_hash_range(unsigned long context, { unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn; int i, j; - HPTE *hptep; - Hpte_dword0 dw0; + hpte_t *hptep; + unsigned long hpte_v; struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); /* XXX fix for large ptes */ @@ -390,14 +378,15 @@ static void native_flush_hash_range(unsigned long context, native_lock_hpte(hptep); - dw0 = hptep->dw0.dw0; + hpte_v = hptep->v; /* Even if we miss, we need to invalidate the TLB */ - if ((dw0.avpn != avpn) || !dw0.v) { + if ((HPTE_V_AVPN_VAL(hpte_v) != avpn) + || !(hpte_v & HPTE_V_VALID)) { native_unlock_hpte(hptep); } else { /* Invalidate the hpte. NOTE: this also unlocks it */ - hptep->dw0.dword0 = 0; + hptep->v = 0; } j++; diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 1647b1c6f28..623b5d130c3 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c @@ -75,8 +75,8 @@ extern unsigned long dart_tablebase; #endif /* CONFIG_U3_DART */ -HPTE *htab_address; -unsigned long htab_hash_mask; +hpte_t *htab_address; +unsigned long htab_hash_mask; extern unsigned long _SDR1; @@ -97,11 +97,15 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, unsigned long addr; unsigned int step; unsigned long tmp_mode; + unsigned long vflags; - if (large) + if (large) { step = 16*MB; - else + vflags = HPTE_V_BOLTED | HPTE_V_LARGE; + } else { step = 4*KB; + vflags = HPTE_V_BOLTED; + } for (addr = start; addr < end; addr += step) { unsigned long vpn, hash, hpteg; @@ -129,12 +133,12 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, if (systemcfg->platform & PLATFORM_LPAR) ret = pSeries_lpar_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, - 0, tmp_mode, 1, large); + vflags, tmp_mode); else #endif /* CONFIG_PPC_PSERIES */ ret = native_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, - 0, tmp_mode, 1, large); + vflags, tmp_mode); if (ret == -1) { ppc64_terminate_msg(0x20, "create_pte_mapping"); diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index fdcfe97c75c..f9524602818 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c @@ -583,7 +583,7 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access, pte_t *ptep; unsigned long va, vpn; pte_t old_pte, new_pte; - unsigned long hpteflags, prpn; + unsigned long rflags, prpn; long slot; int err = 1; @@ -626,9 +626,9 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access, old_pte = *ptep; new_pte = old_pte; - hpteflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW)); + rflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW)); /* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */ - hpteflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC); + rflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC); /* Check if pte already has an hpte (case 2) */ if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) { @@ -641,7 +641,7 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access, slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12; - if (ppc_md.hpte_updatepp(slot, hpteflags, va, 1, local) == -1) + if (ppc_md.hpte_updatepp(slot, rflags, va, 1, local) == -1) pte_val(old_pte) &= ~_PAGE_HPTEFLAGS; } @@ -661,10 +661,10 @@ repeat: /* Add in WIMG bits */ /* XXX We should store these in the pte */ - hpteflags |= _PAGE_COHERENT; + rflags |= _PAGE_COHERENT; - slot = ppc_md.hpte_insert(hpte_group, va, prpn, 0, - hpteflags, 0, 1); + slot = ppc_md.hpte_insert(hpte_group, va, prpn, + HPTE_V_LARGE, rflags); /* Primary is full, try the secondary */ if (unlikely(slot == -1)) { @@ -672,7 +672,7 @@ repeat: hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; slot = ppc_md.hpte_insert(hpte_group, va, prpn, - 1, hpteflags, 0, 1); + HPTE_V_LARGE, rflags); if (slot == -1) { if (mftb() & 0x1) hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index b50b3a446db..e58a24d4287 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c @@ -180,9 +180,10 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags) hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); /* Panic if a pte grpup is full */ - if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT, 0, - _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX, - 1, 0) == -1) { + if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT, + HPTE_V_BOLTED, + _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX) + == -1) { panic("map_io_page: could not insert mapping"); } } diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 61405622287..18610cea03a 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -58,6 +58,7 @@ #include <linux/compat.h> #include <linux/vfs.h> #include <linux/ptrace.h> +#include <linux/fadvise.h> #include <asm/types.h> #include <asm/ipc.h> @@ -1043,3 +1044,40 @@ sys32_timer_create(clockid_t which_clock, struct compat_sigevent *se32, return ret; } + +/* + * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64. + * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE} + * because the 31 bit values differ from the 64 bit values. + */ + +asmlinkage long +sys32_fadvise64(int fd, loff_t offset, size_t len, int advise) +{ + if (advise == 4) + advise = POSIX_FADV_DONTNEED; + else if (advise == 5) + advise = POSIX_FADV_NOREUSE; + return sys_fadvise64(fd, offset, len, advise); +} + +struct fadvise64_64_args { + int fd; + long long offset; + long long len; + int advice; +}; + +asmlinkage long +sys32_fadvise64_64(struct fadvise64_64_args __user *args) +{ + struct fadvise64_64_args a; + + if ( copy_from_user(&a, args, sizeof(a)) ) + return -EFAULT; + if (a.advice == 4) + a.advice = POSIX_FADV_DONTNEED; + else if (a.advice == 5) + a.advice = POSIX_FADV_NOREUSE; + return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); +} diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index bf529739c8a..799a98eac92 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1251,12 +1251,12 @@ sys32_fadvise64_wrapper: or %r3,%r4 # get low word of 64bit loff_t llgfr %r4,%r5 # size_t (unsigned long) lgfr %r5,%r6 # int - jg sys_fadvise64 + jg sys32_fadvise64 .globl sys32_fadvise64_64_wrapper sys32_fadvise64_64_wrapper: llgtr %r2,%r2 # struct fadvise64_64_args * - jg s390_fadvise64_64 + jg sys32_fadvise64_64 .globl sys32_clock_settime_wrapper sys32_clock_settime_wrapper: diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S index bbd3429bcff..c366a8b326e 100644 --- a/arch/v850/kernel/vmlinux.lds.S +++ b/arch/v850/kernel/vmlinux.lds.S @@ -1,8 +1,8 @@ /* * arch/v850/vmlinux.lds.S -- kernel linker script for v850 platforms * - * Copyright (C) 2002,03,04 NEC Electronics Corporation - * Copyright (C) 2002,03,04 Miles Bader <miles@gnu.org> + * Copyright (C) 2002,03,04,05 NEC Electronics Corporation + * Copyright (C) 2002,03,04,05 Miles Bader <miles@gnu.org> * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this @@ -61,6 +61,7 @@ *(__kcrctab_gpl) \ ___stop___kcrctab_gpl = .; \ /* Built-in module parameters */ \ + . = ALIGN (4) ; \ ___start___param = .; \ *(__param) \ ___stop___param = .; diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index 033456bb9fe..e996183c5b0 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c @@ -105,7 +105,7 @@ out: static void amijoy_close(struct input_dev *dev) { - down(&amijoysem); + down(&amijoy_sem); if (!--amijoy_used) free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt); up(&amijoy_sem); diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index b5dc59389bb..df95d2158b1 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -300,7 +300,7 @@ config MTD_JEDEC config MTD_XIP bool "XIP aware MTD support" - depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL + depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM default y if XIP_KERNEL help This allows MTD support to work with flash memory which is also diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 8c24e18db3b..c894f880157 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -4,7 +4,7 @@ * * (C) 2000 Red Hat. GPL'd * - * $Id: cfi_cmdset_0020.c,v 1.17 2004/11/20 12:49:04 dwmw2 Exp $ + * $Id: cfi_cmdset_0020.c,v 1.19 2005/07/13 15:52:45 dwmw2 Exp $ * * 10/10/2000 Nicolas Pitre <nico@cam.org> * - completely revamped method functions so they are aware and @@ -16,6 +16,8 @@ * - modified Intel Command Set 0x0001 to support ST Advanced Architecture * (command set 0x0020) * - added a writev function + * 07/13/2005 Joern Engel <joern@wh.fh-wedel.de> + * - Plugged memory leak in cfi_staa_writev(). */ #include <linux/version.h> @@ -719,6 +721,7 @@ cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs, write_error: if (retlen) *retlen = totlen; + kfree(buffer); return ret; } diff --git a/fs/inode.c b/fs/inode.c index 96364fae084..e57f1724db3 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -757,6 +757,7 @@ EXPORT_SYMBOL(igrab); * @head: the head of the list to search * @test: callback used for comparisons between inodes * @data: opaque data pointer to pass to @test + * @wait: if true wait for the inode to be unlocked, if false do not * * ifind() searches for the inode specified by @data in the inode * cache. This is a generalized version of ifind_fast() for file systems where @@ -771,7 +772,7 @@ EXPORT_SYMBOL(igrab); */ static inline struct inode *ifind(struct super_block *sb, struct hlist_head *head, int (*test)(struct inode *, void *), - void *data) + void *data, const int wait) { struct inode *inode; @@ -780,7 +781,8 @@ static inline struct inode *ifind(struct super_block *sb, if (inode) { __iget(inode); spin_unlock(&inode_lock); - wait_on_inode(inode); + if (likely(wait)) + wait_on_inode(inode); return inode; } spin_unlock(&inode_lock); @@ -820,7 +822,7 @@ static inline struct inode *ifind_fast(struct super_block *sb, } /** - * ilookup5 - search for an inode in the inode cache + * ilookup5_nowait - search for an inode in the inode cache * @sb: super block of file system to search * @hashval: hash value (usually inode number) to search for * @test: callback used for comparisons between inodes @@ -832,7 +834,38 @@ static inline struct inode *ifind_fast(struct super_block *sb, * identification of an inode. * * If the inode is in the cache, the inode is returned with an incremented - * reference count. + * reference count. Note, the inode lock is not waited upon so you have to be + * very careful what you do with the returned inode. You probably should be + * using ilookup5() instead. + * + * Otherwise NULL is returned. + * + * Note, @test is called with the inode_lock held, so can't sleep. + */ +struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval, + int (*test)(struct inode *, void *), void *data) +{ + struct hlist_head *head = inode_hashtable + hash(sb, hashval); + + return ifind(sb, head, test, data, 0); +} + +EXPORT_SYMBOL(ilookup5_nowait); + +/** + * ilookup5 - search for an inode in the inode cache + * @sb: super block of file system to search + * @hashval: hash value (usually inode number) to search for + * @test: callback used for comparisons between inodes + * @data: opaque data pointer to pass to @test + * + * ilookup5() uses ifind() to search for the inode specified by @hashval and + * @data in the inode cache. This is a generalized version of ilookup() for + * file systems where the inode number is not sufficient for unique + * identification of an inode. + * + * If the inode is in the cache, the inode lock is waited upon and the inode is + * returned with an incremented reference count. * * Otherwise NULL is returned. * @@ -843,7 +876,7 @@ struct inode *ilookup5(struct super_block *sb, unsigned long hashval, { struct hlist_head *head = inode_hashtable + hash(sb, hashval); - return ifind(sb, head, test, data); + return ifind(sb, head, test, data, 1); } EXPORT_SYMBOL(ilookup5); @@ -900,7 +933,7 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval, struct hlist_head *head = inode_hashtable + hash(sb, hashval); struct inode *inode; - inode = ifind(sb, head, test, data); + inode = ifind(sb, head, test, data, 1); if (inode) return inode; /* diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c index 3dd5394921c..97dc39796e2 100644 --- a/fs/jffs2/build.c +++ b/fs/jffs2/build.c @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: build.c,v 1.70 2005/02/28 08:21:05 dedekind Exp $ + * $Id: build.c,v 1.71 2005/07/12 16:37:08 dedekind Exp $ * */ @@ -336,13 +336,6 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c) c->blocks[i].bad_count = 0; } - init_MUTEX(&c->alloc_sem); - init_MUTEX(&c->erase_free_sem); - init_waitqueue_head(&c->erase_wait); - init_waitqueue_head(&c->inocache_wq); - spin_lock_init(&c->erase_completion_lock); - spin_lock_init(&c->inocache_lock); - INIT_LIST_HEAD(&c->clean_list); INIT_LIST_HEAD(&c->very_dirty_list); INIT_LIST_HEAD(&c->dirty_list); diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c index c7bbdeec93a..4991c348f6e 100644 --- a/fs/jffs2/nodelist.c +++ b/fs/jffs2/nodelist.c @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: nodelist.c,v 1.97 2005/07/06 15:18:41 dwmw2 Exp $ + * $Id: nodelist.c,v 1.98 2005/07/10 15:15:32 dedekind Exp $ * */ @@ -55,11 +55,11 @@ void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new }); } -/* Put a new tmp_dnode_info into the list, keeping the list in - order of increasing version -*/ - -static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct rb_root *list) +/* + * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in + * order of increasing version. + */ +static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list) { struct rb_node **p = &list->rb_node; struct rb_node * parent = NULL; @@ -420,7 +420,7 @@ int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n", ref_offset(ref), je32_to_cpu(node.i.version), je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize))); - jffs2_add_tn_to_list(tn, &ret_tn); + jffs2_add_tn_to_tree(tn, &ret_tn); break; default: diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 7bf72e012c9..d900c8929b0 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: os-linux.h,v 1.57 2005/07/06 12:13:09 dwmw2 Exp $ + * $Id: os-linux.h,v 1.58 2005/07/12 02:34:35 tpoynor Exp $ * */ @@ -86,6 +86,8 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) #define jffs2_dataflash(c) (0) #define jffs2_nor_ecc_flash_setup(c) (0) #define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) +#define jffs2_dataflash_setup(c) (0) +#define jffs2_dataflash_cleanup(c) do {} while (0) #else /* NAND and/or ECC'd NOR support present */ diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 081656c1d49..5b2a83599d7 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: readinode.c,v 1.120 2005/07/05 21:03:07 dwmw2 Exp $ + * $Id: readinode.c,v 1.125 2005/07/10 13:13:55 dedekind Exp $ * */ @@ -151,6 +151,9 @@ int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_in D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn)); + if (unlikely(!fn->size)) + return 0; + newfrag = jffs2_alloc_node_frag(); if (unlikely(!newfrag)) return -ENOMEM; @@ -158,11 +161,6 @@ int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_in D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag)); - if (unlikely(!fn->size)) { - jffs2_free_node_frag(newfrag); - return 0; - } - newfrag->ofs = fn->ofs; newfrag->size = fn->size; newfrag->node = fn; @@ -560,7 +558,6 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, } next_tn: BUG_ON(rb->rb_left); - repl_rb = NULL; if (rb->rb_parent && rb->rb_parent->rb_left == rb) { /* We were then left-hand child of our parent. We need to move our own right-hand child into our place. */ diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 2cf14cf8b35..aaf9475cfb6 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: super.c,v 1.106 2005/05/18 11:37:25 dedekind Exp $ + * $Id: super.c,v 1.107 2005/07/12 16:37:08 dedekind Exp $ * */ @@ -140,6 +140,15 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n", mtd->index, mtd->name)); + /* Initialize JFFS2 superblock locks, the further initialization will be + * done later */ + init_MUTEX(&c->alloc_sem); + init_MUTEX(&c->erase_free_sem); + init_waitqueue_head(&c->erase_wait); + init_waitqueue_head(&c->inocache_wq); + spin_lock_init(&c->erase_completion_lock); + spin_lock_init(&c->inocache_lock); + sb->s_op = &jffs2_super_operations; sb->s_flags = flags | MS_NOATIME; diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 6e242556b90..12a857c29e2 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -331,7 +331,7 @@ static ctl_table nlm_sysctls[] = { .ctl_name = CTL_UNNUMBERED, .procname = "nlm_grace_period", .data = &nlm_grace_period, - .maxlen = sizeof(int), + .maxlen = sizeof(unsigned long), .mode = 0644, .proc_handler = &proc_doulongvec_minmax, .extra1 = (unsigned long *) &nlm_grace_period_min, @@ -341,7 +341,7 @@ static ctl_table nlm_sysctls[] = { .ctl_name = CTL_UNNUMBERED, .procname = "nlm_timeout", .data = &nlm_timeout, - .maxlen = sizeof(int), + .maxlen = sizeof(unsigned long), .mode = 0644, .proc_handler = &proc_doulongvec_minmax, .extra1 = (unsigned long *) &nlm_timeout_min, diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index ccabbce39d8..afe26ffc2e2 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h @@ -149,6 +149,7 @@ static inline void get_mmu_context(struct mm_struct *mm) */ static inline void destroy_context(struct mm_struct *mm) { + preempt_disable(); if (mm->context != NO_CONTEXT) { clear_bit(mm->context, context_map); mm->context = NO_CONTEXT; @@ -156,6 +157,7 @@ static inline void destroy_context(struct mm_struct *mm) atomic_inc(&nr_free_contexts); #endif } + preempt_enable(); } static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, diff --git a/include/asm-ppc64/iSeries/HvCallHpt.h b/include/asm-ppc64/iSeries/HvCallHpt.h index 66f38222ff7..43a1969230b 100644 --- a/include/asm-ppc64/iSeries/HvCallHpt.h +++ b/include/asm-ppc64/iSeries/HvCallHpt.h @@ -77,27 +77,26 @@ static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson, return compressedStatus; } -static inline u64 HvCallHpt_findValid(HPTE *hpte, u64 vpn) +static inline u64 HvCallHpt_findValid(hpte_t *hpte, u64 vpn) { return HvCall3Ret16(HvCallHptFindValid, hpte, vpn, 0, 0); } -static inline u64 HvCallHpt_findNextValid(HPTE *hpte, u32 hpteIndex, +static inline u64 HvCallHpt_findNextValid(hpte_t *hpte, u32 hpteIndex, u8 bitson, u8 bitsoff) { return HvCall3Ret16(HvCallHptFindNextValid, hpte, hpteIndex, bitson, bitsoff); } -static inline void HvCallHpt_get(HPTE *hpte, u32 hpteIndex) +static inline void HvCallHpt_get(hpte_t *hpte, u32 hpteIndex) { HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0); } -static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, HPTE *hpte) +static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, hpte_t *hpte) { - HvCall4(HvCallHptAddValidate, hpteIndex, hBit, (*((u64 *)hpte)), - (*(((u64 *)hpte)+1))); + HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r); } #endif /* _HVCALLHPT_H */ diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index 1e6ad482413..f0c1d2d9267 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h @@ -53,10 +53,8 @@ struct machdep_calls { long (*hpte_insert)(unsigned long hpte_group, unsigned long va, unsigned long prpn, - int secondary, - unsigned long hpteflags, - int bolted, - int large); + unsigned long vflags, + unsigned long rflags); long (*hpte_remove)(unsigned long hpte_group); void (*flush_hash_range)(unsigned long context, unsigned long number, diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h index f373de5e3dd..3d07ddd11e3 100644 --- a/include/asm-ppc64/mmu.h +++ b/include/asm-ppc64/mmu.h @@ -60,6 +60,22 @@ #define HPTES_PER_GROUP 8 +#define HPTE_V_AVPN_SHIFT 7 +#define HPTE_V_AVPN ASM_CONST(0xffffffffffffff80) +#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT) +#define HPTE_V_BOLTED ASM_CONST(0x0000000000000010) +#define HPTE_V_LOCK ASM_CONST(0x0000000000000008) +#define HPTE_V_LARGE ASM_CONST(0x0000000000000004) +#define HPTE_V_SECONDARY ASM_CONST(0x0000000000000002) +#define HPTE_V_VALID ASM_CONST(0x0000000000000001) + +#define HPTE_R_PP0 ASM_CONST(0x8000000000000000) +#define HPTE_R_TS ASM_CONST(0x4000000000000000) +#define HPTE_R_RPN_SHIFT 12 +#define HPTE_R_RPN ASM_CONST(0x3ffffffffffff000) +#define HPTE_R_FLAGS ASM_CONST(0x00000000000003ff) +#define HPTE_R_PP ASM_CONST(0x0000000000000003) + /* Values for PP (assumes Ks=0, Kp=1) */ /* pp0 will always be 0 for linux */ #define PP_RWXX 0 /* Supervisor read/write, User none */ @@ -69,54 +85,13 @@ #ifndef __ASSEMBLY__ -/* Hardware Page Table Entry */ -typedef struct { - unsigned long avpn:57; /* vsid | api == avpn */ - unsigned long : 2; /* Software use */ - unsigned long bolted: 1; /* HPTE is "bolted" */ - unsigned long lock: 1; /* lock on pSeries SMP */ - unsigned long l: 1; /* Virtual page is large (L=1) or 4 KB (L=0) */ - unsigned long h: 1; /* Hash function identifier */ - unsigned long v: 1; /* Valid (v=1) or invalid (v=0) */ -} Hpte_dword0; - -typedef struct { - unsigned long pp0: 1; /* Page protection bit 0 */ - unsigned long ts: 1; /* Tag set bit */ - unsigned long rpn: 50; /* Real page number */ - unsigned long : 2; /* Reserved */ - unsigned long ac: 1; /* Address compare */ - unsigned long r: 1; /* Referenced */ - unsigned long c: 1; /* Changed */ - unsigned long w: 1; /* Write-thru cache mode */ - unsigned long i: 1; /* Cache inhibited */ - unsigned long m: 1; /* Memory coherence required */ - unsigned long g: 1; /* Guarded */ - unsigned long n: 1; /* No-execute */ - unsigned long pp: 2; /* Page protection bits 1:2 */ -} Hpte_dword1; - -typedef struct { - char padding[6]; /* padding */ - unsigned long : 6; /* padding */ - unsigned long flags: 10; /* HPTE flags */ -} Hpte_dword1_flags; - typedef struct { - union { - unsigned long dword0; - Hpte_dword0 dw0; - } dw0; - - union { - unsigned long dword1; - Hpte_dword1 dw1; - Hpte_dword1_flags flags; - } dw1; -} HPTE; + unsigned long v; + unsigned long r; +} hpte_t; -extern HPTE * htab_address; -extern unsigned long htab_hash_mask; +extern hpte_t *htab_address; +extern unsigned long htab_hash_mask; static inline unsigned long hpt_hash(unsigned long vpn, int large) { @@ -181,18 +156,18 @@ static inline void tlbiel(unsigned long va) asm volatile("ptesync": : :"memory"); } -static inline unsigned long slot2va(unsigned long avpn, unsigned long large, - unsigned long secondary, unsigned long slot) +static inline unsigned long slot2va(unsigned long hpte_v, unsigned long slot) { + unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v); unsigned long va; va = avpn << 23; - if (!large) { + if (! (hpte_v & HPTE_V_LARGE)) { unsigned long vpi, pteg; pteg = slot / HPTES_PER_GROUP; - if (secondary) + if (hpte_v & HPTE_V_SECONDARY) pteg = ~pteg; vpi = ((va >> 28) ^ pteg) & htab_hash_mask; @@ -219,11 +194,11 @@ extern void hpte_init_iSeries(void); extern long pSeries_lpar_hpte_insert(unsigned long hpte_group, unsigned long va, unsigned long prpn, - int secondary, unsigned long hpteflags, - int bolted, int large); + unsigned long vflags, + unsigned long rflags); extern long native_hpte_insert(unsigned long hpte_group, unsigned long va, - unsigned long prpn, int secondary, - unsigned long hpteflags, int bolted, int large); + unsigned long prpn, + unsigned long vflags, unsigned long rflags); #endif /* __ASSEMBLY__ */ diff --git a/include/linux/fadvise.h b/include/linux/fadvise.h index 6fc656dfb93..e8e747139b9 100644 --- a/include/linux/fadvise.h +++ b/include/linux/fadvise.h @@ -5,7 +5,17 @@ #define POSIX_FADV_RANDOM 1 /* Expect random page references. */ #define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ #define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ + +/* + * The advise values for POSIX_FADV_DONTNEED and POSIX_ADV_NOREUSE + * for s390-64 differ from the values for the rest of the world. + */ +#if defined(__s390x__) +#define POSIX_FADV_DONTNEED 6 /* Don't need these pages. */ +#define POSIX_FADV_NOREUSE 7 /* Data will be accessed once. */ +#else #define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ #define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ +#endif #endif /* FADVISE_H_INCLUDED */ diff --git a/include/linux/fs.h b/include/linux/fs.h index c9bf3746a9f..0f53e012494 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1441,6 +1441,9 @@ extern int inode_needs_sync(struct inode *inode); extern void generic_delete_inode(struct inode *inode); extern void generic_drop_inode(struct inode *inode); +extern struct inode *ilookup5_nowait(struct super_block *sb, + unsigned long hashval, int (*test)(struct inode *, void *), + void *data); extern struct inode *ilookup5(struct super_block *sb, unsigned long hashval, int (*test)(struct inode *, void *), void *data); extern struct inode *ilookup(struct super_block *sb, unsigned long ino); |