Browse Source

Merge master.kernel.org:/home/rmk/linux-2.6-arm

* master.kernel.org:/home/rmk/linux-2.6-arm:
  [ARM] Provide basic printk_clock() implementation
  [ARM] Resolve fuse and direct-IO failures due to missing cache flushes
  [ARM] pass vma for flush_anon_page()
  [ARM] Fix potential MMCI bug
  [ARM] Fix kernel-mode undefined instruction aborts
  [ARM] 4082/1: iop3xx: fix iop33x gpio register offset
  [ARM] 4070/1: arch/arm/kernel: fix warnings from missing includes
  [ARM] 4079/1: iop: Update MAINTAINERS
Linus Torvalds 19 years ago
parent
commit
74bda9310f

+ 3 - 2
Documentation/cachetlb.txt

@@ -373,14 +373,15 @@ maps this page at its virtual address.
 	likely that you will need to flush the instruction cache
 	likely that you will need to flush the instruction cache
 	for copy_to_user_page().
 	for copy_to_user_page().
 
 
-  void flush_anon_page(struct page *page, unsigned long vmaddr)
+  void flush_anon_page(struct vm_area_struct *vma, struct page *page,
+                       unsigned long vmaddr)
   	When the kernel needs to access the contents of an anonymous
   	When the kernel needs to access the contents of an anonymous
 	page, it calls this function (currently only
 	page, it calls this function (currently only
 	get_user_pages()).  Note: flush_dcache_page() deliberately
 	get_user_pages()).  Note: flush_dcache_page() deliberately
 	doesn't work for an anonymous page.  The default
 	doesn't work for an anonymous page.  The default
 	implementation is a nop (and should remain so for all coherent
 	implementation is a nop (and should remain so for all coherent
 	architectures).  For incoherent architectures, it should flush
 	architectures).  For incoherent architectures, it should flush
-	the cache of the page at vmaddr in the current user process.
+	the cache of the page at vmaddr.
 
 
   void flush_kernel_dcache_page(struct page *page)
   void flush_kernel_dcache_page(struct page *page)
 	When the kernel needs to modify a user page is has obtained
 	When the kernel needs to modify a user page is has obtained

+ 18 - 4
MAINTAINERS

@@ -412,20 +412,32 @@ S:      Maintained
 ARM/INTEL IOP32X ARM ARCHITECTURE
 ARM/INTEL IOP32X ARM ARCHITECTURE
 P:	Lennert Buytenhek
 P:	Lennert Buytenhek
 M:	kernel@wantstofly.org
 M:	kernel@wantstofly.org
+P:	Dan Williams
+M:	dan.j.williams@intel.com
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-S:	Maintained
+S:	Supported
+
+ARM/INTEL IOP33X ARM ARCHITECTURE
+P:	Dan Williams
+M:	dan.j.williams@intel.com
+L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S:	Supported
 
 
 ARM/INTEL IOP13XX ARM ARCHITECTURE
 ARM/INTEL IOP13XX ARM ARCHITECTURE
 P:	Lennert Buytenhek
 P:	Lennert Buytenhek
 M:	kernel@wantstofly.org
 M:	kernel@wantstofly.org
+P:	Dan Williams
+M:	dan.j.williams@intel.com
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-S:	Maintained
+S:	Supported
 
 
 ARM/INTEL IQ81342EX MACHINE SUPPORT
 ARM/INTEL IQ81342EX MACHINE SUPPORT
 P:	Lennert Buytenhek
 P:	Lennert Buytenhek
 M:	kernel@wantstofly.org
 M:	kernel@wantstofly.org
+P:	Dan Williams
+M:	dan.j.williams@intel.com
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-S:	Maintained
+S:	Supported
 
 
 ARM/INTEL IXP2000 ARM ARCHITECTURE
 ARM/INTEL IXP2000 ARM ARCHITECTURE
 P:	Lennert Buytenhek
 P:	Lennert Buytenhek
@@ -448,8 +460,10 @@ S:	Maintained
 ARM/INTEL XSC3 (MANZANO) ARM CORE
 ARM/INTEL XSC3 (MANZANO) ARM CORE
 P:	Lennert Buytenhek
 P:	Lennert Buytenhek
 M:	kernel@wantstofly.org
 M:	kernel@wantstofly.org
+P:	Dan Williams
+M:	dan.j.williams@intel.com
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-S:	Maintained
+S:	Supported
 
 
 ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT
 ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT
 P:	Lennert Buytenhek
 P:	Lennert Buytenhek

+ 8 - 4
arch/arm/kernel/entry-armv.S

@@ -436,7 +436,7 @@ __und_usr:
 	usr_entry
 	usr_entry
 
 
 	tst	r3, #PSR_T_BIT			@ Thumb mode?
 	tst	r3, #PSR_T_BIT			@ Thumb mode?
-	bne	fpundefinstr			@ ignore FP
+	bne	__und_usr_unknown		@ ignore FP
 	sub	r4, r2, #4
 	sub	r4, r2, #4
 
 
 	@
 	@
@@ -448,7 +448,7 @@ __und_usr:
 	@
 	@
 1:	ldrt	r0, [r4]
 1:	ldrt	r0, [r4]
 	adr	r9, ret_from_exception
 	adr	r9, ret_from_exception
-	adr	lr, fpundefinstr
+	adr	lr, __und_usr_unknown
 	@
 	@
 	@ fallthrough to call_fpe
 	@ fallthrough to call_fpe
 	@
 	@
@@ -476,7 +476,9 @@ __und_usr:
  * Emulators may wish to make use of the following registers:
  * Emulators may wish to make use of the following registers:
  *  r0  = instruction opcode.
  *  r0  = instruction opcode.
  *  r2  = PC+4
  *  r2  = PC+4
+ *  r9  = normal "successful" return address
  *  r10 = this threads thread_info structure.
  *  r10 = this threads thread_info structure.
+ *  lr  = unrecognised instruction return address
  */
  */
 call_fpe:
 call_fpe:
 	tst	r0, #0x08000000			@ only CDP/CPRT/LDC/STC have bit 27
 	tst	r0, #0x08000000			@ only CDP/CPRT/LDC/STC have bit 27
@@ -545,10 +547,12 @@ do_fpe:
 
 
 	.data
 	.data
 ENTRY(fp_enter)
 ENTRY(fp_enter)
-	.word	fpundefinstr
+	.word	no_fp
 	.text
 	.text
 
 
-fpundefinstr:
+no_fp:	mov	pc, lr
+
+__und_usr_unknown:
 	mov	r0, sp
 	mov	r0, sp
 	adr	lr, ret_from_exception
 	adr	lr, ret_from_exception
 	b	do_undefinstr
 	b	do_undefinstr

+ 13 - 0
arch/arm/kernel/time.c

@@ -29,6 +29,8 @@
 #include <linux/timer.h>
 #include <linux/timer.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
 
 
+#include <linux/mc146818rtc.h>
+
 #include <asm/leds.h>
 #include <asm/leds.h>
 #include <asm/thread_info.h>
 #include <asm/thread_info.h>
 #include <asm/mach/time.h>
 #include <asm/mach/time.h>
@@ -85,6 +87,17 @@ unsigned long long __attribute__((weak)) sched_clock(void)
 	return (unsigned long long)jiffies * (1000000000 / HZ);
 	return (unsigned long long)jiffies * (1000000000 / HZ);
 }
 }
 
 
+/*
+ * An implementation of printk_clock() independent from
+ * sched_clock().  This avoids non-bootable kernels when
+ * printk_clock is enabled.
+ */
+unsigned long long printk_clock(void)
+{
+	return (unsigned long long)(jiffies - INITIAL_JIFFIES) *
+			(1000000000 / HZ);
+}
+
 static unsigned long next_rtc_update;
 static unsigned long next_rtc_update;
 
 
 /*
 /*

+ 1 - 0
arch/arm/kernel/traps.c

@@ -27,6 +27,7 @@
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/unistd.h>
 #include <asm/traps.h>
 #include <asm/traps.h>
+#include <asm/io.h>
 
 
 #include "ptrace.h"
 #include "ptrace.h"
 #include "signal.h"
 #include "signal.h"

+ 39 - 0
arch/arm/mm/flush.c

@@ -202,3 +202,42 @@ void flush_dcache_page(struct page *page)
 	}
 	}
 }
 }
 EXPORT_SYMBOL(flush_dcache_page);
 EXPORT_SYMBOL(flush_dcache_page);
+
+/*
+ * Flush an anonymous page so that users of get_user_pages()
+ * can safely access the data.  The expected sequence is:
+ *
+ *  get_user_pages()
+ *    -> flush_anon_page
+ *  memcpy() to/from page
+ *  if written to page, flush_dcache_page()
+ */
+void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
+{
+	unsigned long pfn;
+
+	/* VIPT non-aliasing caches need do nothing */
+	if (cache_is_vipt_nonaliasing())
+		return;
+
+	/*
+	 * Write back and invalidate userspace mapping.
+	 */
+	pfn = page_to_pfn(page);
+	if (cache_is_vivt()) {
+		flush_cache_page(vma, vmaddr, pfn);
+	} else {
+		/*
+		 * For aliasing VIPT, we can flush an alias of the
+		 * userspace address only.
+		 */
+		flush_pfn_alias(pfn, vmaddr);
+	}
+
+	/*
+	 * Invalidate kernel mapping.  No data should be contained
+	 * in this mapping of the page.  FIXME: this is overkill
+	 * since we actually ask for a write-back and invalidate.
+	 */
+	__cpuc_flush_dcache_page(page_address(page));
+}

+ 4 - 0
drivers/mmc/mmci.c

@@ -42,6 +42,8 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 {
 {
 	writel(0, host->base + MMCICOMMAND);
 	writel(0, host->base + MMCICOMMAND);
 
 
+	BUG_ON(host->data);
+
 	host->mrq = NULL;
 	host->mrq = NULL;
 	host->cmd = NULL;
 	host->cmd = NULL;
 
 
@@ -198,6 +200,8 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
 	}
 	}
 
 
 	if (!cmd->data || cmd->error != MMC_ERR_NONE) {
 	if (!cmd->data || cmd->error != MMC_ERR_NONE) {
+		if (host->data)
+			mmci_stop_data(host);
 		mmci_request_end(host, cmd->mrq);
 		mmci_request_end(host, cmd->mrq);
 	} else if (!(cmd->data->flags & MMC_DATA_READ)) {
 	} else if (!(cmd->data->flags & MMC_DATA_READ)) {
 		mmci_start_data(host, cmd->data);
 		mmci_start_data(host, cmd->data);

+ 1 - 1
include/asm-arm/arch-iop32x/iop32x.h

@@ -19,7 +19,7 @@
  * Peripherals that are shared between the iop32x and iop33x but
  * Peripherals that are shared between the iop32x and iop33x but
  * located at different addresses.
  * located at different addresses.
  */
  */
-#define IOP3XX_GPIO_REG(reg)	(IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c0 + (reg))
+#define IOP3XX_GPIO_REG(reg)	(IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c4 + (reg))
 #define IOP3XX_TIMER_REG(reg)	(IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg))
 #define IOP3XX_TIMER_REG(reg)	(IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg))
 
 
 #include <asm/hardware/iop3xx.h>
 #include <asm/hardware/iop3xx.h>

+ 10 - 0
include/asm-arm/cacheflush.h

@@ -357,6 +357,16 @@ extern void flush_dcache_page(struct page *);
 
 
 extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
 extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
 
 
+#define ARCH_HAS_FLUSH_ANON_PAGE
+static inline void flush_anon_page(struct vm_area_struct *vma,
+			 struct page *page, unsigned long vmaddr)
+{
+	extern void __flush_anon_page(struct vm_area_struct *vma,
+				struct page *, unsigned long);
+	if (PageAnon(page))
+		__flush_anon_page(vma, page, vmaddr);
+}
+
 #define flush_dcache_mmap_lock(mapping) \
 #define flush_dcache_mmap_lock(mapping) \
 	write_lock_irq(&(mapping)->tree_lock)
 	write_lock_irq(&(mapping)->tree_lock)
 #define flush_dcache_mmap_unlock(mapping) \
 #define flush_dcache_mmap_unlock(mapping) \

+ 3 - 3
include/asm-arm/hardware/iop3xx.h

@@ -168,9 +168,9 @@ extern void gpio_line_set(int line, int value);
 #define IOP3XX_PERCR0		(volatile u32 *)IOP3XX_REG_ADDR(0x0710)
 #define IOP3XX_PERCR0		(volatile u32 *)IOP3XX_REG_ADDR(0x0710)
 
 
 /* General Purpose I/O  */
 /* General Purpose I/O  */
-#define IOP3XX_GPOE		(volatile u32 *)IOP3XX_GPIO_REG(0x0004)
-#define IOP3XX_GPID		(volatile u32 *)IOP3XX_GPIO_REG(0x0008)
-#define IOP3XX_GPOD		(volatile u32 *)IOP3XX_GPIO_REG(0x000c)
+#define IOP3XX_GPOE		(volatile u32 *)IOP3XX_GPIO_REG(0x0000)
+#define IOP3XX_GPID		(volatile u32 *)IOP3XX_GPIO_REG(0x0004)
+#define IOP3XX_GPOD		(volatile u32 *)IOP3XX_GPIO_REG(0x0008)
 
 
 /* Timers  */
 /* Timers  */
 #define IOP3XX_TU_TMR0		(volatile u32 *)IOP3XX_TIMER_REG(0x0000)
 #define IOP3XX_TU_TMR0		(volatile u32 *)IOP3XX_TIMER_REG(0x0000)

+ 1 - 1
include/asm-parisc/cacheflush.h

@@ -186,7 +186,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
 }
 }
 
 
 static inline void
 static inline void
-flush_anon_page(struct page *page, unsigned long vmaddr)
+flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
 {
 {
 	if (PageAnon(page))
 	if (PageAnon(page))
 		flush_user_dcache_page(vmaddr);
 		flush_user_dcache_page(vmaddr);

+ 1 - 1
include/linux/highmem.h

@@ -8,7 +8,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 
 
 #ifndef ARCH_HAS_FLUSH_ANON_PAGE
 #ifndef ARCH_HAS_FLUSH_ANON_PAGE
-static inline void flush_anon_page(struct page *page, unsigned long vmaddr)
+static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
 {
 {
 }
 }
 #endif
 #endif

+ 1 - 1
mm/memory.c

@@ -1091,7 +1091,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 			if (pages) {
 			if (pages) {
 				pages[i] = page;
 				pages[i] = page;
 
 
-				flush_anon_page(page, start);
+				flush_anon_page(vma, page, start);
 				flush_dcache_page(page);
 				flush_dcache_page(page);
 			}
 			}
 			if (vmas)
 			if (vmas)