Skip to contentSkip to conversation

FRV: Make the FRV arch work again

PATCH New David Howells 1 participant 4 messages Nov 23, 2005 – Nov 29, 2005

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/3 FRV: Make the FRV arch work again

The attached patch implements a bunch of small changes to the FRV arch to make it work again.

It deals with the following problems:

(1) SEM_DEBUG should be SEMAPHORE_DEBUG.

(2) The argument list to pcibios_penalize_isa_irq() has changed.

(3) CONFIG_HIGHMEM can't be used directly in #if as it may not be defined.

(4) page->private is no longer directly accessible.

(5) linux/hardirq.h assumes asm/hardirq.h will include linux/irq.h

(6) The IDE MMIO access functions are given pointers, not integers, and so get type casting errors.

(7) __pa() is passed an explicit u64 type in drivers/char/mem.c, but that can't be cast directly to a pointer on a 32-bit platform.

(8) SEMAPHORE_DEBUG should not be contingent on WAITQUEUE_DEBUG as that no longer exists.

(9) PREEMPT_ACTIVE is too low a value.

---
warthog>diffstat -p1 frv-cleanup-2615rc2.diff

 arch/frv/kernel/semaphore.c     |    2 +-
 arch/frv/mb93090-mb00/pci-irq.c |    2 +-
 arch/frv/mm/init.c              |    2 +-
 arch/frv/mm/pgalloc.c           |    6 +++---
 include/asm-frv/hardirq.h       |    1 +
 include/asm-frv/ide.h           |    8 ++++----
 include/asm-frv/page.h          |    4 ++--
 include/asm-frv/semaphore.h     |    2 +-
 include/asm-frv/thread_info.h   |    2 +-
 9 files changed, 15 insertions(+), 14 deletions(-)
arch/frv/kernel/semaphore.c renamed from warthog/kernels/linux-2.6.15-rc2/arch/frv/kernel/semaphore.c +1 -1
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/arch/frv/kernel/semaphore.c linux-2.6.15-rc2-frv/arch/frv/kernel/semaphore.c
@@ -20,7 +20,7 @@ struct sem_waiter {
 	struct task_struct	*task;
 };
 
-#if SEM_DEBUG
+#if SEMAPHORE_DEBUG
 void semtrace(struct semaphore *sem, const char *str)
 {
 	if (sem->debug)
arch/frv/mb93090-mb00/pci-irq.c renamed from warthog/kernels/linux-2.6.15-rc2/arch/frv/mb93090-mb00/pci-irq.c +1 -1
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/arch/frv/mb93090-mb00/pci-irq.c linux-2.6.15-rc2-frv/arch/frv/mb93090-mb00/pci-irq.c
@@ -60,7 +60,7 @@ void __init pcibios_fixup_irqs(void)
 	}
 }
 
-void __init pcibios_penalize_isa_irq(int irq, int active)
+void __init pcibios_penalize_isa_irq(int irq)
 {
 }
 
arch/frv/mm/init.c renamed from warthog/kernels/linux-2.6.15-rc2/arch/frv/mm/init.c +1 -1
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/arch/frv/mm/init.c linux-2.6.15-rc2-frv/arch/frv/mm/init.c
@@ -108,7 +108,7 @@ void __init paging_init(void)
 
 	memset((void *) empty_zero_page, 0, PAGE_SIZE);
 
-#if CONFIG_HIGHMEM
+#ifdef CONFIG_HIGHMEM
 	if (num_physpages - num_mappedpages) {
 		pgd_t *pge;
 		pud_t *pue;
arch/frv/mm/pgalloc.c renamed from warthog/kernels/linux-2.6.15-rc2/arch/frv/mm/pgalloc.c +3 -3
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/arch/frv/mm/pgalloc.c linux-2.6.15-rc2-frv/arch/frv/mm/pgalloc.c
@@ -85,7 +85,7 @@ static inline void pgd_list_add(pgd_t *p
 	struct page *page = virt_to_page(pgd);
 	page->index = (unsigned long) pgd_list;
 	if (pgd_list)
-		pgd_list->private = (unsigned long) &page->index;
+		set_page_private(pgd_list, (unsigned long) &page->index);
 	pgd_list = page;
 	set_page_private(page, (unsigned long)&pgd_list);
 }
@@ -94,10 +94,10 @@ static inline void pgd_list_del(pgd_t *p
 {
 	struct page *next, **pprev, *page = virt_to_page(pgd);
 	next = (struct page *) page->index;
-	pprev = (struct page **)page_private(page);
+	pprev = (struct page **) page_private(page);
 	*pprev = next;
 	if (next)
-		next->private = (unsigned long) pprev;
+		set_page_private(next, (unsigned long) pprev);
 }
 
 void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
include/asm-frv/hardirq.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/hardirq.h +1 -0
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/hardirq.h linux-2.6.15-rc2-frv/include/asm-frv/hardirq.h
@@ -14,6 +14,7 @@
 
 #include <linux/config.h>
 #include <linux/threads.h>
+#include <linux/irq.h>
 
 typedef struct {
 	unsigned int __softirq_pending;
include/asm-frv/ide.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/ide.h +4 -4
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/ide.h linux-2.6.15-rc2-frv/include/asm-frv/ide.h
@@ -33,10 +33,10 @@
 /*
  * some bits needed for parts of the IDE subsystem to compile
  */
-#define __ide_mm_insw(port, addr, n)	insw(port, addr, n)
-#define __ide_mm_insl(port, addr, n)	insl(port, addr, n)
-#define __ide_mm_outsw(port, addr, n)	outsw(port, addr, n)
-#define __ide_mm_outsl(port, addr, n)	outsl(port, addr, n)
+#define __ide_mm_insw(port, addr, n)	insw((unsigned long) (port), addr, n)
+#define __ide_mm_insl(port, addr, n)	insl((unsigned long) (port), addr, n)
+#define __ide_mm_outsw(port, addr, n)	outsw((unsigned long) (port), addr, n)
+#define __ide_mm_outsl(port, addr, n)	outsl((unsigned long) (port), addr, n)
 
 
 #endif /* __KERNEL__ */
include/asm-frv/page.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/page.h +2 -2
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/page.h linux-2.6.15-rc2-frv/include/asm-frv/page.h
@@ -47,8 +47,8 @@ typedef struct { unsigned long	pgprot;	}
 
 #define devmem_is_allowed(pfn)	1
 
-#define __pa(vaddr)		virt_to_phys((void *) vaddr)
-#define __va(paddr)		phys_to_virt((unsigned long) paddr)
+#define __pa(vaddr)		virt_to_phys((void *) (unsigned long) (vaddr))
+#define __va(paddr)		phys_to_virt((unsigned long) (paddr))
 
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 
include/asm-frv/semaphore.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/semaphore.h +1 -1
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/semaphore.h linux-2.6.15-rc2-frv/include/asm-frv/semaphore.h
@@ -20,7 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
 
-#define SEMAPHORE_DEBUG		WAITQUEUE_DEBUG
+#define SEMAPHORE_DEBUG		0
 
 /*
  * the semaphore definition
include/asm-frv/thread_info.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/thread_info.h +1 -1
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/thread_info.h linux-2.6.15-rc2-frv/include/asm-frv/thread_info.h
@@ -58,7 +58,7 @@ struct thread_info {
 
 #endif
 
-#define PREEMPT_ACTIVE		0x4000000
+#define PREEMPT_ACTIVE		0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
#1 lore raw

PATCH 2/3 FRV: Clean up bootmem allocator's page freeing algorithm

The attached patch cleans up the way the bootmem allocator frees pages.

A new function, __free_pages_bootmem(), is provided in mm/page_alloc.c () that is called from mm/bootmem.c to turn pages over to the main allocator. All the bits of code to initialise pages (clearing PG_reserved and setting the page count) are moved to here. The checks on page validity are removed, on the assumption that the struct page arrays will have been prepared correctly.

---
warthog>diffstat -p1 frv-bootmem-2615rc2.diff

 mm/bootmem.c    |   20 +++-------------
 mm/internal.h   |    2 -
 mm/page_alloc.c |   70 +++++++++++++++++++++++++++++++++++++++++---------------
 3 files changed, 57 insertions(+), 35 deletions(-)
mm/bootmem.c renamed from warthog/kernels/linux-2.6.15-rc2/mm/bootmem.c +4 -16
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/mm/bootmem.c linux-2.6.15-rc2-frv/mm/bootmem.c
@@ -294,20 +294,12 @@ static unsigned long __init free_all_boo
 		unsigned long v = ~map[i / BITS_PER_LONG];
 
 		if (gofast && v == ~0UL) {
-			int j, order;
+			int order;
 
 			page = pfn_to_page(pfn);
 			count += BITS_PER_LONG;
-			__ClearPageReserved(page);
 			order = ffs(BITS_PER_LONG) - 1;
-			set_page_refs(page, order);
-			for (j = 1; j < BITS_PER_LONG; j++) {
-				if (j + 16 < BITS_PER_LONG)
-					prefetchw(page + j + 16);
-				__ClearPageReserved(page + j);
-				set_page_count(page + j, 0);
-			}
-			__free_pages(page, order);
+			__free_pages_bootmem(page, order);
 			i += BITS_PER_LONG;
 			page += BITS_PER_LONG;
 		} else if (v) {
@@ -317,9 +309,7 @@ static unsigned long __init free_all_boo
 			for (m = 1; m && i < idx; m<<=1, page++, i++) {
 				if (v & m) {
 					count++;
-					__ClearPageReserved(page);
-					set_page_refs(page, 0);
-					__free_page(page);
+					__free_pages_bootmem(page, 0);
 				}
 			}
 		} else {
@@ -337,9 +327,7 @@ static unsigned long __init free_all_boo
 	count = 0;
 	for (i = 0; i < ((bdata->node_low_pfn-(bdata->node_boot_start >> PAGE_SHIFT))/8 + PAGE_SIZE-1)/PAGE_SIZE; i++,page++) {
 		count++;
-		__ClearPageReserved(page);
-		set_page_count(page, 1);
-		__free_page(page);
+		__free_pages_bootmem(page, 0);
 	}
 	total += count;
 	bdata->node_bootmem_map = NULL;
mm/internal.h renamed from warthog/kernels/linux-2.6.15-rc2/mm/internal.h +1 -1
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/mm/internal.h linux-2.6.15-rc2-frv/mm/internal.h
@@ -10,4 +10,4 @@
  */
 
 /* page_alloc.c */
-extern void set_page_refs(struct page *page, int order);
+extern void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order);
mm/page_alloc.c renamed from warthog/kernels/linux-2.6.15-rc2/mm/page_alloc.c +52 -18

100 lines not on this page · raw message

#2 lore raw

PATCH 3/3 FRV: Make futex code compilable on nommu

In reply to David Howells

The attached patch makes the futex code compilable on nommu by making the attempt to handle page faults conditional on CONFIG_MMU. If this is not enabled, then we can assume that EFAULT returned from futex_atomic_op_inuser() is not recoverable, and that the address lies outside of valid memory.

---
warthog>diffstat -p1 frv-futex-2615rc2.diff

 include/linux/mm.h |    3 +++
 kernel/futex.c     |   18 +++++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)
include/linux/mm.h renamed from warthog/kernels/linux-2.6.15-rc2/include/linux/mm.h +3 -0
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/linux/mm.h linux-2.6.15-rc2-frv/include/linux/mm.h
@@ -708,12 +708,15 @@ static inline void unmap_shared_mapping_
 extern int vmtruncate(struct inode * inode, loff_t offset);
 extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
 extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
+
+#ifdef CONFIG_MMU
 extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
 
 static inline int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access)
 {
 	return __handle_mm_fault(mm, vma, address, write_access) & (~VM_FAULT_WRITE);
 }
+#endif
 
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
kernel/futex.c renamed from warthog/kernels/linux-2.6.15-rc2/kernel/futex.c +17 -1
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/kernel/futex.c linux-2.6.15-rc2-frv/kernel/futex.c
@@ -335,9 +335,14 @@ static int futex_wake_op(unsigned long u
 	struct futex_hash_bucket *bh1, *bh2;
 	struct list_head *head;
 	struct futex_q *this, *next;
-	int ret, op_ret, attempt = 0;
+	int ret, op_ret;
+#ifdef CONFIG_MMU
+	int attempt = 0;
+#endif
 
+#ifdef CONFIG_MMU
 retryfull:
+#endif
 	down_read(&current->mm->mmap_sem);
 
 	ret = get_futex_key(uaddr1, &key1);
@@ -350,7 +355,9 @@ retryfull:
 	bh1 = hash_futex(&key1);
 	bh2 = hash_futex(&key2);
 
+#ifdef CONFIG_MMU
 retry:
+#endif
 	if (bh1 < bh2)
 		spin_lock(&bh1->lock);
 	spin_lock(&bh2->lock);
@@ -359,12 +366,15 @@ retry:
 
 	op_ret = futex_atomic_op_inuser(op, (int __user *)uaddr2);
 	if (unlikely(op_ret < 0)) {
+#ifdef CONFIG_MMU
 		int dummy;
+#endif
 
 		spin_unlock(&bh1->lock);
 		if (bh1 != bh2)
 			spin_unlock(&bh2->lock);
 
+#ifdef CONFIG_MMU
 		if (unlikely(op_ret != -EFAULT)) {
 			ret = op_ret;
 			goto out;
@@ -408,6 +418,12 @@ retry:
 			return ret;
 
 		goto retryfull;
+
+#else
+		/* we don't get EFAULT from MMU faults if we don't have an MMU,
+		 * but we might get them from range checking */
+		goto out;
+#endif
 	}
 
 	head = &bh1->chain;
#3 lore raw

PATCH 3/3 FRV: Make futex code compilable on nommu [try #2]

The attached patch makes the futex code compilable and usable on NOMMU by making the attempt to handle page faults conditional on CONFIG_MMU. If this is not enabled, then we can assume that EFAULT returned from futex_atomic_op_inuser() is not recoverable, and that the address lies outside of valid memory.

handle_mm_fault() is made to BUG if called on NOMMU without attempting to invoke the actual handler (__handle_mm_fault).

---
warthog>diffstat -p1 frv-futex-2615rc2-2.diff

 include/linux/mm.h |   10 ++++++++++
 kernel/futex.c     |    7 +++++++
 2 files changed, 17 insertions(+)
include/linux/mm.h renamed from warthog/kernels/linux-2.6.15-rc2/include/linux/mm.h +10 -0
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/linux/mm.h linux-2.6.15-rc2-frv/include/linux/mm.h
@@ -708,12 +708,22 @@ static inline void unmap_shared_mapping_
 extern int vmtruncate(struct inode * inode, loff_t offset);
 extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
 extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
+
+#ifdef CONFIG_MMU
 extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
 
 static inline int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access)
 {
 	return __handle_mm_fault(mm, vma, address, write_access) & (~VM_FAULT_WRITE);
 }
+#else
+static inline int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access)
+{
+	/* should never happen if there's no MMU */
+	BUG();
+	return VM_FAULT_SIGBUS;
+}
+#endif
 
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
kernel/futex.c renamed from warthog/kernels/linux-2.6.15-rc2/kernel/futex.c +7 -0
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/kernel/futex.c linux-2.6.15-rc2-frv/kernel/futex.c
@@ -365,6 +365,13 @@ retry:
 		if (bh1 != bh2)
 			spin_unlock(&bh2->lock);
 
+#ifndef CONFIG_MMU
+		/* we don't get EFAULT from MMU faults if we don't have an MMU,
+		 * but we might get them from range checking */
+		ret = op_ret;
+		goto out;
+#endif
+
 		if (unlikely(op_ret != -EFAULT)) {
 			ret = op_ret;
 			goto out;