From a0c111c631e7ab4abd68920debd44259160812ef Mon Sep 17 00:00:00 2001 From: Paolo Galtieri Date: Tue, 11 Oct 2005 08:29:07 -0700 Subject: [PATCH] ppc highmem fix I've noticed that the calculations for seg_size and nr_segs in __dma_sync_page_highmem() (arch/ppc/kernel/dma-mapping.c) are wrong. The incorrect calculations can result in either an oops or a panic when running fsck depending on the size of the partition. The problem with the seg_size calculation is that it can result in a negative number if size is offset > size. The problem with the nr_segs caculation is returns the wrong number of segments, e.g. it returns 1 when size is 200 and offset is 4095, when it should return 2 or more. Acked-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/dma-mapping.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/ppc') diff --git a/arch/ppc/kernel/dma-mapping.c b/arch/ppc/kernel/dma-mapping.c index b566d982806c..8edee806dae7 100644 --- a/arch/ppc/kernel/dma-mapping.c +++ b/arch/ppc/kernel/dma-mapping.c @@ -401,10 +401,10 @@ EXPORT_SYMBOL(__dma_sync); static inline void __dma_sync_page_highmem(struct page *page, unsigned long offset, size_t size, int direction) { - size_t seg_size = min((size_t)PAGE_SIZE, size) - offset; + size_t seg_size = min((size_t)(PAGE_SIZE - offset), size); size_t cur_size = seg_size; unsigned long flags, start, seg_offset = offset; - int nr_segs = PAGE_ALIGN(size + (PAGE_SIZE - offset))/PAGE_SIZE; + int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE; int seg_nr = 0; local_irq_save(flags); -- cgit v1.2.2 From d8e998c58a870770905495a1d45ebf7285b5b1c5 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 12 Oct 2005 14:22:50 +1000 Subject: [PATCH] ppc32: Tell userland about lack of standard TB Glibc is about to get some new high precision timer stuff that relies on the standard timebase of the PPC architecture. However, some (rare & old) CPUs do not have such timebase and it is a bit annoying to have your stuff just crash because you are running on the wrong CPU... This exposes to userland a CPU feature bit that tells that the current processor doesn't have a standard timebase. It's negative logic so that glibc will still "just work" on older kernels (it will just be unhappy on those old CPUs but that doesn't really matter as distro tend to update glibc & kernel at the same time). Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- arch/ppc/kernel/cputable.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/ppc') diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 546e1ea4cafa..6b76cf58d9e0 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -91,7 +91,7 @@ struct cpu_spec cpu_specs[] = { .cpu_features = CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE, .cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR | - PPC_FEATURE_UNIFIED_CACHE, + PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_601 @@ -745,7 +745,8 @@ struct cpu_spec cpu_specs[] = { .cpu_name = "403GCX", .cpu_features = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, - .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB, .icache_bsize = 16, .dcache_bsize = 16, }, -- cgit v1.2.2