Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 2 May 2013 17:16:16 +0000 (10:16 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 2 May 2013 17:16:16 +0000 (10:16 -0700)
Pull powerpc update from Benjamin Herrenschmidt:
 "The main highlights this time around are:

   - A pile of addition POWER8 bits and nits, such as updated
     performance counter support (Michael Ellerman), new branch history
     buffer support (Anshuman Khandual), base support for the new PCI
     host bridge when not using the hypervisor (Gavin Shan) and other
     random related bits and fixes from various contributors.

   - Some rework of our page table format by Aneesh Kumar which fixes a
     thing or two and paves the way for THP support.  THP itself will
     not make it this time around however.

   - More Freescale updates, including Altivec support on the new e6500
     cores, new PCI controller support, and a pile of new boards support
     and updates.

   - The usual batch of trivial cleanups & fixes"

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (156 commits)
  powerpc: Fix build error for book3e
  powerpc: Context switch the new EBB SPRs
  powerpc: Turn on the EBB H/FSCR bits
  powerpc: Replace CPU_FTR_BCTAR with CPU_FTR_ARCH_207S
  powerpc: Setup BHRB instructions facility in HFSCR for POWER8
  powerpc: Fix interrupt range check on debug exception
  powerpc: Update tlbie/tlbiel as per ISA doc
  powerpc: Print page size info during boot
  powerpc: print both base and actual page size on hash failure
  powerpc: Fix hpte_decode to use the correct decoding for page sizes
  powerpc: Decode the pte-lp-encoding bits correctly.
  powerpc: Use encode avpn where we need only avpn values
  powerpc: Reduce PTE table memory wastage
  powerpc: Move the pte free routines from common header
  powerpc: Reduce the PTE_INDEX_SIZE
  powerpc: Switch 16GB and 16MB explicit hugepages to a different page table format
  powerpc: New hugepage directory format
  powerpc: Don't truncate pgd_index wrongly
  powerpc: Don't hard code the size of pte page
  powerpc: Save DAR and DSISR in pt_regs on MCE
  ...

18 files changed:
1  2 
arch/metag/mm/Kconfig
arch/powerpc/Kconfig
arch/powerpc/include/asm/hugetlb.h
arch/powerpc/kernel/lparcfg.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/rtas_flash.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/numa.c
arch/powerpc/platforms/512x/Kconfig
arch/powerpc/platforms/512x/mpc512x_shared.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/xmon/xmon.c
drivers/macintosh/via-pmu.c
drivers/pci/probe.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c

diff --combined arch/metag/mm/Kconfig
index 794f26a187f9b153807ce50222db2238752f287f,ccf2576786eeca2ea1affec597bdd44894ea2151..03fb8f1555a1a5778a04b817ce57c2fa2ad47647
@@@ -93,11 -93,9 +93,6 @@@ config ARCH_SPARSEMEM_ENABL
  config ARCH_SPARSEMEM_DEFAULT
        def_bool y
  
- config MAX_ACTIVE_REGIONS
-       int
-       default "2" if SPARSEMEM
-       default "1"
 -config ARCH_POPULATES_NODE_MAP
 -      def_bool y
--
  config ARCH_SELECT_MEMORY_MODEL
        def_bool y
  
diff --combined arch/powerpc/Kconfig
index a0259edae5c9165bac4f33b551f87ac529b7ad18,84cb0c932153bc4720da26fff8cf7de305db733c..bbbe02197afbdf151858beecc662adb7b5cddd0c
@@@ -114,6 -114,7 +114,6 @@@ config PP
        select USE_GENERIC_SMP_HELPERS if SMP
        select HAVE_OPROFILE
        select HAVE_DEBUG_KMEMLEAK
 -      select HAVE_SYSCALL_WRAPPERS if PPC64
        select GENERIC_ATOMIC64 if PPC32
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
        select HAVE_PERF_EVENTS
@@@ -427,11 -428,6 +427,6 @@@ config NODES_SHIF
        default "4"
        depends on NEED_MULTIPLE_NODES
  
- config MAX_ACTIVE_REGIONS
-       int
-       default "256" if PPC64
-       default "32"
  config ARCH_SELECT_MEMORY_MODEL
        def_bool y
        depends on PPC64
@@@ -646,14 -642,14 +641,14 @@@ menu "Bus options
  
  config ISA
        bool "Support for ISA-bus hardware"
-       depends on PPC_PREP || PPC_CHRP
+       depends on PPC_CHRP
        select PPC_I8259
        help
          Find out whether you have ISA slots on your motherboard.  ISA is the
          name of a bus system, i.e. the way the CPU talks to the other stuff
          inside your box.  If you have an Apple machine, say N here; if you
-         have an IBM RS/6000 or pSeries machine or a PReP machine, say Y.  If
-         you have an embedded board, consult your board documentation.
+         have an IBM RS/6000 or pSeries machine, say Y.  If you have an
+         embedded board, consult your board documentation.
  
  config ZONE_DMA
        bool
@@@ -685,7 -681,6 +680,6 @@@ config SBU
  config FSL_SOC
        bool
        select HAVE_CAN_FLEXCAN if NET && CAN
-       select PPC_CLOCK
  
  config FSL_PCI
        bool
@@@ -744,7 -739,6 +738,6 @@@ config PC
        bool "PCI support" if PPC_PCI_CHOICE
        default y if !40x && !CPM2 && !8xx && !PPC_83xx \
                && !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON
-       default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
        default PCI_QSPAN if !4xx && !CPM2 && 8xx
        select ARCH_SUPPORTS_MSI
        select GENERIC_PCI_IOMAP
@@@ -774,11 -768,6 +767,6 @@@ config PCI_826
        select PPC_INDIRECT_PCI
        default y
  
- config 8260_PCI9
-       bool "Enable workaround for MPC826x erratum PCI 9"
-       depends on PCI_8260 && !8272
-       default y
  source "drivers/pci/pcie/Kconfig"
  
  source "drivers/pci/Kconfig"
@@@ -968,7 -957,7 +956,7 @@@ config TASK_SIZE_BOO
  
  config TASK_SIZE
        hex "Size of user task space" if TASK_SIZE_BOOL
-       default "0x80000000" if PPC_PREP || PPC_8xx
+       default "0x80000000" if PPC_8xx
        default "0xc0000000"
  
  config CONSISTENT_SIZE_BOOL
index 4fcbd6b14a3adba4184bce01110b990ca63bc8b2,4daf7e684f580f5702d08b1fb94b9af887bbd87c..f2498c8e595d0b5c936e0a2981643d2323cc462c
@@@ -3,10 -3,36 +3,37 @@@
  
  #ifdef CONFIG_HUGETLB_PAGE
  #include <asm/page.h>
 +#include <asm-generic/hugetlb.h>
  
  extern struct kmem_cache *hugepte_cache;
  
+ #ifdef CONFIG_PPC_BOOK3S_64
+ /*
+  * This should work for other subarchs too. But right now we use the
+  * new format only for 64bit book3s
+  */
+ static inline pte_t *hugepd_page(hugepd_t hpd)
+ {
+       BUG_ON(!hugepd_ok(hpd));
+       /*
+        * We have only four bits to encode, MMU page size
+        */
+       BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf);
+       return (pte_t *)(hpd.pd & ~HUGEPD_SHIFT_MASK);
+ }
+ static inline unsigned int hugepd_mmu_psize(hugepd_t hpd)
+ {
+       return (hpd.pd & HUGEPD_SHIFT_MASK) >> 2;
+ }
+ static inline unsigned int hugepd_shift(hugepd_t hpd)
+ {
+       return mmu_psize_to_shift(hugepd_mmu_psize(hpd));
+ }
+ #else
  static inline pte_t *hugepd_page(hugepd_t hpd)
  {
        BUG_ON(!hugepd_ok(hpd));
@@@ -18,6 -44,9 +45,9 @@@ static inline unsigned int hugepd_shift
        return hpd.pd & HUGEPD_SHIFT_MASK;
  }
  
+ #endif /* CONFIG_PPC_BOOK3S_64 */
  static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr,
                                    unsigned pdshift)
  {
index 801a757c363000fc7f5c4bc44bfcd51b3f30a239,ab297f492c678a304d075f1595d4db6fecada721..d92f3871e9cf959b583cf35b03de95929fc253ed
@@@ -41,6 -41,8 +41,6 @@@
  
  /* #define LPARCFG_DEBUG */
  
 -static struct proc_dir_entry *proc_ppc64_lparcfg;
 -
  /*
   * Track sum of all purrs across all processors. This is used to further
   * calculate usage values by different applications
@@@ -299,6 -301,7 +299,7 @@@ static void parse_system_parameter_stri
                                __pa(rtas_data_buf),
                                RTAS_DATA_BUF_SIZE);
        memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
+       local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
        spin_unlock(&rtas_data_buf_lock);
  
        if (call_status != 0) {
@@@ -686,22 -689,27 +687,22 @@@ static const struct file_operations lpa
  
  static int __init lparcfg_init(void)
  {
 -      struct proc_dir_entry *ent;
        umode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
  
        /* Allow writing if we have FW_FEATURE_SPLPAR */
        if (firmware_has_feature(FW_FEATURE_SPLPAR))
                mode |= S_IWUSR;
  
 -      ent = proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops);
 -      if (!ent) {
 +      if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops)) {
                printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
                return -EIO;
        }
 -
 -      proc_ppc64_lparcfg = ent;
        return 0;
  }
  
  static void __exit lparcfg_cleanup(void)
  {
 -      if (proc_ppc64_lparcfg)
 -              remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
 +      remove_proc_subtree("powerpc/lparcfg", NULL);
  }
  
  module_init(lparcfg_init);
index 13a8d9d0b5cbd9d098861725e28607cfb7c36515,c0dea6f23567dbcd965bc99af04aa9b3ff9b2034..ceb4e7b62cf441ed6237499d11ef15cc6e2e4d50
@@@ -831,8 -831,6 +831,8 @@@ void show_regs(struct pt_regs * regs
  {
        int i, trap;
  
 +      show_regs_print_info(KERN_DEFAULT);
 +
        printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
               regs->nip, regs->link, regs->ctr);
        printk("REGS: %p TRAP: %04lx   %s  (%s)\n",
  #else
                printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr);
  #endif
 -      printk("TASK = %p[%d] '%s' THREAD: %p",
 -             current, task_pid_nr(current), current->comm, task_thread_info(current));
 -
 -#ifdef CONFIG_SMP
 -      printk(" CPU: %d", raw_smp_processor_id());
 -#endif /* CONFIG_SMP */
  
        for (i = 0;  i < 32;  i++) {
                if ((i % REGS_PER_LINE) == 0)
@@@ -908,10 -912,6 +908,6 @@@ int arch_dup_task_struct(struct task_st
        flush_altivec_to_thread(src);
        flush_vsx_to_thread(src);
        flush_spe_to_thread(src);
- #ifdef CONFIG_HAVE_HW_BREAKPOINT
-       flush_ptrace_hw_breakpoint(src);
- #endif /* CONFIG_HAVE_HW_BREAKPOINT */
        *dst = *src;
        return 0;
  }
@@@ -982,6 -982,10 +978,10 @@@ int copy_thread(unsigned long clone_fla
        p->thread.ksp_limit = (unsigned long)task_stack_page(p) +
                                _ALIGN_UP(sizeof(struct thread_info), 16);
  
+ #ifdef CONFIG_HAVE_HW_BREAKPOINT
+       p->thread.ptrace_bps[0] = NULL;
+ #endif
  #ifdef CONFIG_PPC_STD_MMU_64
        if (mmu_has_feature(MMU_FTR_SLB)) {
                unsigned long sp_vsid;
@@@ -1358,6 -1362,12 +1358,6 @@@ void show_stack(struct task_struct *tsk
        } while (count++ < kstack_depth_to_print);
  }
  
 -void dump_stack(void)
 -{
 -      show_stack(current, NULL);
 -}
 -EXPORT_SYMBOL(dump_stack);
 -
  #ifdef CONFIG_PPC64
  /* Called with hard IRQs off */
  void __ppc64_runlatch_on(void)
index 5b770262c6737034dcb5c9947bde05375c71250f,243e184cbe45aaa4fb3f8cd4fbbf9aec3ca8b3e3..5b3022470126ce1787bb259c89b319d7f7e9770f
  #define VALIDATE_READY               -1001 /* Firmware image ready for validation */
  #define VALIDATE_PARAM_ERR     -3    /* RTAS Parameter Error */
  #define VALIDATE_HW_ERR        -1    /* RTAS Hardware Error */
- #define VALIDATE_TMP_UPDATE    0     /* Validate Return Status */
- #define VALIDATE_FLASH_AUTH    1     /* Validate Return Status */
- #define VALIDATE_INVALID_IMG   2     /* Validate Return Status */
- #define VALIDATE_CUR_UNKNOWN   3     /* Validate Return Status */
- #define VALIDATE_TMP_COMMIT_DL 4     /* Validate Return Status */
- #define VALIDATE_TMP_COMMIT    5     /* Validate Return Status */
- #define VALIDATE_TMP_UPDATE_DL 6     /* Validate Return Status */
+ /* ibm,validate-flash-image update result tokens */
+ #define VALIDATE_TMP_UPDATE    0     /* T side will be updated */
+ #define VALIDATE_FLASH_AUTH    1     /* Partition does not have authority */
+ #define VALIDATE_INVALID_IMG   2     /* Candidate image is not valid */
+ #define VALIDATE_CUR_UNKNOWN   3     /* Current fixpack level is unknown */
+ /*
+  * Current T side will be committed to P side before being replace with new
+  * image, and the new image is downlevel from current image
+  */
+ #define VALIDATE_TMP_COMMIT_DL 4
+ /*
+  * Current T side will be committed to P side before being replaced with new
+  * image
+  */
+ #define VALIDATE_TMP_COMMIT    5
+ /*
+  * T side will be updated with a downlevel image
+  */
+ #define VALIDATE_TMP_UPDATE_DL 6
+ /*
+  * The candidate image's release date is later than the system's firmware
+  * service entitlement date - service warranty period has expired
+  */
+ #define VALIDATE_OUT_OF_WRNTY  7
  
  /* ibm,manage-flash-image operation tokens */
  #define RTAS_REJECT_TMP_IMG   0
@@@ -102,10 -120,9 +120,10 @@@ static struct kmem_cache *flash_block_c
  
  #define FLASH_BLOCK_LIST_VERSION (1UL)
  
 -/* Local copy of the flash block list.
 - * We only allow one open of the flash proc file and create this
 - * list as we go.  The rtas_firmware_flash_list varable will be
 +/*
 + * Local copy of the flash block list.
 + *
 + * The rtas_firmware_flash_list varable will be
   * set once the data is fully read.
   *
   * For convenience as we build the list we use virtual addrs,
@@@ -126,23 -143,23 +144,23 @@@ struct rtas_update_flash_
  struct rtas_manage_flash_t
  {
        int status;                     /* Returned status */
 -      unsigned int op;                /* Reject or commit image */
  };
  
  /* Status int must be first member of struct */
  struct rtas_validate_flash_t
  {
        int status;                     /* Returned status */   
 -      char buf[VALIDATE_BUF_SIZE];    /* Candidate image buffer */
 +      char *buf;                      /* Candidate image buffer */
        unsigned int buf_size;          /* Size of image buf */
        unsigned int update_results;    /* Update results token */
  };
  
 -static DEFINE_SPINLOCK(flash_file_open_lock);
 -static struct proc_dir_entry *firmware_flash_pde;
 -static struct proc_dir_entry *firmware_update_pde;
 -static struct proc_dir_entry *validate_pde;
 -static struct proc_dir_entry *manage_pde;
 +static struct rtas_update_flash_t rtas_update_flash_data;
 +static struct rtas_manage_flash_t rtas_manage_flash_data;
 +static struct rtas_validate_flash_t rtas_validate_flash_data;
 +static DEFINE_MUTEX(rtas_update_flash_mutex);
 +static DEFINE_MUTEX(rtas_manage_flash_mutex);
 +static DEFINE_MUTEX(rtas_validate_flash_mutex);
  
  /* Do simple sanity checks on the flash image. */
  static int flash_list_valid(struct flash_block_list *flist)
@@@ -192,10 -209,10 +210,10 @@@ static void free_flash_list(struct flas
  
  static int rtas_flash_release(struct inode *inode, struct file *file)
  {
 -      struct proc_dir_entry *dp = PDE(file_inode(file));
 -      struct rtas_update_flash_t *uf;
 -      
 -      uf = (struct rtas_update_flash_t *) dp->data;
 +      struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
 +
 +      mutex_lock(&rtas_update_flash_mutex);
 +
        if (uf->flist) {    
                /* File was opened in write mode for a new flash attempt */
                /* Clear saved list */
                uf->flist = NULL;
        }
  
 -      atomic_dec(&dp->count);
 +      mutex_unlock(&rtas_update_flash_mutex);
        return 0;
  }
  
 -static void get_flash_status_msg(int status, char *buf)
 +static size_t get_flash_status_msg(int status, char *buf)
  {
 -      char *msg;
 +      const char *msg;
 +      size_t len;
  
        switch (status) {
        case FLASH_AUTH:
                msg = "ready: firmware image ready for flash on reboot\n";
                break;
        default:
 -              sprintf(buf, "error: unexpected status value %d\n", status);
 -              return;
 +              return sprintf(buf, "error: unexpected status value %d\n",
 +                             status);
        }
  
 -      strcpy(buf, msg);       
 +      len = strlen(msg);
 +      memcpy(buf, msg, len + 1);
 +      return len;
  }
  
  /* Reading the proc file will show status (not the firmware contents) */
 -static ssize_t rtas_flash_read(struct file *file, char __user *buf,
 -                             size_t count, loff_t *ppos)
 +static ssize_t rtas_flash_read_msg(struct file *file, char __user *buf,
 +                                 size_t count, loff_t *ppos)
  {
 -      struct proc_dir_entry *dp = PDE(file_inode(file));
 -      struct rtas_update_flash_t *uf;
 +      struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
        char msg[RTAS_MSG_MAXLEN];
 +      size_t len;
 +      int status;
  
 -      uf = dp->data;
 +      mutex_lock(&rtas_update_flash_mutex);
 +      status = uf->status;
 +      mutex_unlock(&rtas_update_flash_mutex);
  
 -      if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) {
 -              get_flash_status_msg(uf->status, msg);
 -      } else {           /* FIRMWARE_UPDATE_NAME */
 -              sprintf(msg, "%d\n", uf->status);
 -      }
 +      /* Read as text message */
 +      len = get_flash_status_msg(status, msg);
 +      return simple_read_from_buffer(buf, count, ppos, msg, len);
 +}
 +
 +static ssize_t rtas_flash_read_num(struct file *file, char __user *buf,
 +                                 size_t count, loff_t *ppos)
 +{
 +      struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
 +      char msg[RTAS_MSG_MAXLEN];
 +      int status;
  
 +      mutex_lock(&rtas_update_flash_mutex);
 +      status = uf->status;
 +      mutex_unlock(&rtas_update_flash_mutex);
 +
 +      /* Read as number */
 +      sprintf(msg, "%d\n", status);
        return simple_read_from_buffer(buf, count, ppos, msg, strlen(msg));
  }
  
- /* constructor for flash_block_cache */
- static void rtas_block_ctor(void *ptr)
- {
-       memset(ptr, 0, RTAS_BLK_SIZE);
- }
  /* We could be much more efficient here.  But to keep this function
   * simple we allocate a page to the block list no matter how small the
   * count is.  If the system is low on memory it will be just as well
  static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
                                size_t count, loff_t *off)
  {
 -      struct proc_dir_entry *dp = PDE(file_inode(file));
 -      struct rtas_update_flash_t *uf;
 +      struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
        char *p;
 -      int next_free;
 +      int next_free, rc;
        struct flash_block_list *fl;
  
 -      uf = (struct rtas_update_flash_t *) dp->data;
 +      mutex_lock(&rtas_update_flash_mutex);
  
        if (uf->status == FLASH_AUTH || count == 0)
 -              return count;   /* discard data */
 +              goto out;       /* discard data */
  
        /* In the case that the image is not ready for flashing, the memory
         * allocated for the block list will be freed upon the release of the 
         * proc file
         */
        if (uf->flist == NULL) {
-               uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
+               uf->flist = kmem_cache_zalloc(flash_block_cache, GFP_KERNEL);
                if (!uf->flist)
 -                      return -ENOMEM;
 +                      goto nomem;
        }
  
        fl = uf->flist;
        next_free = fl->num_blocks;
        if (next_free == FLASH_BLOCKS_PER_NODE) {
                /* Need to allocate another block_list */
-               fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
+               fl->next = kmem_cache_zalloc(flash_block_cache, GFP_KERNEL);
                if (!fl->next)
 -                      return -ENOMEM;
 +                      goto nomem;
                fl = fl->next;
                next_free = 0;
        }
  
        if (count > RTAS_BLK_SIZE)
                count = RTAS_BLK_SIZE;
-       p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
+       p = kmem_cache_zalloc(flash_block_cache, GFP_KERNEL);
        if (!p)
 -              return -ENOMEM;
 +              goto nomem;
        
        if(copy_from_user(p, buffer, count)) {
                kmem_cache_free(flash_block_cache, p);
 -              return -EFAULT;
 +              rc = -EFAULT;
 +              goto error;
        }
        fl->blocks[next_free].data = p;
        fl->blocks[next_free].length = count;
        fl->num_blocks++;
 -
 +out:
 +      mutex_unlock(&rtas_update_flash_mutex);
        return count;
 -}
 -
 -static int rtas_excl_open(struct inode *inode, struct file *file)
 -{
 -      struct proc_dir_entry *dp = PDE(inode);
 -
 -      /* Enforce exclusive open with use count of PDE */
 -      spin_lock(&flash_file_open_lock);
 -      if (atomic_read(&dp->count) > 2) {
 -              spin_unlock(&flash_file_open_lock);
 -              return -EBUSY;
 -      }
 -
 -      atomic_inc(&dp->count);
 -      spin_unlock(&flash_file_open_lock);
 -      
 -      return 0;
 -}
 -
 -static int rtas_excl_release(struct inode *inode, struct file *file)
 -{
 -      struct proc_dir_entry *dp = PDE(inode);
  
 -      atomic_dec(&dp->count);
 -
 -      return 0;
 +nomem:
 +      rc = -ENOMEM;
 +error:
 +      mutex_unlock(&rtas_update_flash_mutex);
 +      return rc;
  }
  
 -static void manage_flash(struct rtas_manage_flash_t *args_buf)
 +/*
 + * Flash management routines.
 + */
 +static void manage_flash(struct rtas_manage_flash_t *args_buf, unsigned int op)
  {
        s32 rc;
  
        do {
 -              rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 
 -                             1, NULL, args_buf->op);
 +              rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 1,
 +                             NULL, op);
        } while (rtas_busy_delay(rc));
  
        args_buf->status = rc;
  static ssize_t manage_flash_read(struct file *file, char __user *buf,
                               size_t count, loff_t *ppos)
  {
 -      struct proc_dir_entry *dp = PDE(file_inode(file));
 -      struct rtas_manage_flash_t *args_buf;
 +      struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data;
        char msg[RTAS_MSG_MAXLEN];
 -      int msglen;
 +      int msglen, status;
  
 -      args_buf = dp->data;
 -      if (args_buf == NULL)
 -              return 0;
 -
 -      msglen = sprintf(msg, "%d\n", args_buf->status);
 +      mutex_lock(&rtas_manage_flash_mutex);
 +      status = args_buf->status;
 +      mutex_unlock(&rtas_manage_flash_mutex);
  
 +      msglen = sprintf(msg, "%d\n", status);
        return simple_read_from_buffer(buf, count, ppos, msg, msglen);
  }
  
  static ssize_t manage_flash_write(struct file *file, const char __user *buf,
                                size_t count, loff_t *off)
  {
 -      struct proc_dir_entry *dp = PDE(file_inode(file));
 -      struct rtas_manage_flash_t *args_buf;
 -      const char reject_str[] = "0";
 -      const char commit_str[] = "1";
 +      struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data;
 +      static const char reject_str[] = "0";
 +      static const char commit_str[] = "1";
        char stkbuf[10];
 -      int op;
 +      int op, rc;
 +
 +      mutex_lock(&rtas_manage_flash_mutex);
  
 -      args_buf = (struct rtas_manage_flash_t *) dp->data;
        if ((args_buf->status == MANAGE_AUTH) || (count == 0))
 -              return count;
 +              goto out;
                
        op = -1;
        if (buf) {
                if (count > 9) count = 9;
 -              if (copy_from_user (stkbuf, buf, count)) {
 -                      return -EFAULT;
 -              }
 +              rc = -EFAULT;
 +              if (copy_from_user (stkbuf, buf, count))
 +                      goto error;
                if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0) 
                        op = RTAS_REJECT_TMP_IMG;
                else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0) 
                        op = RTAS_COMMIT_TMP_IMG;
        }
        
 -      if (op == -1)   /* buf is empty, or contains invalid string */
 -              return -EINVAL;
 -
 -      args_buf->op = op;
 -      manage_flash(args_buf);
 +      if (op == -1) {   /* buf is empty, or contains invalid string */
 +              rc = -EINVAL;
 +              goto error;
 +      }
  
 +      manage_flash(args_buf, op);
 +out:
 +      mutex_unlock(&rtas_manage_flash_mutex);
        return count;
 +
 +error:
 +      mutex_unlock(&rtas_manage_flash_mutex);
 +      return rc;
  }
  
 +/*
 + * Validation routines.
 + */
  static void validate_flash(struct rtas_validate_flash_t *args_buf)
  {
        int token = rtas_token("ibm,validate-flash-image");
@@@ -472,14 -474,14 +484,14 @@@ static int get_validate_flash_msg(struc
  static ssize_t validate_flash_read(struct file *file, char __user *buf,
                               size_t count, loff_t *ppos)
  {
 -      struct proc_dir_entry *dp = PDE(file_inode(file));
 -      struct rtas_validate_flash_t *args_buf;
 +      struct rtas_validate_flash_t *const args_buf =
 +              &rtas_validate_flash_data;
        char msg[RTAS_MSG_MAXLEN];
        int msglen;
  
 -      args_buf = dp->data;
 -
 +      mutex_lock(&rtas_validate_flash_mutex);
        msglen = get_validate_flash_msg(args_buf, msg);
 +      mutex_unlock(&rtas_validate_flash_mutex);
  
        return simple_read_from_buffer(buf, count, ppos, msg, msglen);
  }
  static ssize_t validate_flash_write(struct file *file, const char __user *buf,
                                    size_t count, loff_t *off)
  {
 -      struct proc_dir_entry *dp = PDE(file_inode(file));
 -      struct rtas_validate_flash_t *args_buf;
 +      struct rtas_validate_flash_t *const args_buf =
 +              &rtas_validate_flash_data;
        int rc;
  
 -      args_buf = (struct rtas_validate_flash_t *) dp->data;
 -
 -      if (dp->data == NULL) {
 -              dp->data = kmalloc(sizeof(struct rtas_validate_flash_t), 
 -                              GFP_KERNEL);
 -              if (dp->data == NULL) 
 -                      return -ENOMEM;
 -      }
 +      mutex_lock(&rtas_validate_flash_mutex);
  
        /* We are only interested in the first 4K of the
         * candidate image */
        if ((*off >= VALIDATE_BUF_SIZE) || 
                (args_buf->status == VALIDATE_AUTH)) {
                *off += count;
 +              mutex_unlock(&rtas_validate_flash_mutex);
                return count;
        }
  
        *off += count;
        rc = count;
  done:
 -      if (rc < 0) {
 -              kfree(dp->data);
 -              dp->data = NULL;
 -      }
 +      mutex_unlock(&rtas_validate_flash_mutex);
        return rc;
  }
  
  static int validate_flash_release(struct inode *inode, struct file *file)
  {
 -      struct proc_dir_entry *dp = PDE(file_inode(file));
 -      struct rtas_validate_flash_t *args_buf;
 +      struct rtas_validate_flash_t *const args_buf =
 +              &rtas_validate_flash_data;
  
 -      args_buf = (struct rtas_validate_flash_t *) dp->data;
 +      mutex_lock(&rtas_validate_flash_mutex);
  
        if (args_buf->status == VALIDATE_READY) {
                args_buf->buf_size = VALIDATE_BUF_SIZE;
                validate_flash(args_buf);
        }
  
 -      /* The matching atomic_inc was in rtas_excl_open() */
 -      atomic_dec(&dp->count);
 -
 +      mutex_unlock(&rtas_validate_flash_mutex);
        return 0;
  }
  
 +/*
 + * On-reboot flash update applicator.
 + */
  static void rtas_flash_firmware(int reboot_type)
  {
        unsigned long image_size;
        spin_unlock(&rtas_data_buf_lock);
  }
  
 -static void remove_flash_pde(struct proc_dir_entry *dp)
 -{
 -      if (dp) {
 -              kfree(dp->data);
 -              remove_proc_entry(dp->name, dp->parent);
 -      }
 -}
 -
 -static int initialize_flash_pde_data(const char *rtas_call_name,
 -                                   size_t buf_size,
 -                                   struct proc_dir_entry *dp)
 -{
 +/*
 + * Manifest of proc files to create
 + */
 +struct rtas_flash_file {
 +      const char *filename;
 +      const char *rtas_call_name;
        int *status;
 -      int token;
 -
 -      dp->data = kzalloc(buf_size, GFP_KERNEL);
 -      if (dp->data == NULL)
 -              return -ENOMEM;
 -
 -      /*
 -       * This code assumes that the status int is the first member of the
 -       * struct 
 -       */
 -      status = (int *) dp->data;
 -      token = rtas_token(rtas_call_name);
 -      if (token == RTAS_UNKNOWN_SERVICE)
 -              *status = FLASH_AUTH;
 -      else
 -              *status = FLASH_NO_OP;
 -
 -      return 0;
 -}
 -
 -static struct proc_dir_entry *create_flash_pde(const char *filename,
 -                                             const struct file_operations *fops)
 -{
 -      return proc_create(filename, S_IRUSR | S_IWUSR, NULL, fops);
 -}
 -
 -static const struct file_operations rtas_flash_operations = {
 -      .owner          = THIS_MODULE,
 -      .read           = rtas_flash_read,
 -      .write          = rtas_flash_write,
 -      .open           = rtas_excl_open,
 -      .release        = rtas_flash_release,
 -      .llseek         = default_llseek,
 -};
 -
 -static const struct file_operations manage_flash_operations = {
 -      .owner          = THIS_MODULE,
 -      .read           = manage_flash_read,
 -      .write          = manage_flash_write,
 -      .open           = rtas_excl_open,
 -      .release        = rtas_excl_release,
 -      .llseek         = default_llseek,
 +      const struct file_operations fops;
  };
  
 -static const struct file_operations validate_flash_operations = {
 -      .owner          = THIS_MODULE,
 -      .read           = validate_flash_read,
 -      .write          = validate_flash_write,
 -      .open           = rtas_excl_open,
 -      .release        = validate_flash_release,
 -      .llseek         = default_llseek,
 +static const struct rtas_flash_file rtas_flash_files[] = {
 +      {
 +              .filename       = "powerpc/rtas/" FIRMWARE_FLASH_NAME,
 +              .rtas_call_name = "ibm,update-flash-64-and-reboot",
 +              .status         = &rtas_update_flash_data.status,
 +              .fops.read      = rtas_flash_read_msg,
 +              .fops.write     = rtas_flash_write,
 +              .fops.release   = rtas_flash_release,
 +              .fops.llseek    = default_llseek,
 +      },
 +      {
 +              .filename       = "powerpc/rtas/" FIRMWARE_UPDATE_NAME,
 +              .rtas_call_name = "ibm,update-flash-64-and-reboot",
 +              .status         = &rtas_update_flash_data.status,
 +              .fops.read      = rtas_flash_read_num,
 +              .fops.write     = rtas_flash_write,
 +              .fops.release   = rtas_flash_release,
 +              .fops.llseek    = default_llseek,
 +      },
 +      {
 +              .filename       = "powerpc/rtas/" VALIDATE_FLASH_NAME,
 +              .rtas_call_name = "ibm,validate-flash-image",
 +              .status         = &rtas_validate_flash_data.status,
 +              .fops.read      = validate_flash_read,
 +              .fops.write     = validate_flash_write,
 +              .fops.release   = validate_flash_release,
 +              .fops.llseek    = default_llseek,
 +      },
 +      {
 +              .filename       = "powerpc/rtas/" MANAGE_FLASH_NAME,
 +              .rtas_call_name = "ibm,manage-flash-image",
 +              .status         = &rtas_manage_flash_data.status,
 +              .fops.read      = manage_flash_read,
 +              .fops.write     = manage_flash_write,
 +              .fops.llseek    = default_llseek,
 +      }
  };
  
  static int __init rtas_flash_init(void)
  {
 -      int rc;
 +      int i;
  
        if (rtas_token("ibm,update-flash-64-and-reboot") ==
                       RTAS_UNKNOWN_SERVICE) {
                return 1;
        }
  
 -      firmware_flash_pde = create_flash_pde("powerpc/rtas/"
 -                                            FIRMWARE_FLASH_NAME,
 -                                            &rtas_flash_operations);
 -      if (firmware_flash_pde == NULL) {
 -              rc = -ENOMEM;
 -              goto cleanup;
 -      }
 +      rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
 +      if (!rtas_validate_flash_data.buf)
 +              return -ENOMEM;
  
 -      rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
 -                                     sizeof(struct rtas_update_flash_t), 
 -                                     firmware_flash_pde);
 -      if (rc != 0)
 -              goto cleanup;
 -
 -      firmware_update_pde = create_flash_pde("powerpc/rtas/"
 -                                             FIRMWARE_UPDATE_NAME,
 -                                             &rtas_flash_operations);
 -      if (firmware_update_pde == NULL) {
 -              rc = -ENOMEM;
 -              goto cleanup;
 +      flash_block_cache = kmem_cache_create("rtas_flash_cache",
 +                                            RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
-                                             rtas_block_ctor);
++                                            NULL);
 +      if (!flash_block_cache) {
 +              printk(KERN_ERR "%s: failed to create block cache\n",
 +                              __func__);
 +              goto enomem_buf;
        }
  
 -      rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
 -                                     sizeof(struct rtas_update_flash_t), 
 -                                     firmware_update_pde);
 -      if (rc != 0)
 -              goto cleanup;
 -
 -      validate_pde = create_flash_pde("powerpc/rtas/" VALIDATE_FLASH_NAME,
 -                                      &validate_flash_operations);
 -      if (validate_pde == NULL) {
 -              rc = -ENOMEM;
 -              goto cleanup;
 -      }
 +      for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) {
 +              const struct rtas_flash_file *f = &rtas_flash_files[i];
 +              int token;
  
 -      rc = initialize_flash_pde_data("ibm,validate-flash-image",
 -                                     sizeof(struct rtas_validate_flash_t), 
 -                                     validate_pde);
 -      if (rc != 0)
 -              goto cleanup;
 -
 -      manage_pde = create_flash_pde("powerpc/rtas/" MANAGE_FLASH_NAME,
 -                                    &manage_flash_operations);
 -      if (manage_pde == NULL) {
 -              rc = -ENOMEM;
 -              goto cleanup;
 -      }
 +              if (!proc_create(f->filename, S_IRUSR | S_IWUSR, NULL, &f->fops))
 +                      goto enomem;
  
 -      rc = initialize_flash_pde_data("ibm,manage-flash-image",
 -                                     sizeof(struct rtas_manage_flash_t),
 -                                     manage_pde);
 -      if (rc != 0)
 -              goto cleanup;
 +              /*
 +               * This code assumes that the status int is the first member of the
 +               * struct
 +               */
 +              token = rtas_token(f->rtas_call_name);
 +              if (token == RTAS_UNKNOWN_SERVICE)
 +                      *f->status = FLASH_AUTH;
 +              else
 +                      *f->status = FLASH_NO_OP;
 +      }
  
        rtas_flash_term_hook = rtas_flash_firmware;
 -
 -      flash_block_cache = kmem_cache_create("rtas_flash_cache",
 -                              RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
 -                              NULL);
 -      if (!flash_block_cache) {
 -              printk(KERN_ERR "%s: failed to create block cache\n",
 -                              __func__);
 -              rc = -ENOMEM;
 -              goto cleanup;
 -      }
        return 0;
  
 -cleanup:
 -      remove_flash_pde(firmware_flash_pde);
 -      remove_flash_pde(firmware_update_pde);
 -      remove_flash_pde(validate_pde);
 -      remove_flash_pde(manage_pde);
 +enomem:
 +      while (--i >= 0) {
 +              const struct rtas_flash_file *f = &rtas_flash_files[i];
 +              remove_proc_entry(f->filename, NULL);
 +      }
  
 -      return rc;
 +      kmem_cache_destroy(flash_block_cache);
 +enomem_buf:
 +      kfree(rtas_validate_flash_data.buf);
 +      return -ENOMEM;
  }
  
  static void __exit rtas_flash_cleanup(void)
  {
 +      int i;
 +
        rtas_flash_term_hook = NULL;
  
 -      if (flash_block_cache)
 -              kmem_cache_destroy(flash_block_cache);
+       if (rtas_firmware_flash_list) {
+               free_flash_list(rtas_firmware_flash_list);
+               rtas_firmware_flash_list = NULL;
+       }
 +      for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) {
 +              const struct rtas_flash_file *f = &rtas_flash_files[i];
 +              remove_proc_entry(f->filename, NULL);
 +      }
  
 -      remove_flash_pde(firmware_flash_pde);
 -      remove_flash_pde(firmware_update_pde);
 -      remove_flash_pde(validate_pde);
 -      remove_flash_pde(manage_pde);
 +      kmem_cache_destroy(flash_block_cache);
 +      kfree(rtas_validate_flash_data.buf);
  }
  
  module_init(rtas_flash_init);
index b62bd1b97c6878ffe2c8e655250fccb736b92b0a,c794a4cd0225d7caea3ddf1fe92aab160da995db..f5416934932b17078fb60fdd4b0302df9e7c0e62
@@@ -1483,7 -1483,7 +1483,7 @@@ static int kvm_rma_release(struct inod
        return 0;
  }
  
 -static struct file_operations kvm_rma_fops = {
 +static const struct file_operations kvm_rma_fops = {
        .mmap           = kvm_rma_mmap,
        .release        = kvm_rma_release,
  };
@@@ -1515,7 -1515,13 +1515,13 @@@ static void kvmppc_add_seg_page_size(st
        (*sps)->page_shift = def->shift;
        (*sps)->slb_enc = def->sllp;
        (*sps)->enc[0].page_shift = def->shift;
-       (*sps)->enc[0].pte_enc = def->penc;
+       /*
+        * Only return base page encoding. We don't want to return
+        * all the supporting pte_enc, because our H_ENTER doesn't
+        * support MPSS yet. Once they do, we can start passing all
+        * support pte_enc here
+        */
+       (*sps)->enc[0].pte_enc = def->penc[linux_psize];
        (*sps)++;
  }
  
index 5a535b73ea1833ef18ef0144374420302e62edf1,a56de85ad3b79d49bcb970ea0dc42691eb889b0c..c2787bf779ca0f8730f23b542f54c2657fe77471
@@@ -129,8 -129,7 +129,7 @@@ void pgtable_cache_add(unsigned shift, 
        align = max_t(unsigned long, align, minalign);
        name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift);
        new = kmem_cache_create(name, table_size, align, 0, ctor);
-       PGT_CACHE(shift) = new;
+       pgtable_cache[shift - 1] = new;
        pr_debug("Allocated pgtable cache for order %d\n", shift);
  }
  
@@@ -263,14 -262,19 +262,14 @@@ static __meminit void vmemmap_list_popu
        vmemmap_list = vmem_back;
  }
  
 -int __meminit vmemmap_populate(struct page *start_page,
 -                             unsigned long nr_pages, int node)
 +int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
  {
 -      unsigned long start = (unsigned long)start_page;
 -      unsigned long end = (unsigned long)(start_page + nr_pages);
        unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
  
        /* Align to the page size of the linear mapping. */
        start = _ALIGN_DOWN(start, page_size);
  
 -      pr_debug("vmemmap_populate page %p, %ld pages, node %d\n",
 -               start_page, nr_pages, node);
 -      pr_debug(" -> map %lx..%lx\n", start, end);
 +      pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node);
  
        for (; start < end; start += page_size) {
                void *p;
        return 0;
  }
  
 -void vmemmap_free(struct page *memmap, unsigned long nr_pages)
 +void vmemmap_free(unsigned long start, unsigned long end)
  {
  }
  
diff --combined arch/powerpc/mm/mem.c
index cd76c454942fd51c943c64f33ae2e7e24d3143a5,056732e8ca382b86fa35e7dded18cb5bdc9b06ae..0988a26e04131e5408f8f1f3a16627b21699ad4a
@@@ -66,10 -66,9 +66,9 @@@ unsigned long long memory_limit
  
  #ifdef CONFIG_HIGHMEM
  pte_t *kmap_pte;
+ EXPORT_SYMBOL(kmap_pte);
  pgprot_t kmap_prot;
  EXPORT_SYMBOL(kmap_prot);
- EXPORT_SYMBOL(kmap_pte);
  
  static inline pte_t *virt_to_kpte(unsigned long vaddr)
  {
@@@ -352,9 -351,13 +351,9 @@@ void __init mem_init(void
                        struct page *page = pfn_to_page(pfn);
                        if (memblock_is_reserved(paddr))
                                continue;
 -                      ClearPageReserved(page);
 -                      init_page_count(page);
 -                      __free_page(page);
 -                      totalhigh_pages++;
 +                      free_highmem_page(page);
                        reservedpages--;
                }
 -              totalram_pages += totalhigh_pages;
                printk(KERN_DEBUG "High memory: %luk\n",
                       totalhigh_pages << (PAGE_SHIFT-10));
        }
  
  void free_initmem(void)
  {
 -      unsigned long addr;
 -
        ppc_md.progress = ppc_printk_progress;
 -
 -      addr = (unsigned long)__init_begin;
 -      for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
 -              memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
 -              ClearPageReserved(virt_to_page(addr));
 -              init_page_count(virt_to_page(addr));
 -              free_page(addr);
 -              totalram_pages++;
 -      }
 -      pr_info("Freeing unused kernel memory: %luk freed\n",
 -              ((unsigned long)__init_end -
 -              (unsigned long)__init_begin) >> 10);
 +      free_initmem_default(POISON_FREE_INITMEM);
  }
  
  #ifdef CONFIG_BLK_DEV_INITRD
  void __init free_initrd_mem(unsigned long start, unsigned long end)
  {
 -      if (start >= end)
 -              return;
 -
 -      start = _ALIGN_DOWN(start, PAGE_SIZE);
 -      end = _ALIGN_UP(end, PAGE_SIZE);
 -      pr_info("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 -
 -      for (; start < end; start += PAGE_SIZE) {
 -              ClearPageReserved(virt_to_page(start));
 -              init_page_count(virt_to_page(start));
 -              free_page(start);
 -              totalram_pages++;
 -      }
 +      free_reserved_area(start, end, 0, "initrd");
  }
  #endif
  
diff --combined arch/powerpc/mm/numa.c
index fa33c546e77869bc7596b434bdbf6dafe39a4b4a,c3bd046f801a18b7cac8298375e040fdd91ecb37..88c0425dc0a88f41f61c38b4d01888ec468a937c
  #include <linux/pfn.h>
  #include <linux/cpuset.h>
  #include <linux/node.h>
+ #include <linux/stop_machine.h>
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+ #include <linux/uaccess.h>
  #include <linux/slab.h>
  #include <asm/sparsemem.h>
  #include <asm/prom.h>
@@@ -30,6 -34,7 +34,7 @@@
  #include <asm/paca.h>
  #include <asm/hvcall.h>
  #include <asm/setup.h>
+ #include <asm/vdso.h>
  
  static int numa_enabled = 1;
  
@@@ -63,11 -68,14 +68,11 @@@ static int distance_lookup_table[MAX_NU
   */
  static void __init setup_node_to_cpumask_map(void)
  {
 -      unsigned int node, num = 0;
 +      unsigned int node;
  
        /* setup nr_node_ids if not done yet */
 -      if (nr_node_ids == MAX_NUMNODES) {
 -              for_each_node_mask(node, node_possible_map)
 -                      num = node;
 -              nr_node_ids = num + 1;
 -      }
 +      if (nr_node_ids == MAX_NUMNODES)
 +              setup_nr_node_ids();
  
        /* allocate the map */
        for (node = 0; node < nr_node_ids; node++)
@@@ -77,7 -85,7 +82,7 @@@
        dbg("Node to cpumask map for %d nodes\n", nr_node_ids);
  }
  
- static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
+ static int __init fake_numa_create_new_node(unsigned long end_pfn,
                                                unsigned int *nid)
  {
        unsigned long long mem;
@@@ -199,7 -207,7 +204,7 @@@ int __node_distance(int a, int b
        int distance = LOCAL_DISTANCE;
  
        if (!form1_affinity)
-               return distance;
+               return ((a == b) ? LOCAL_DISTANCE : REMOTE_DISTANCE);
  
        for (i = 0; i < distance_ref_points_depth; i++) {
                if (distance_lookup_table[a][i] == distance_lookup_table[b][i])
@@@ -289,9 -297,7 +294,7 @@@ EXPORT_SYMBOL_GPL(of_node_to_nid)
  static int __init find_min_common_depth(void)
  {
        int depth;
-       struct device_node *chosen;
        struct device_node *root;
-       const char *vec5;
  
        if (firmware_has_feature(FW_FEATURE_OPAL))
                root = of_find_node_by_path("/ibm,opal");
  
        distance_ref_points_depth /= sizeof(int);
  
- #define VEC5_AFFINITY_BYTE    5
- #define VEC5_AFFINITY         0x80
-       if (firmware_has_feature(FW_FEATURE_OPAL))
+       if (firmware_has_feature(FW_FEATURE_OPAL) ||
+           firmware_has_feature(FW_FEATURE_TYPE1_AFFINITY)) {
+               dbg("Using form 1 affinity\n");
                form1_affinity = 1;
-       else {
-               chosen = of_find_node_by_path("/chosen");
-               if (chosen) {
-                       vec5 = of_get_property(chosen,
-                                              "ibm,architecture-vec-5", NULL);
-                       if (vec5 && (vec5[VEC5_AFFINITY_BYTE] &
-                                                       VEC5_AFFINITY)) {
-                               dbg("Using form 1 affinity\n");
-                               form1_affinity = 1;
-                       }
-                       of_node_put(chosen);
-               }
        }
  
        if (form1_affinity) {
@@@ -1268,10 -1260,18 +1257,18 @@@ u64 memory_hotplug_max(void
  
  /* Virtual Processor Home Node (VPHN) support */
  #ifdef CONFIG_PPC_SPLPAR
+ struct topology_update_data {
+       struct topology_update_data *next;
+       unsigned int cpu;
+       int old_nid;
+       int new_nid;
+ };
  static u8 vphn_cpu_change_counts[NR_CPUS][MAX_DISTANCE_REF_POINTS];
  static cpumask_t cpu_associativity_changes_mask;
  static int vphn_enabled;
- static void set_topology_timer(void);
+ static int prrn_enabled;
+ static void reset_topology_timer(void);
  
  /*
   * Store the current values of the associativity change counters in the
@@@ -1307,11 -1307,9 +1304,9 @@@ static void setup_cpu_associativity_cha
   */
  static int update_cpu_associativity_changes_mask(void)
  {
-       int cpu, nr_cpus = 0;
+       int cpu;
        cpumask_t *changes = &cpu_associativity_changes_mask;
  
-       cpumask_clear(changes);
        for_each_possible_cpu(cpu) {
                int i, changed = 0;
                u8 *counts = vphn_cpu_change_counts[cpu];
                }
                if (changed) {
                        cpumask_set_cpu(cpu, changes);
-                       nr_cpus++;
                }
        }
  
-       return nr_cpus;
+       return cpumask_weight(changes);
  }
  
  /*
@@@ -1420,41 -1417,85 +1414,85 @@@ static long vphn_get_associativity(unsi
        return rc;
  }
  
+ /*
+  * Update the CPU maps and sysfs entries for a single CPU when its NUMA
+  * characteristics change. This function doesn't perform any locking and is
+  * only safe to call from stop_machine().
+  */
+ static int update_cpu_topology(void *data)
+ {
+       struct topology_update_data *update;
+       unsigned long cpu;
+       if (!data)
+               return -EINVAL;
+       cpu = get_cpu();
+       for (update = data; update; update = update->next) {
+               if (cpu != update->cpu)
+                       continue;
+               unregister_cpu_under_node(update->cpu, update->old_nid);
+               unmap_cpu_from_node(update->cpu);
+               map_cpu_to_node(update->cpu, update->new_nid);
+               vdso_getcpu_init();
+               register_cpu_under_node(update->cpu, update->new_nid);
+       }
+       return 0;
+ }
  /*
   * Update the node maps and sysfs entries for each cpu whose home node
   * has changed. Returns 1 when the topology has changed, and 0 otherwise.
   */
  int arch_update_cpu_topology(void)
  {
-       int cpu, nid, old_nid, changed = 0;
+       unsigned int cpu, changed = 0;
+       struct topology_update_data *updates, *ud;
        unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};
+       cpumask_t updated_cpus;
        struct device *dev;
+       int weight, i = 0;
  
-       for_each_cpu(cpu,&cpu_associativity_changes_mask) {
+       weight = cpumask_weight(&cpu_associativity_changes_mask);
+       if (!weight)
+               return 0;
+       updates = kzalloc(weight * (sizeof(*updates)), GFP_KERNEL);
+       if (!updates)
+               return 0;
+       cpumask_clear(&updated_cpus);
+       for_each_cpu(cpu, &cpu_associativity_changes_mask) {
+               ud = &updates[i++];
+               ud->cpu = cpu;
                vphn_get_associativity(cpu, associativity);
-               nid = associativity_to_nid(associativity);
+               ud->new_nid = associativity_to_nid(associativity);
  
-               if (nid < 0 || !node_online(nid))
-                       nid = first_online_node;
+               if (ud->new_nid < 0 || !node_online(ud->new_nid))
+                       ud->new_nid = first_online_node;
  
-               old_nid = numa_cpu_lookup_table[cpu];
+               ud->old_nid = numa_cpu_lookup_table[cpu];
+               cpumask_set_cpu(cpu, &updated_cpus);
  
-               /* Disable hotplug while we update the cpu
-                * masks and sysfs.
-                */
-               get_online_cpus();
-               unregister_cpu_under_node(cpu, old_nid);
-               unmap_cpu_from_node(cpu);
-               map_cpu_to_node(cpu, nid);
-               register_cpu_under_node(cpu, nid);
-               put_online_cpus();
-               dev = get_cpu_device(cpu);
+               if (i < weight)
+                       ud->next = &updates[i];
+       }
+       stop_machine(update_cpu_topology, &updates[0], &updated_cpus);
+       for (ud = &updates[0]; ud; ud = ud->next) {
+               dev = get_cpu_device(ud->cpu);
                if (dev)
                        kobject_uevent(&dev->kobj, KOBJ_CHANGE);
+               cpumask_clear_cpu(ud->cpu, &cpu_associativity_changes_mask);
                changed = 1;
        }
  
+       kfree(updates);
        return changed;
  }
  
@@@ -1471,49 -1512,165 +1509,165 @@@ void topology_schedule_update(void
  
  static void topology_timer_fn(unsigned long ignored)
  {
-       if (!vphn_enabled)
-               return;
-       if (update_cpu_associativity_changes_mask() > 0)
+       if (prrn_enabled && cpumask_weight(&cpu_associativity_changes_mask))
                topology_schedule_update();
-       set_topology_timer();
+       else if (vphn_enabled) {
+               if (update_cpu_associativity_changes_mask() > 0)
+                       topology_schedule_update();
+               reset_topology_timer();
+       }
  }
  static struct timer_list topology_timer =
        TIMER_INITIALIZER(topology_timer_fn, 0, 0);
  
- static void set_topology_timer(void)
+ static void reset_topology_timer(void)
  {
        topology_timer.data = 0;
        topology_timer.expires = jiffies + 60 * HZ;
-       add_timer(&topology_timer);
+       mod_timer(&topology_timer, topology_timer.expires);
  }
  
+ #ifdef CONFIG_SMP
+ static void stage_topology_update(int core_id)
+ {
+       cpumask_or(&cpu_associativity_changes_mask,
+               &cpu_associativity_changes_mask, cpu_sibling_mask(core_id));
+       reset_topology_timer();
+ }
+ static int dt_update_callback(struct notifier_block *nb,
+                               unsigned long action, void *data)
+ {
+       struct of_prop_reconfig *update;
+       int rc = NOTIFY_DONE;
+       switch (action) {
+       case OF_RECONFIG_UPDATE_PROPERTY:
+               update = (struct of_prop_reconfig *)data;
+               if (!of_prop_cmp(update->dn->type, "cpu") &&
+                   !of_prop_cmp(update->prop->name, "ibm,associativity")) {
+                       u32 core_id;
+                       of_property_read_u32(update->dn, "reg", &core_id);
+                       stage_topology_update(core_id);
+                       rc = NOTIFY_OK;
+               }
+               break;
+       }
+       return rc;
+ }
+ static struct notifier_block dt_update_nb = {
+       .notifier_call = dt_update_callback,
+ };
+ #endif
  /*
-  * Start polling for VPHN associativity changes.
+  * Start polling for associativity changes.
   */
  int start_topology_update(void)
  {
        int rc = 0;
  
-       /* Disabled until races with load balancing are fixed */
-       if (0 && firmware_has_feature(FW_FEATURE_VPHN) &&
-           get_lppaca()->shared_proc) {
-               vphn_enabled = 1;
-               setup_cpu_associativity_change_counters();
-               init_timer_deferrable(&topology_timer);
-               set_topology_timer();
-               rc = 1;
+       if (firmware_has_feature(FW_FEATURE_PRRN)) {
+               if (!prrn_enabled) {
+                       prrn_enabled = 1;
+                       vphn_enabled = 0;
+ #ifdef CONFIG_SMP
+                       rc = of_reconfig_notifier_register(&dt_update_nb);
+ #endif
+               }
+       } else if (firmware_has_feature(FW_FEATURE_VPHN) &&
+                  get_lppaca()->shared_proc) {
+               if (!vphn_enabled) {
+                       prrn_enabled = 0;
+                       vphn_enabled = 1;
+                       setup_cpu_associativity_change_counters();
+                       init_timer_deferrable(&topology_timer);
+                       reset_topology_timer();
+               }
        }
  
        return rc;
  }
- __initcall(start_topology_update);
  
  /*
   * Disable polling for VPHN associativity changes.
   */
  int stop_topology_update(void)
  {
-       vphn_enabled = 0;
-       return del_timer_sync(&topology_timer);
+       int rc = 0;
+       if (prrn_enabled) {
+               prrn_enabled = 0;
+ #ifdef CONFIG_SMP
+               rc = of_reconfig_notifier_unregister(&dt_update_nb);
+ #endif
+       } else if (vphn_enabled) {
+               vphn_enabled = 0;
+               rc = del_timer_sync(&topology_timer);
+       }
+       return rc;
+ }
+ int prrn_is_enabled(void)
+ {
+       return prrn_enabled;
+ }
+ static int topology_read(struct seq_file *file, void *v)
+ {
+       if (vphn_enabled || prrn_enabled)
+               seq_puts(file, "on\n");
+       else
+               seq_puts(file, "off\n");
+       return 0;
+ }
+ static int topology_open(struct inode *inode, struct file *file)
+ {
+       return single_open(file, topology_read, NULL);
+ }
+ static ssize_t topology_write(struct file *file, const char __user *buf,
+                             size_t count, loff_t *off)
+ {
+       char kbuf[4]; /* "on" or "off" plus null. */
+       int read_len;
+       read_len = count < 3 ? count : 3;
+       if (copy_from_user(kbuf, buf, read_len))
+               return -EINVAL;
+       kbuf[read_len] = '\0';
+       if (!strncmp(kbuf, "on", 2))
+               start_topology_update();
+       else if (!strncmp(kbuf, "off", 3))
+               stop_topology_update();
+       else
+               return -EINVAL;
+       return count;
+ }
+ static const struct file_operations topology_ops = {
+       .read = seq_read,
+       .write = topology_write,
+       .open = topology_open,
+       .release = single_release
+ };
+ static int topology_update_init(void)
+ {
+       start_topology_update();
+       proc_create("powerpc/topology_updates", 644, NULL, &topology_ops);
+       return 0;
  }
+ device_initcall(topology_update_init);
  #endif /* CONFIG_PPC_SPLPAR */
index 381a592826a214887f29570d3d6b3c69e8fb2369,eb4620355e7b6d73f54417439b4df26efe12865c..fc9c1cbfcb1d5ff7719d75f7db46d36a8e93d1b9
@@@ -7,8 -7,6 +7,8 @@@ config PPC_MPC512
        select PPC_PCI_CHOICE
        select FSL_PCI if PCI
        select ARCH_WANT_OPTIONAL_GPIOLIB
 +      select USB_EHCI_BIG_ENDIAN_MMIO
 +      select USB_EHCI_BIG_ENDIAN_DESC
  
  config MPC5121_ADS
        bool "Freescale MPC5121E ADS"
        help
          This option enables support for the MPC5121E ADS board.
  
- config MPC5121_GENERIC
-       bool "Generic support for simple MPC5121 based boards"
+ config MPC512x_GENERIC
+       bool "Generic support for simple MPC512x based boards"
        depends on PPC_MPC512x
        select DEFAULT_UIMAGE
        help
-         This option enables support for simple MPC5121 based boards
+         This option enables support for simple MPC512x based boards
          which do not need custom platform specific setup.
  
          Compatible boards include:  Protonic LVT base boards (ZANMCU
-         and VICVT2).
+         and VICVT2), Freescale MPC5125 Tower system.
  
  config PDM360NG
        bool "ifm PDM360NG board"
index db6ac389ef8ccb0412e371071b272d9dab961337,7642cd7aad73971378549dc1b779b87c167b5970..6eb94ab99d3943990e1000b90c44e081d2931e9a
@@@ -172,9 -172,12 +172,9 @@@ static struct fsl_diu_shared_fb __attri
  
  static inline void mpc512x_free_bootmem(struct page *page)
  {
 -      __ClearPageReserved(page);
        BUG_ON(PageTail(page));
        BUG_ON(atomic_read(&page->_count) > 1);
 -      atomic_set(&page->_count, 1);
 -      __free_page(page);
 -      totalram_pages++;
 +      free_reserved_page(page);
  }
  
  void mpc512x_release_bootmem(void)
@@@ -327,26 -330,34 +327,34 @@@ void __init mpc512x_init_IRQ(void
  static struct of_device_id __initdata of_bus_ids[] = {
        { .compatible = "fsl,mpc5121-immr", },
        { .compatible = "fsl,mpc5121-localbus", },
+       { .compatible = "fsl,mpc5121-mbx", },
+       { .compatible = "fsl,mpc5121-nfc", },
+       { .compatible = "fsl,mpc5121-sram", },
+       { .compatible = "fsl,mpc5121-pci", },
+       { .compatible = "gpio-leds", },
        {},
  };
  
  void __init mpc512x_declare_of_platform_devices(void)
  {
-       struct device_node *np;
        if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
                printk(KERN_ERR __FILE__ ": "
                        "Error while probing of_platform bus\n");
-       np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-nfc");
-       if (np) {
-               of_platform_device_create(np, NULL, NULL);
-               of_node_put(np);
-       }
  }
  
  #define DEFAULT_FIFO_SIZE 16
  
+ const char *mpc512x_select_psc_compat(void)
+ {
+       if (of_machine_is_compatible("fsl,mpc5121"))
+               return "fsl,mpc5121-psc";
+       if (of_machine_is_compatible("fsl,mpc5125"))
+               return "fsl,mpc5125-psc";
+       return NULL;
+ }
  static unsigned int __init get_fifo_size(struct device_node *np,
                                         char *prop_name)
  {
@@@ -372,9 -383,16 +380,16 @@@ void __init mpc512x_psc_fifo_init(void
        void __iomem *psc;
        unsigned int tx_fifo_size;
        unsigned int rx_fifo_size;
+       const char *psc_compat;
        int fifobase = 0; /* current fifo address in 32 bit words */
  
-       for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") {
+       psc_compat = mpc512x_select_psc_compat();
+       if (!psc_compat) {
+               pr_err("%s: no compatible devices found\n", __func__);
+               return;
+       }
+       for_each_compatible_node(np, NULL, psc_compat) {
                tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size");
                rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size");
  
index d43d2d0b90e3f3902a5687072246622b3b055983,0026a37e21fd3087fa5e80d944e1ce120bfa5e76..90986923a53aae1ff2233409f4cbf25da398db4d
@@@ -149,6 -149,7 +149,6 @@@ static int __fops ## _open(struct inod
        return spufs_attr_open(inode, file, __get, __set, __fmt);       \
  }                                                                     \
  static const struct file_operations __fops = {                                \
 -      .owner   = THIS_MODULE,                                         \
        .open    = __fops ## _open,                                     \
        .release = spufs_attr_release,                                  \
        .read    = spufs_attr_read,                                     \
@@@ -351,7 -352,7 +351,7 @@@ static unsigned long spufs_get_unmapped
  
        /* Else, try to obtain a 64K pages slice */
        return slice_get_unmapped_area(addr, len, flags,
-                                      MMU_PAGE_64K, 1, 0);
+                                      MMU_PAGE_64K, 1);
  }
  #endif /* CONFIG_SPU_FS_64K_LS */
  
@@@ -2590,6 -2591,7 +2590,6 @@@ static unsigned int spufs_switch_log_po
  }
  
  static const struct file_operations spufs_switch_log_fops = {
 -      .owner          = THIS_MODULE,
        .open           = spufs_switch_log_open,
        .read           = spufs_switch_log_read,
        .poll           = spufs_switch_log_poll,
diff --combined arch/powerpc/xmon/xmon.c
index 3e34cd224b7c4cba633a9fa0310fd8428c91ed11,51e237c4648f4b1b66df7a9c25e49ebbc251c336..96bf5bd30fbca1a7988ba979b39870f055b343c4
@@@ -1430,7 -1430,7 +1430,7 @@@ static void excprint(struct pt_regs *fp
        printf("    sp: %lx\n", fp->gpr[1]);
        printf("   msr: %lx\n", fp->msr);
  
-       if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
+       if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
                printf("   dar: %lx\n", fp->dar);
                if (trap != 0x380)
                        printf(" dsisr: %lx\n", fp->dsisr);
@@@ -2947,7 -2947,7 +2947,7 @@@ static void sysrq_handle_xmon(int key
  
  static struct sysrq_key_op sysrq_xmon_op = {
        .handler =      sysrq_handle_xmon,
 -      .help_msg =     "Xmon",
 +      .help_msg =     "xmon(x)",
        .action_msg =   "Entering xmon",
  };
  
index c31fbab6aa82f5561bd343caec3e183c09113236,c9c85426f4ff55c60fc995dc5e9eb59e554b2c66..283e1b53c6be4ef1d4b3dfbf381b68f5cf1cdbc2
@@@ -750,8 -750,9 +750,9 @@@ done_battery_state_smart(struct adb_req
                                voltage = (req->reply[8] << 8) | req->reply[9];
                                break;
                        default:
-                               printk(KERN_WARNING "pmu.c : unrecognized battery info, len: %d, %02x %02x %02x %02x\n",
-                                       req->reply_len, req->reply[0], req->reply[1], req->reply[2], req->reply[3]);
+                               pr_warn("pmu.c: unrecognized battery info, "
+                                       "len: %d, %4ph\n", req->reply_len,
+                                                          req->reply);
                                break;
                }
        }
@@@ -869,7 -870,7 +870,7 @@@ static int pmu_battery_proc_show(struc
  
  static int pmu_battery_proc_open(struct inode *inode, struct file *file)
  {
 -      return single_open(file, pmu_battery_proc_show, PDE(inode)->data);
 +      return single_open(file, pmu_battery_proc_show, PDE_DATA(inode));
  }
  
  static const struct file_operations pmu_battery_proc_fops = {
diff --combined drivers/pci/probe.c
index 43ece5d41d36ca428068ef8b09f01f5956f10a25,92be60cf52145878d684ef9d01d6854f36640c49..631aeb7d2d2dd548d7db2ccfeae6b7518f0fc483
@@@ -673,8 -673,6 +673,8 @@@ add_dev
        ret = device_register(&child->dev);
        WARN_ON(ret < 0);
  
 +      pcibios_add_bus(child);
 +
        /* Create legacy_io and legacy_mem files for this bus */
        pci_create_legacy_files(child);
  
@@@ -990,7 -988,6 +990,6 @@@ int pci_setup_device(struct pci_dev *de
        dev->sysdata = dev->bus->sysdata;
        dev->dev.parent = dev->bus->bridge;
        dev->dev.bus = &pci_bus_type;
-       dev->dev.type = &pci_dev_type;
        dev->hdr_type = hdr_type & 0x7f;
        dev->multifunction = !!(hdr_type & 0x80);
        dev->error_state = pci_channel_io_normal;
@@@ -1210,6 -1207,7 +1209,7 @@@ struct pci_dev *alloc_pci_dev(void
                return NULL;
  
        INIT_LIST_HEAD(&dev->bus_list);
+       dev->dev.type = &pci_dev_type;
  
        return dev;
  }
@@@ -1629,7 -1627,8 +1629,7 @@@ unsigned int pci_scan_child_bus(struct 
        if (!bus->is_added) {
                dev_dbg(&bus->dev, "fixups for bus\n");
                pcibios_fixup_bus(bus);
 -              if (pci_is_root_bus(bus))
 -                      bus->is_added = 1;
 +              bus->is_added = 1;
        }
  
        for (pass=0; pass < 2; pass++)
@@@ -1662,14 -1661,6 +1662,14 @@@ int __weak pcibios_root_bridge_prepare(
        return 0;
  }
  
 +void __weak pcibios_add_bus(struct pci_bus *bus)
 +{
 +}
 +
 +void __weak pcibios_remove_bus(struct pci_bus *bus)
 +{
 +}
 +
  struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
                struct pci_ops *ops, void *sysdata, struct list_head *resources)
  {
        if (error)
                goto class_dev_reg_err;
  
 +      pcibios_add_bus(b);
 +
        /* Create legacy_io and legacy_mem files for this bus */
        pci_create_legacy_files(b);
  
diff --combined fs/binfmt_elf.c
index 34a9771eaa6ce12794ed07ae54bfc8760f816121,f1c64a27257ef6fb4c7e52747045633eedb1205c..f8a0b0efda44078c7debba07e2287e91c84405ac
@@@ -240,6 -240,9 +240,9 @@@ create_elf_tables(struct linux_binprm *
        NEW_AUX_ENT(AT_EGID, from_kgid_munged(cred->user_ns, cred->egid));
        NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
        NEW_AUX_ENT(AT_RANDOM, (elf_addr_t)(unsigned long)u_rand_bytes);
+ #ifdef ELF_HWCAP2
+       NEW_AUX_ENT(AT_HWCAP2, ELF_HWCAP2);
+ #endif
        NEW_AUX_ENT(AT_EXECFN, bprm->exec);
        if (k_platform) {
                NEW_AUX_ENT(AT_PLATFORM,
@@@ -803,8 -806,7 +806,8 @@@ static int load_elf_binary(struct linux
                         * follow the loader, and is not movable.  */
  #ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
                        /* Memory randomization might have been switched off
 -                       * in runtime via sysctl.
 +                       * in runtime via sysctl or explicit setting of
 +                       * personality flags.
                         * If that is the case, retain the original non-zero
                         * load_bias value in order to establish proper
                         * non-randomized mappings.
@@@ -2092,7 -2094,8 +2095,7 @@@ static int elf_core_dump(struct coredum
                goto cleanup;
  
        has_dumped = 1;
 -      current->flags |= PF_DUMPCORE;
 -  
 +
        fs = get_fs();
        set_fs(KERNEL_DS);
  
diff --combined fs/binfmt_elf_fdpic.c
index 9dac212fc6f9e1c90459d407c5f2d3def019df3f,bf2381d00132b1d1cad9d813a69343b844b8e43e..c166f325a1839b1ecf83ae0b068f13e8a26495c2
@@@ -483,7 -483,6 +483,6 @@@ static int create_elf_fdpic_tables(stru
        size_t platform_len = 0, len;
        char *k_platform, *k_base_platform;
        char __user *u_platform, *u_base_platform, *p;
-       long hwcap;
        int loop;
        int nr; /* reset for each csp adjustment */
  
                return -EFAULT;
  #endif
  
-       hwcap = ELF_HWCAP;
        /*
         * If this architecture has a platform capability string, copy it
         * to userspace.  In some cases (Sparc), this info is impossible
  
        nr = 0;
        csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
-       NEW_AUX_ENT(AT_HWCAP,   hwcap);
+       NEW_AUX_ENT(AT_HWCAP,   ELF_HWCAP);
+ #ifdef ELF_HWCAP2
+       NEW_AUX_ENT(AT_HWCAP2,  ELF_HWCAP2);
+ #endif
        NEW_AUX_ENT(AT_PAGESZ,  PAGE_SIZE);
        NEW_AUX_ENT(AT_CLKTCK,  CLOCKS_PER_SEC);
        NEW_AUX_ENT(AT_PHDR,    exec_params->ph_addr);
@@@ -926,6 -926,7 +926,6 @@@ static int elf_fdpic_map_file_constdisp
        struct elf32_fdpic_loadseg *seg;
        struct elf32_phdr *phdr;
        unsigned long load_addr, base = ULONG_MAX, top = 0, maddr = 0, mflags;
 -      loff_t fpos;
        int loop, ret;
  
        load_addr = params->load_addr;
                if (params->phdrs[loop].p_type != PT_LOAD)
                        continue;
  
 -              fpos = phdr->p_offset;
 -
                seg->addr = maddr + (phdr->p_vaddr - base);
                seg->p_vaddr = phdr->p_vaddr;
                seg->p_memsz = phdr->p_memsz;
  
 -              ret = file->f_op->read(file, (void *) seg->addr,
 -                                     phdr->p_filesz, &fpos);
 +              ret = read_code(file, seg->addr, phdr->p_offset,
 +                                     phdr->p_filesz);
                if (ret < 0)
                        return ret;
  
@@@ -1684,6 -1687,8 +1684,6 @@@ static int elf_fdpic_core_dump(struct c
        fill_elf_fdpic_header(elf, e_phnum);
  
        has_dumped = 1;
 -      current->flags |= PF_DUMPCORE;
 -
        /*
         * Set up the notes in similar form to SVR4 core dumps made
         * with info from their /proc.