Commit c2a65d3d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS fixes from Ralf Baechle:
 "Three issues fixed accross the field:

   - Some functions that were recently outlined as part of a preemption
     fix were causing problems with function tracing.
   - The recently merged in-kernel MPI library uses very outdated
     headers that contain MIPS-specific code which won't build on with
     gcc 4.4 or newer.
   - The MIPS non-NUMA memory initialization was making only a very
     half-baked attempt at merging adjacent memory ranges.  This kept
     the code simple enough but is now causing issues with kexec."

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus:
  MPI: Fix compilation on MIPS with GCC 4.4 and newer
  MIPS: Fix crash that occurs when function tracing is enabled
  MIPS: Merge overlapping bootmem ranges
parents 194d9831 a3cea989
...@@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", }; ...@@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", };
void __init add_memory_region(phys_t start, phys_t size, long type) void __init add_memory_region(phys_t start, phys_t size, long type)
{ {
int x = boot_mem_map.nr_map; int x = boot_mem_map.nr_map;
struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; int i;
/* Sanity check */ /* Sanity check */
if (start + size < start) { if (start + size < start) {
...@@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type) ...@@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type)
} }
/* /*
* Try to merge with previous entry if any. This is far less than * Try to merge with existing entry, if any.
* perfect but is sufficient for most real world cases.
*/ */
if (x && prev->addr + prev->size == start && prev->type == type) { for (i = 0; i < boot_mem_map.nr_map; i++) {
prev->size += size; struct boot_mem_map_entry *entry = boot_mem_map.map + i;
unsigned long top;
if (entry->type != type)
continue;
if (start + size < entry->addr)
continue; /* no overlap */
if (entry->addr + entry->size < start)
continue; /* no overlap */
top = max(entry->addr + entry->size, start + size);
entry->addr = min(entry->addr, start);
entry->size = top - entry->addr;
return; return;
} }
if (x == BOOT_MEM_MAP_MAX) { if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) {
pr_err("Ooops! Too many entries in the memory map!\n"); pr_err("Ooops! Too many entries in the memory map!\n");
return; return;
} }
......
...@@ -56,7 +56,7 @@ __asm__( ...@@ -56,7 +56,7 @@ __asm__(
" .set pop \n" " .set pop \n"
" .endm \n"); " .endm \n");
void arch_local_irq_disable(void) notrace void arch_local_irq_disable(void)
{ {
preempt_disable(); preempt_disable();
__asm__ __volatile__( __asm__ __volatile__(
...@@ -93,7 +93,7 @@ __asm__( ...@@ -93,7 +93,7 @@ __asm__(
" .set pop \n" " .set pop \n"
" .endm \n"); " .endm \n");
unsigned long arch_local_irq_save(void) notrace unsigned long arch_local_irq_save(void)
{ {
unsigned long flags; unsigned long flags;
preempt_disable(); preempt_disable();
...@@ -135,7 +135,7 @@ __asm__( ...@@ -135,7 +135,7 @@ __asm__(
" .set pop \n" " .set pop \n"
" .endm \n"); " .endm \n");
void arch_local_irq_restore(unsigned long flags) notrace void arch_local_irq_restore(unsigned long flags)
{ {
unsigned long __tmp1; unsigned long __tmp1;
...@@ -159,7 +159,7 @@ void arch_local_irq_restore(unsigned long flags) ...@@ -159,7 +159,7 @@ void arch_local_irq_restore(unsigned long flags)
EXPORT_SYMBOL(arch_local_irq_restore); EXPORT_SYMBOL(arch_local_irq_restore);
void __arch_local_irq_restore(unsigned long flags) notrace void __arch_local_irq_restore(unsigned long flags)
{ {
unsigned long __tmp1; unsigned long __tmp1;
......
...@@ -641,7 +641,14 @@ do { \ ...@@ -641,7 +641,14 @@ do { \
************** MIPS ***************** ************** MIPS *****************
***************************************/ ***************************************/
#if defined(__mips__) && W_TYPE_SIZE == 32 #if defined(__mips__) && W_TYPE_SIZE == 32
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4
#define umul_ppmm(w1, w0, u, v) \
do { \
UDItype __ll = (UDItype)(u) * (v); \
w1 = __ll >> 32; \
w0 = __ll; \
} while (0)
#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
#define umul_ppmm(w1, w0, u, v) \ #define umul_ppmm(w1, w0, u, v) \
__asm__ ("multu %2,%3" \ __asm__ ("multu %2,%3" \
: "=l" ((USItype)(w0)), \ : "=l" ((USItype)(w0)), \
...@@ -666,7 +673,15 @@ do { \ ...@@ -666,7 +673,15 @@ do { \
************** MIPS/64 ************** ************** MIPS/64 **************
***************************************/ ***************************************/
#if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4
#define umul_ppmm(w1, w0, u, v) \
do { \
typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
__ll_UTItype __ll = (__ll_UTItype)(u) * (v); \
w1 = __ll >> 64; \
w0 = __ll; \
} while (0)
#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
#define umul_ppmm(w1, w0, u, v) \ #define umul_ppmm(w1, w0, u, v) \
__asm__ ("dmultu %2,%3" \ __asm__ ("dmultu %2,%3" \
: "=l" ((UDItype)(w0)), \ : "=l" ((UDItype)(w0)), \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment