| summaryrefslogtreecommitdiff |
Side-by-side diff
| -rw-r--r-- | arch/frv/Kconfig | 1 | ||||
| -rw-r--r-- | arch/frv/include/asm/system.h | 9 | ||||
| -rw-r--r-- | arch/frv/include/asm/thread_info.h | 4 | ||||
| -rw-r--r-- | arch/frv/kernel/irq-mb93091.c | 2 | ||||
| -rw-r--r-- | include/linux/vmalloc.h | 32 | ||||
| -rw-r--r-- | mm/nommu.c | 52 | ||||
| -rw-r--r-- | mm/percpu.c | 3 |
7 files changed, 76 insertions, 27 deletions
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index e06e3c3..6db8aea 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -354,25 +354,24 @@ source "drivers/pcmcia/Kconfig" # depends on EXPERIMENTAL # help # At some point in the future, this will cause floating-point math # instructions to be emulated by the kernel on machines that lack a # floating-point math coprocessor. Thrill-seekers and chronically # sleep-deprived psychotic hacker types can say Y now, everyone else # should probably wait a while. menu "Power management options" config ARCH_SUSPEND_POSSIBLE def_bool y - depends on !SMP source kernel/power/Kconfig endmenu endmenu menu "Executable formats" source "fs/Kconfig.binfmt" endmenu diff --git a/arch/frv/include/asm/system.h b/arch/frv/include/asm/system.h index 0a6d8d9..6c10fd2 100644 --- a/arch/frv/include/asm/system.h +++ b/arch/frv/include/asm/system.h @@ -36,39 +36,30 @@ do { \ mb(); \ } while(0) /* * Force strict CPU ordering. */ #define nop() asm volatile ("nop"::) #define mb() asm volatile ("membar" : : :"memory") #define rmb() asm volatile ("membar" : : :"memory") #define wmb() asm volatile ("membar" : : :"memory") #define read_barrier_depends() do { } while (0) -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) \ - do { xchg(&var, (value)); } while (0) -#else #define smp_mb() barrier() #define smp_rmb() barrier() #define smp_wmb() barrier() #define smp_read_barrier_depends() do {} while(0) #define set_mb(var, value) \ do { var = (value); barrier(); } while (0) -#endif extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2))); extern void free_initmem(void); #define arch_align_stack(x) (x) /*****************************************************************************/ /* * compare and conditionally exchange value with memory * - if (*ptr == test) then orig = *ptr; *ptr = test; * - if (*ptr != test) then orig = *ptr; */ diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h index 8582e9c..cefbe73 100644 --- a/arch/frv/include/asm/thread_info.h +++ b/arch/frv/include/asm/thread_info.h @@ -12,24 +12,26 @@ #ifndef _ASM_THREAD_INFO_H #define _ASM_THREAD_INFO_H #ifdef __KERNEL__ #ifndef __ASSEMBLY__ #include <asm/processor.h> #endif #define THREAD_SIZE 8192 +#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR + /* * low level task data that entry.S needs immediate access to * - this struct should fit entirely inside of one cache line * - this struct shares the supervisor stack pages * - if the contents of this structure are changed, the assembly constants must also be changed */ #ifndef __ASSEMBLY__ struct thread_info { struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ unsigned long flags; /* low level flags */ @@ -78,25 +80,25 @@ struct thread_info { /* how to get the thread information struct from C */ register struct thread_info *__current_thread_info asm("gr15"); #define current_thread_info() ({ __current_thread_info; }) #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR /* thread information allocation */ #ifdef CONFIG_DEBUG_STACK_USAGE #define alloc_thread_info_node(tsk, node) \ kzalloc_node(THREAD_SIZE, GFP_KERNEL, node) #else -#define alloc_thread_info_node(tsk) \ +#define alloc_thread_info_node(tsk, node) \ kmalloc_node(THREAD_SIZE, GFP_KERNEL, node) #endif #define free_thread_info(info) kfree(info) #endif /* __ASSEMBLY__ */ /* * thread information flags * - these are process state flags that various assembly files may need to access * - pending work-to-be-done flags are in LSW * - other flags in MSW diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c index 372fe60..9afc2ea 100644 --- a/arch/frv/kernel/irq-mb93091.c +++ b/arch/frv/kernel/irq-mb93091.c @@ -38,25 +38,25 @@ */ static void frv_fpga_mask(struct irq_data *d) { uint16_t imr = __get_IMR(); imr |= 1 << (d->irq - IRQ_BASE_FPGA); __set_IMR(imr); } static void frv_fpga_ack(struct irq_data *d) { - __clr_IFR(1 << (irq - IRQ_BASE_FPGA)); + __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA)); } static void frv_fpga_mask_ack(struct irq_data *d) { uint16_t imr = __get_IMR(); imr |= 1 << (d->irq - IRQ_BASE_FPGA); __set_IMR(imr); __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA)); } diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 4ed6fcd..9332e52 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -86,41 +86,73 @@ extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags); extern struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, void *caller); extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, unsigned long start, unsigned long end); extern struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, unsigned long start, unsigned long end, void *caller); extern struct vm_struct *remove_vm_area(const void *addr); extern int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages); +#ifdef CONFIG_MMU extern int map_kernel_range_noflush(unsigned long start, unsigned long size, pgprot_t prot, struct page **pages); extern void unmap_kernel_range_noflush(unsigned long addr, unsigned long size); extern void unmap_kernel_range(unsigned long addr, unsigned long size); +#else +static inline int +map_kernel_range_noflush(unsigned long start, unsigned long size, + pgprot_t prot, struct page **pages) +{ + return size >> PAGE_SHIFT; +} +static inline void +unmap_kernel_range_noflush(unsigned long addr, unsigned long size) +{ +} +static inline void +unmap_kernel_range(unsigned long addr, unsigned long size) +{ +} +#endif /* Allocate/destroy a 'vmalloc' VM area. */ extern struct vm_struct *alloc_vm_area(size_t size); extern void free_vm_area(struct vm_struct *area); /* for /dev/kmem */ extern long vread(char *buf, char *addr, unsigned long count); extern long vwrite(char *buf, char *addr, unsigned long count); /* * Internals. Dont't use.. */ extern rwlock_t vmlist_lock; extern struct vm_struct *vmlist; extern __init void vm_area_register_early(struct vm_struct *vm, size_t align); #ifdef CONFIG_SMP +# ifdef CONFIG_MMU struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, const size_t *sizes, int nr_vms, size_t align); void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms); +# else +static inline struct vm_struct ** +pcpu_get_vm_areas(const unsigned long *offsets, + const size_t *sizes, int nr_vms, + size_t align) +{ + return NULL; +} + +static inline void +pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms) +{ +} +# endif #endif #endif /* _LINUX_VMALLOC_H */ @@ -1962,63 +1962,89 @@ error: int in_gate_area_no_mm(unsigned long addr) { return 0; } int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { BUG(); return 0; } EXPORT_SYMBOL(filemap_fault); -/* - * Access another process' address space. - * - source/target buffer must be kernel space - */ -int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) +static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, + unsigned long addr, void *buf, int len, int write) { struct vm_area_struct *vma; - struct mm_struct *mm; - - if (addr + len < addr) - return 0; - - mm = get_task_mm(tsk); - if (!mm) - return 0; down_read(&mm->mmap_sem); /* the access must start within one of the target process's mappings */ vma = find_vma(mm, addr); if (vma) { /* don't overrun this mapping */ if (addr + len >= vma->vm_end) len = vma->vm_end - addr; /* only read or write mappings where it is permitted */ if (write && vma->vm_flags & VM_MAYWRITE) copy_to_user_page(vma, NULL, addr, (void *) addr, buf, len); else if (!write && vma->vm_flags & VM_MAYREAD) copy_from_user_page(vma, NULL, addr, buf, (void *) addr, len); else len = 0; } else { len = 0; } up_read(&mm->mmap_sem); + + return len; +} + +/** + * @access_remote_vm - access another process' address space + * @mm: the mm_struct of the target address space + * @addr: start address to access + * @buf: source or destination buffer + * @len: number of bytes to transfer + * @write: whether the access is a write + * + * The caller must hold a reference on @mm. + */ +int access_remote_vm(struct mm_struct *mm, unsigned long addr, + void *buf, int len, int write) +{ + return __access_remote_vm(NULL, mm, addr, buf, len, write); +} + +/* + * Access another process' address space. + * - source/target buffer must be kernel space + */ +int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) +{ + struct mm_struct *mm; + + if (addr + len < addr) + return 0; + + mm = get_task_mm(tsk); + if (!mm) + return 0; + + len = __access_remote_vm(tsk, mm, addr, buf, len, write); + mmput(mm); return len; } /** * nommu_shrink_inode_mappings - Shrink the shared mappings on an inode * @inode: The inode to check * @size: The current filesize of the inode * @newsize: The proposed filesize of the inode * * Check the shared mappings on an inode on behalf of a shrinking truncate to * make sure that that any outstanding VMAs aren't broken and then shrink the diff --git a/mm/percpu.c b/mm/percpu.c index 3f93001..55d4d11 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -999,26 +999,25 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr) (unsigned long)addr < first_end) { for_each_possible_cpu(cpu) { void *start = per_cpu_ptr(base, cpu); if (addr >= start && addr < start + pcpu_unit_size) { in_first_chunk = true; break; } } } if (in_first_chunk) { - if ((unsigned long)addr < VMALLOC_START || - (unsigned long)addr >= VMALLOC_END) + if (!is_vmalloc_addr(addr)) return __pa(addr); else return page_to_phys(vmalloc_to_page(addr)); } else return page_to_phys(pcpu_addr_to_page(addr)); } /** * pcpu_alloc_alloc_info - allocate percpu allocation info * @nr_groups: the number of groups * @nr_units: the number of units * |