Linuxppc64-dev Digest, Vol 16, Issue 11

Renuka Pampana prenuka at gmail.com
Mon Dec 5 19:35:22 EST 2005


Hi,

Where can i get PPC440ep (yosemite) patch for 64 bit kernel. Can you
give me some pointers to refer.


Thank you in advance

Renuka

On 12/5/05, linuxppc64-dev-request at ozlabs.org
<linuxppc64-dev-request at ozlabs.org> wrote:
> Send Linuxppc64-dev mailing list submissions to
>         linuxppc64-dev at ozlabs.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://ozlabs.org/mailman/listinfo/linuxppc64-dev
> or, via email, send a message with subject or body 'help' to
>         linuxppc64-dev-request at ozlabs.org
>
> You can reach the person managing the list at
>         linuxppc64-dev-owner at ozlabs.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Linuxppc64-dev digest..."
>
>
> Today's Topics:
>
>    1. [PATCH 8/11] powerpc: Add arch dependent basic infrastructure
>       for       Kdump. (Michael Ellerman)
>    2. [PATCH 9/11] powerpc: Parse crashkernel= parameter in first
>       kernel (Michael Ellerman)
>    3. [PATCH 10/11] powerpc: Add arch-dependant copy_oldmem_page
>       (Michael Ellerman)
>    4. [PATCH 11/11] powerpc: Add support for "linux,    usable-memory"
>       on memory nodes (Michael Ellerman)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Sun, 04 Dec 2005 18:39:43
> From: Michael Ellerman <michael at ellerman.id.au>
> Subject: [PATCH 8/11] powerpc: Add arch dependent basic infrastructure
>         for     Kdump.
> To: <linuxppc64-dev at ozlabs.org>,        Paul Mackerras <paulus at samba.org>
> Message-ID: <20051205003957.4CD9868887 at ozlabs.org>
>
> Implementing the machine_crash_shutdown which will be called by
> crash_kexec (called in case of a panic, sysrq etc.). Disable the
> interrupts, shootdown cpus using debugger IPI and collect regs
> for all CPUs.
>
> elfcorehdr= specifies the location of elf core header stored by
> the crashed kernel. This command line option will be passed by
> the kexec-tools to capture kernel.
>
> savemaxmem= specifies the actual memory size that the first kernel
> has and this value will be used for dumping in the capture kernel.
> This command line option will be passed by the kexec-tools to
> capture kernel.
>
> Signed-off-by: Haren Myneni <haren at us.ibm.com>
> Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
> ---
>
>  arch/powerpc/kernel/Makefile            |    2
>  arch/powerpc/kernel/crash.c             |  264 ++++++++++++++++++++++++++++++++
>  arch/powerpc/kernel/crash_dump.c        |   20 ++
>  arch/powerpc/kernel/machine_kexec_64.c  |   13 +
>  arch/powerpc/kernel/smp.c               |   22 ++
>  arch/powerpc/kernel/traps.c             |   17 +-
>  arch/powerpc/platforms/cell/setup.c     |    1
>  arch/powerpc/platforms/maple/setup.c    |    1
>  arch/powerpc/platforms/powermac/setup.c |    1
>  arch/powerpc/platforms/pseries/setup.c  |    1
>  arch/powerpc/platforms/pseries/xics.c   |    2
>  include/asm-powerpc/kexec.h             |   10 +
>  12 files changed, 345 insertions(+), 9 deletions(-)
>
> Index: kexec/arch/powerpc/kernel/smp.c
> ===================================================================
> --- kexec.orig/arch/powerpc/kernel/smp.c
> +++ kexec/arch/powerpc/kernel/smp.c
> @@ -75,6 +75,8 @@ void smp_call_function_interrupt(void);
>
>  int smt_enabled_at_boot = 1;
>
> +static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
> +
>  #ifdef CONFIG_MPIC
>  int __init smp_mpic_probe(void)
>  {
> @@ -123,11 +125,16 @@ void smp_message_recv(int msg, struct pt
>                 /* XXX Do we have to do this? */
>                 set_need_resched();
>                 break;
> -#ifdef CONFIG_DEBUGGER
>         case PPC_MSG_DEBUGGER_BREAK:
> +               if (crash_ipi_function_ptr) {
> +                       crash_ipi_function_ptr(regs);
> +                       break;
> +               }
> +#ifdef CONFIG_DEBUGGER
>                 debugger_ipi(regs);
>                 break;
> -#endif
> +#endif /* CONFIG_DEBUGGER */
> +               /* FALLTHROUGH */
>         default:
>                 printk("SMP %d: smp_message_recv(): unknown msg %d\n",
>                        smp_processor_id(), msg);
> @@ -147,6 +154,17 @@ void smp_send_debugger_break(int cpu)
>  }
>  #endif
>
> +#ifdef CONFIG_KEXEC
> +void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
> +{
> +       crash_ipi_function_ptr = crash_ipi_callback;
> +       if (crash_ipi_callback) {
> +               mb();
> +               smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK);
> +       }
> +}
> +#endif
> +
>  static void stop_this_cpu(void *dummy)
>  {
>         local_irq_disable();
> Index: kexec/arch/powerpc/kernel/crash.c
> ===================================================================
> --- /dev/null
> +++ kexec/arch/powerpc/kernel/crash.c
> @@ -0,0 +1,264 @@
> +/*
> + * Architecture specific (PPC64) functions for kexec based crash dumps.
> + *
> + * Copyright (C) 2005, IBM Corp.
> + *
> + * Created by: Haren Myneni
> + *
> + * This source code is licensed under the GNU General Public License,
> + * Version 2.  See the file COPYING for more details.
> + *
> + */
> +
> +#undef DEBUG
> +
> +#include <linux/kernel.h>
> +#include <linux/smp.h>
> +#include <linux/reboot.h>
> +#include <linux/kexec.h>
> +#include <linux/bootmem.h>
> +#include <linux/crash_dump.h>
> +#include <linux/irq.h>
> +#include <linux/delay.h>
> +#include <linux/elf.h>
> +#include <linux/elfcore.h>
> +#include <linux/init.h>
> +#include <linux/types.h>
> +
> +#include <asm/processor.h>
> +#include <asm/machdep.h>
> +#include <asm/kdump.h>
> +#include <asm/lmb.h>
> +#include <asm/firmware.h>
> +
> +#ifdef DEBUG
> +#include <asm/udbg.h>
> +#define DBG(fmt...) udbg_printf(fmt)
> +#else
> +#define DBG(fmt...)
> +#endif
> +
> +/* This keeps a track of which one is crashing cpu. */
> +int crashing_cpu = -1;
> +
> +static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
> +                                                              size_t data_len)
> +{
> +       struct elf_note note;
> +
> +       note.n_namesz = strlen(name) + 1;
> +       note.n_descsz = data_len;
> +       note.n_type   = type;
> +       memcpy(buf, &note, sizeof(note));
> +       buf += (sizeof(note) +3)/4;
> +       memcpy(buf, name, note.n_namesz);
> +       buf += (note.n_namesz + 3)/4;
> +       memcpy(buf, data, note.n_descsz);
> +       buf += (note.n_descsz + 3)/4;
> +
> +       return buf;
> +}
> +
> +static void final_note(u32 *buf)
> +{
> +       struct elf_note note;
> +
> +       note.n_namesz = 0;
> +       note.n_descsz = 0;
> +       note.n_type   = 0;
> +       memcpy(buf, &note, sizeof(note));
> +}
> +
> +static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
> +{
> +       struct elf_prstatus prstatus;
> +       u32 *buf;
> +
> +       if ((cpu < 0) || (cpu >= NR_CPUS))
> +               return;
> +
> +       /* Using ELF notes here is opportunistic.
> +        * I need a well defined structure format
> +        * for the data I pass, and I need tags
> +        * on the data to indicate what information I have
> +        * squirrelled away.  ELF notes happen to provide
> +        * all of that that no need to invent something new.
> +        */
> +       buf = &crash_notes[cpu][0];
> +       memset(&prstatus, 0, sizeof(prstatus));
> +       prstatus.pr_pid = current->pid;
> +       elf_core_copy_regs(&prstatus.pr_reg, regs);
> +       buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
> +                       sizeof(prstatus));
> +       final_note(buf);
> +}
> +
> +/* FIXME Merge this with xmon_save_regs ?? */
> +static inline void crash_get_current_regs(struct pt_regs *regs)
> +{
> +       unsigned long tmp1, tmp2;
> +
> +       __asm__ __volatile__ (
> +               "std    0,0(%2)\n"
> +               "std    1,8(%2)\n"
> +               "std    2,16(%2)\n"
> +               "std    3,24(%2)\n"
> +               "std    4,32(%2)\n"
> +               "std    5,40(%2)\n"
> +               "std    6,48(%2)\n"
> +               "std    7,56(%2)\n"
> +               "std    8,64(%2)\n"
> +               "std    9,72(%2)\n"
> +               "std    10,80(%2)\n"
> +               "std    11,88(%2)\n"
> +               "std    12,96(%2)\n"
> +               "std    13,104(%2)\n"
> +               "std    14,112(%2)\n"
> +               "std    15,120(%2)\n"
> +               "std    16,128(%2)\n"
> +               "std    17,136(%2)\n"
> +               "std    18,144(%2)\n"
> +               "std    19,152(%2)\n"
> +               "std    20,160(%2)\n"
> +               "std    21,168(%2)\n"
> +               "std    22,176(%2)\n"
> +               "std    23,184(%2)\n"
> +               "std    24,192(%2)\n"
> +               "std    25,200(%2)\n"
> +               "std    26,208(%2)\n"
> +               "std    27,216(%2)\n"
> +               "std    28,224(%2)\n"
> +               "std    29,232(%2)\n"
> +               "std    30,240(%2)\n"
> +               "std    31,248(%2)\n"
> +               "mfmsr  %0\n"
> +               "std    %0, 264(%2)\n"
> +               "mfctr  %0\n"
> +               "std    %0, 280(%2)\n"
> +               "mflr   %0\n"
> +               "std    %0, 288(%2)\n"
> +               "bl     1f\n"
> +       "1:      mflr   %1\n"
> +               "std    %1, 256(%2)\n"
> +               "mtlr   %0\n"
> +               "mfxer  %0\n"
> +               "std    %0, 296(%2)\n"
> +               : "=&r" (tmp1), "=&r" (tmp2)
> +               : "b" (regs));
> +}
> +
> +/* We may have saved_regs from where the error came from
> + * or it is NULL if via a direct panic().
> + */
> +static void crash_save_self(struct pt_regs *saved_regs)
> +{
> +       struct pt_regs regs;
> +       int cpu;
> +
> +       cpu = smp_processor_id();
> +       if (saved_regs)
> +               memcpy(&regs, saved_regs, sizeof(regs));
> +       else
> +               crash_get_current_regs(&regs);
> +       crash_save_this_cpu(&regs, cpu);
> +}
> +
> +#ifdef CONFIG_SMP
> +static atomic_t waiting_for_crash_ipi;
> +
> +void crash_ipi_callback(struct pt_regs *regs)
> +{
> +       int cpu = smp_processor_id();
> +
> +       if (cpu == crashing_cpu)
> +               return;
> +
> +       if (!cpu_online(cpu))
> +               return;
> +
> +       if (ppc_md.kexec_cpu_down)
> +               ppc_md.kexec_cpu_down(1, 1);
> +
> +       local_irq_disable();
> +
> +       crash_save_this_cpu(regs, cpu);
> +       atomic_dec(&waiting_for_crash_ipi);
> +       kexec_smp_wait();
> +       /* NOTREACHED */
> +}
> +
> +static void crash_kexec_prepare_cpus(void)
> +{
> +       unsigned int msecs;
> +
> +       atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
> +
> +       crash_send_ipi(crash_ipi_callback);
> +       smp_wmb();
> +
> +       /*
> +        * FIXME: Until we will have the way to stop other CPUSs reliabally,
> +        * the crash CPU will send an IPI and wait for other CPUs to
> +        * respond. If not, proceed the kexec boot even though we failed to
> +        * capture other CPU states.
> +        */
> +       msecs = 1000000;
> +       while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) {
> +               barrier();
> +               mdelay(1);
> +       }
> +
> +       /* Would it be better to replace the trap vector here? */
> +
> +       /*
> +        * FIXME: In case if we do not get all CPUs, one possibility: ask the
> +        * user to do soft reset such that we get all.
> +        * IPI handler is already set by the panic cpu initially. Therefore,
> +        * all cpus could invoke this handler from die() and the panic CPU
> +        * will call machine_kexec() directly from this handler to do
> +        * kexec boot.
> +        */
> +       if (atomic_read(&waiting_for_crash_ipi))
> +               printk(KERN_ALERT "done waiting: %d cpus not responding\n",
> +                       atomic_read(&waiting_for_crash_ipi));
> +       /* Leave the IPI callback set */
> +}
> +#else
> +static void crash_kexec_prepare_cpus(void)
> +{
> +       /*
> +        * move the secondarys to us so that we can copy
> +        * the new kernel 0-0x100 safely
> +        *
> +        * do this if kexec in setup.c ?
> +        */
> +       smp_release_cpus();
> +}
> +
> +#endif
> +
> +void default_machine_crash_shutdown(struct pt_regs *regs)
> +{
> +       /*
> +        * This function is only called after the system
> +        * has paniced or is otherwise in a critical state.
> +        * The minimum amount of code to allow a kexec'd kernel
> +        * to run successfully needs to happen here.
> +        *
> +        * In practice this means stopping other cpus in
> +        * an SMP system.
> +        * The kernel is broken so disable interrupts.
> +        */
> +       local_irq_disable();
> +
> +       if (ppc_md.kexec_cpu_down)
> +               ppc_md.kexec_cpu_down(1, 0);
> +
> +       /*
> +        * Make a note of crashing cpu. Will be used in machine_kexec
> +        * such that another IPI will not be sent.
> +        */
> +       crashing_cpu = smp_processor_id();
> +       crash_kexec_prepare_cpus();
> +       crash_save_self(regs);
> +}
> Index: kexec/arch/powerpc/kernel/traps.c
> ===================================================================
> --- kexec.orig/arch/powerpc/kernel/traps.c
> +++ kexec/arch/powerpc/kernel/traps.c
> @@ -31,6 +31,7 @@
>  #include <linux/prctl.h>
>  #include <linux/delay.h>
>  #include <linux/kprobes.h>
> +#include <linux/kexec.h>
>
>  #include <asm/kdebug.h>
>  #include <asm/pgtable.h>
> @@ -95,7 +96,7 @@ static DEFINE_SPINLOCK(die_lock);
>
>  int die(const char *str, struct pt_regs *regs, long err)
>  {
> -       static int die_counter;
> +       static int die_counter, crash_dump_start = 0;
>         int nl = 0;
>
>         if (debugger(regs))
> @@ -156,7 +157,21 @@ int die(const char *str, struct pt_regs
>         print_modules();
>         show_regs(regs);
>         bust_spinlocks(0);
> +
> +       if (!crash_dump_start && kexec_should_crash(current)) {
> +               crash_dump_start = 1;
> +               spin_unlock_irq(&die_lock);
> +               crash_kexec(regs);
> +               /* NOTREACHED */
> +       }
>         spin_unlock_irq(&die_lock);
> +       if (crash_dump_start)
> +               /*
> +                * Only for soft-reset: Other CPUs will be responded to an IPI
> +                * sent by first kexec CPU.
> +                */
> +               for(;;)
> +                       ;
>
>         if (in_interrupt())
>                 panic("Fatal exception in interrupt");
> Index: kexec/arch/powerpc/kernel/machine_kexec_64.c
> ===================================================================
> --- kexec.orig/arch/powerpc/kernel/machine_kexec_64.c
> +++ kexec/arch/powerpc/kernel/machine_kexec_64.c
> @@ -265,11 +265,18 @@ extern NORET_TYPE void kexec_sequence(vo
>  /* too late to fail here */
>  void default_machine_kexec(struct kimage *image)
>  {
> -
>         /* prepare control code if any */
>
> -       /* shutdown other cpus into our wait loop and quiesce interrupts */
> -       kexec_prepare_cpus();
> +       /*
> +        * If the kexec boot is the normal one, need to shutdown other cpus
> +        * into our wait loop and quiesce interrupts.
> +        * Otherwise, in the case of crashed mode (crashing_cpu >= 0),
> +        * stopping other CPUs and collecting their pt_regs is done before
> +        * using debugger IPI.
> +        */
> +
> +       if (crashing_cpu == -1)
> +               kexec_prepare_cpus();
>
>         /* switch to a staticly allocated stack.  Based on irq stack code.
>          * XXX: the task struct will likely be invalid once we do the copy!
> Index: kexec/include/asm-powerpc/kexec.h
> ===================================================================
> --- kexec.orig/include/asm-powerpc/kexec.h
> +++ kexec/include/asm-powerpc/kexec.h
> @@ -32,6 +32,8 @@
>
>  #ifndef __ASSEMBLY__
>
> +#ifdef CONFIG_KEXEC
> +
>  #define MAX_NOTE_BYTES 1024
>  typedef u32 note_buf_t[MAX_NOTE_BYTES / sizeof(u32)];
>
> @@ -41,11 +43,17 @@ extern note_buf_t crash_notes[];
>  extern void kexec_smp_wait(void);      /* get and clear naca physid, wait for
>                                           master to copy new code to 0 */
>  extern void __init kexec_setup(void);
> -#endif
> +extern int crashing_cpu;
> +extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
> +#endif /* __powerpc64 __ */
>
>  struct kimage;
> +struct pt_regs;
>  extern void default_machine_kexec(struct kimage *image);
>  extern int default_machine_kexec_prepare(struct kimage *image);
> +extern void default_machine_crash_shutdown(struct pt_regs *regs);
> +
> +#endif /* !CONFIG_KEXEC */
>
>  #endif /* ! __ASSEMBLY__ */
>  #endif /* _ASM_POWERPC_KEXEC_H */
> Index: kexec/arch/powerpc/platforms/pseries/xics.c
> ===================================================================
> --- kexec.orig/arch/powerpc/platforms/pseries/xics.c
> +++ kexec/arch/powerpc/platforms/pseries/xics.c
> @@ -417,7 +417,7 @@ irqreturn_t xics_ipi_action(int irq, voi
>                         smp_message_recv(PPC_MSG_MIGRATE_TASK, regs);
>                 }
>  #endif
> -#ifdef CONFIG_DEBUGGER
> +#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
>                 if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
>                                        &xics_ipi_message[cpu].value)) {
>                         mb();
> Index: kexec/arch/powerpc/platforms/cell/setup.c
> ===================================================================
> --- kexec.orig/arch/powerpc/platforms/cell/setup.c
> +++ kexec/arch/powerpc/platforms/cell/setup.c
> @@ -217,5 +217,6 @@ struct machdep_calls __initdata cell_md
>  #ifdef CONFIG_KEXEC
>         .machine_kexec          = default_machine_kexec,
>         .machine_kexec_prepare  = default_machine_kexec_prepare,
> +       .machine_crash_shutdown = default_machine_crash_shutdown,
>  #endif
>  };
> Index: kexec/arch/powerpc/platforms/maple/setup.c
> ===================================================================
> --- kexec.orig/arch/powerpc/platforms/maple/setup.c
> +++ kexec/arch/powerpc/platforms/maple/setup.c
> @@ -282,5 +282,6 @@ struct machdep_calls __initdata maple_md
>  #ifdef CONFIG_KEXEC
>         .machine_kexec          = default_machine_kexec,
>         .machine_kexec_prepare  = default_machine_kexec_prepare,
> +       .machine_crash_shutdown = default_machine_crash_shutdown,
>  #endif
>  };
> Index: kexec/arch/powerpc/platforms/powermac/setup.c
> ===================================================================
> --- kexec.orig/arch/powerpc/platforms/powermac/setup.c
> +++ kexec/arch/powerpc/platforms/powermac/setup.c
> @@ -771,6 +771,7 @@ struct machdep_calls __initdata pmac_md
>  #ifdef CONFIG_KEXEC
>         .machine_kexec          = default_machine_kexec,
>         .machine_kexec_prepare  = default_machine_kexec_prepare,
> +       .machine_crash_shutdown = default_machine_crash_shutdown,
>  #endif
>  #endif /* CONFIG_PPC64 */
>  #ifdef CONFIG_PPC32
> Index: kexec/arch/powerpc/platforms/pseries/setup.c
> ===================================================================
> --- kexec.orig/arch/powerpc/platforms/pseries/setup.c
> +++ kexec/arch/powerpc/platforms/pseries/setup.c
> @@ -629,5 +629,6 @@ struct machdep_calls __initdata pSeries_
>         .kexec_cpu_down         = pseries_kexec_cpu_down,
>         .machine_kexec          = default_machine_kexec,
>         .machine_kexec_prepare  = default_machine_kexec_prepare,
> +       .machine_crash_shutdown = default_machine_crash_shutdown,
>  #endif
>  };
> Index: kexec/arch/powerpc/kernel/crash_dump.c
> ===================================================================
> --- kexec.orig/arch/powerpc/kernel/crash_dump.c
> +++ kexec/arch/powerpc/kernel/crash_dump.c
> @@ -11,6 +11,8 @@
>
>  #undef DEBUG
>
> +#include <linux/crash_dump.h>
> +#include <linux/bootmem.h>
>  #include <asm/kdump.h>
>  #include <asm/lmb.h>
>  #include <asm/firmware.h>
> @@ -51,3 +53,21 @@ void __init kdump_setup(void)
>
>         DBG(" <- kdump_setup()\n");
>  }
> +
> +static int __init parse_elfcorehdr(char *p)
> +{
> +       if (p)
> +               elfcorehdr_addr = memparse(p, &p);
> +
> +       return 0;
> +}
> +__setup("elfcorehdr=", parse_elfcorehdr);
> +
> +static int __init parse_savemaxmem(char *p)
> +{
> +       if (p)
> +               saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
> +
> +       return 0;
> +}
> +__setup("savemaxmem=", parse_savemaxmem);
> Index: kexec/arch/powerpc/kernel/Makefile
> ===================================================================
> --- kexec.orig/arch/powerpc/kernel/Makefile
> +++ kexec/arch/powerpc/kernel/Makefile
> @@ -66,7 +66,7 @@ pci64-$(CONFIG_PPC64)         += pci_64.o pci_d
>  obj-$(CONFIG_PCI)              += $(pci64-y)
>  kexec-$(CONFIG_PPC64)          := machine_kexec_64.o
>  kexec-$(CONFIG_PPC32)          := machine_kexec_32.o
> -obj-$(CONFIG_KEXEC)            += machine_kexec.o $(kexec-y)
> +obj-$(CONFIG_KEXEC)            += machine_kexec.o crash.o $(kexec-y)
>
>  ifeq ($(CONFIG_PPC_ISERIES),y)
>  $(obj)/head_64.o: $(obj)/lparmap.s
>
>
> ------------------------------
>
> Message: 2
> Date: Sun, 04 Dec 2005 18:39:48
> From: Michael Ellerman <michael at ellerman.id.au>
> Subject: [PATCH 9/11] powerpc: Parse crashkernel= parameter in first
>         kernel
> To: <linuxppc64-dev at ozlabs.org>,        Paul Mackerras <paulus at samba.org>
> Message-ID: <20051205004002.7A01B68889 at ozlabs.org>
>
> This patch adds code to parse and setup the crash kernel resource in the
> first kernel. PPC64 ignores the @x part, we always run at 32 MB.
>
> Signed-off-by: Haren Myneni <haren at us.ibm.com>
> Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
> ---
>
>  arch/powerpc/kernel/prom.c      |   11 ++++++++
>  arch/powerpc/kernel/prom_init.c |   53 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 64 insertions(+)
>
> Index: kexec/arch/powerpc/kernel/prom_init.c
> ===================================================================
> --- kexec.orig/arch/powerpc/kernel/prom_init.c
> +++ kexec/arch/powerpc/kernel/prom_init.c
> @@ -192,6 +192,11 @@ static unsigned long __initdata alloc_bo
>  static unsigned long __initdata rmo_top;
>  static unsigned long __initdata ram_top;
>
> +#ifdef CONFIG_KEXEC
> +static unsigned long __initdata prom_crashk_base;
> +static unsigned long __initdata prom_crashk_size;
> +#endif
> +
>  static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
>  static int __initdata mem_reserve_cnt;
>
> @@ -590,6 +595,34 @@ static void __init early_cmdline_parse(v
>                 RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
>  #endif
>         }
> +
> +#ifdef CONFIG_KEXEC
> +       /*
> +        * crashkernel=size at addr specifies the location to reserve for
> +        * crash kernel.
> +        */
> +       opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel="));
> +       if (opt) {
> +               opt += 12;
> +               RELOC(prom_crashk_size) = prom_memparse(opt, &opt);
> +
> +               if (ALIGN(RELOC(prom_crashk_size), 0x1000000) !=
> +                       RELOC(prom_crashk_size)) {
> +                       prom_printf("Warning: crashkernel size is not "
> +                                       "aligned to 16MB\n");
> +               }
> +
> +               /*
> +                * At present, the crash kernel always run at 32MB.
> +                * Just ignore whatever user passed.
> +                */
> +               RELOC(prom_crashk_base) = 0x2000000;
> +               if (*opt == '@') {
> +                       prom_printf("Warning: PPC64 kdump kernel always runs "
> +                                       "at 32 MB\n");
> +               }
> +       }
> +#endif
>  }
>
>  #ifdef CONFIG_PPC_PSERIES
> @@ -1011,6 +1044,12 @@ static void __init prom_init_mem(void)
>         prom_printf("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
>         prom_printf("  rmo_top      : %x\n", RELOC(rmo_top));
>         prom_printf("  ram_top      : %x\n", RELOC(ram_top));
> +#ifdef CONFIG_KEXEC
> +       if (RELOC(prom_crashk_base)) {
> +               prom_printf("  crashk_base  : %x\n",  RELOC(prom_crashk_base));
> +               prom_printf("  crashk_size  : %x\n", RELOC(prom_crashk_size));
> +       }
> +#endif
>  }
>
>
> @@ -2094,6 +2133,10 @@ unsigned long __init prom_init(unsigned
>          */
>         prom_init_mem();
>
> +#ifdef CONFIG_KEXEC
> +       if (RELOC(prom_crashk_base))
> +               reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size));
> +#endif
>         /*
>          * Determine which cpu is actually running right _now_
>          */
> @@ -2150,6 +2193,16 @@ unsigned long __init prom_init(unsigned
>         }
>  #endif
>
> +#ifdef CONFIG_KEXEC
> +       if (RELOC(prom_crashk_base)) {
> +               prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base",
> +                       PTRRELOC(&prom_crashk_base),
> +                       sizeof(RELOC(prom_crashk_base)));
> +               prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size",
> +                       PTRRELOC(&prom_crashk_size),
> +                       sizeof(RELOC(prom_crashk_size)));
> +       }
> +#endif
>         /*
>          * Fixup any known bugs in the device-tree
>          */
> Index: kexec/arch/powerpc/kernel/prom.c
> ===================================================================
> --- kexec.orig/arch/powerpc/kernel/prom.c
> +++ kexec/arch/powerpc/kernel/prom.c
> @@ -29,6 +29,7 @@
>  #include <linux/initrd.h>
>  #include <linux/bitops.h>
>  #include <linux/module.h>
> +#include <linux/kexec.h>
>
>  #include <asm/prom.h>
>  #include <asm/rtas.h>
> @@ -1198,6 +1199,16 @@ static int __init early_init_dt_scan_cho
>         }
>  #endif /* CONFIG_PPC_RTAS */
>
> +#ifdef CONFIG_KEXEC
> +       lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL);
> +       if (lprop)
> +               crashk_res.start = *lprop;
> +
> +       lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-size", NULL);
> +       if (lprop)
> +               crashk_res.end = crashk_res.start + *lprop - 1;
> +#endif
> +
>         /* break now */
>         return 1;
>  }
>
>
> ------------------------------
>
> Message: 3
> Date: Sun, 04 Dec 2005 18:39:51
> From: Michael Ellerman <michael at ellerman.id.au>
> Subject: [PATCH 10/11] powerpc: Add arch-dependant copy_oldmem_page
> To: <linuxppc64-dev at ozlabs.org>,        Paul Mackerras <paulus at samba.org>
> Message-ID: <20051205004006.1FEB26887B at ozlabs.org>
>
> Add arch-dependant copy_oldmem_page.
>
> Signed-off-by: Haren Myneni <haren at us.ibm.com>
> Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
> ---
>
>  arch/powerpc/kernel/crash_dump.c |   36 ++++++++++++++++++++++++++++++++++++
>  include/asm-powerpc/kexec.h      |    2 ++
>  kernel/crash_dump.c              |    3 +++
>  3 files changed, 41 insertions(+)
>
> Index: kexec/arch/powerpc/kernel/crash_dump.c
> ===================================================================
> --- kexec.orig/arch/powerpc/kernel/crash_dump.c
> +++ kexec/arch/powerpc/kernel/crash_dump.c
> @@ -16,6 +16,7 @@
>  #include <asm/kdump.h>
>  #include <asm/lmb.h>
>  #include <asm/firmware.h>
> +#include <asm/uaccess.h>
>
>  #ifdef DEBUG
>  #include <asm/udbg.h>
> @@ -71,3 +72,38 @@ static int __init parse_savemaxmem(char
>         return 0;
>  }
>  __setup("savemaxmem=", parse_savemaxmem);
> +
> +/*
> + * copy_oldmem_page - copy one page from "oldmem"
> + * @pfn: page frame number to be copied
> + * @buf: target memory address for the copy; this can be in kernel address
> + *      space or user address space (see @userbuf)
> + * @csize: number of bytes to copy
> + * @offset: offset in bytes into the page (based on pfn) to begin the copy
> + * @userbuf: if set, @buf is in user address space, use copy_to_user(),
> + *      otherwise @buf is in kernel address space, use memcpy().
> + *
> + * Copy a page from "oldmem". For this page, there is no pte mapped
> + * in the current kernel. We stitch up a pte, similar to kmap_atomic.
> + */
> +ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
> +                       size_t csize, unsigned long offset, int userbuf)
> +{
> +       void  *vaddr;
> +
> +       if (!csize)
> +               return 0;
> +
> +       vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0);
> +
> +       if (userbuf) {
> +               if (copy_to_user((char __user *)buf, (vaddr + offset), csize)) {
> +                       iounmap(vaddr);
> +                       return -EFAULT;
> +               }
> +       } else
> +               memcpy(buf, (vaddr + offset), csize);
> +
> +       iounmap(vaddr);
> +       return csize;
> +}
> Index: kexec/include/asm-powerpc/kexec.h
> ===================================================================
> --- kexec.orig/include/asm-powerpc/kexec.h
> +++ kexec/include/asm-powerpc/kexec.h
> @@ -30,6 +30,8 @@
>  #define KEXEC_ARCH KEXEC_ARCH_PPC
>  #endif
>
> +#define HAVE_ARCH_COPY_OLDMEM_PAGE
> +
>  #ifndef __ASSEMBLY__
>
>  #ifdef CONFIG_KEXEC
> Index: kexec/kernel/crash_dump.c
> ===================================================================
> --- kexec.orig/kernel/crash_dump.c
> +++ kexec/kernel/crash_dump.c
> @@ -14,10 +14,12 @@
>
>  #include <asm/io.h>
>  #include <asm/uaccess.h>
> +#include <asm/kexec.h>
>
>  /* Stores the physical address of elf header of crash image. */
>  unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
>
> +#ifndef HAVE_ARCH_COPY_OLDMEM_PAGE
>  /**
>   * copy_oldmem_page - copy one page from "oldmem"
>   * @pfn: page frame number to be copied
> @@ -59,3 +61,4 @@ ssize_t copy_oldmem_page(unsigned long p
>         kfree(page);
>         return csize;
>  }
> +#endif
>
>
> ------------------------------
>
> Message: 4
> Date: Sun, 04 Dec 2005 18:39:55
> From: Michael Ellerman <michael at ellerman.id.au>
> Subject: [PATCH 11/11] powerpc: Add support for "linux, usable-memory"
>         on memory nodes
> To: <linuxppc64-dev at ozlabs.org>,        Paul Mackerras <paulus at samba.org>
> Message-ID: <20051205004009.D5BCE68865 at ozlabs.org>
>
> Milton has proposed that we should support a "linux,usable-memory" property
> on memory nodes which describes, in preference to "reg", the regions of memory
> Linux should use.
>
> This facility is required for kdump, to inform the second kernel which memory
> it should use.
>
> Signed-off-by: Haren Myneni <haren at us.ibm.com>
> Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
> ---
>
>  arch/powerpc/kernel/prom.c |    9 +++++++--
>  arch/powerpc/mm/numa.c     |    7 ++++++-
>  2 files changed, 13 insertions(+), 3 deletions(-)
>
> Index: kexec/arch/powerpc/kernel/prom.c
> ===================================================================
> --- kexec.orig/arch/powerpc/kernel/prom.c
> +++ kexec/arch/powerpc/kernel/prom.c
> @@ -567,7 +567,10 @@ static int __init interpret_root_props(s
>         unsigned int *rp;
>         int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
>
> -       rp = (unsigned int *) get_property(np, "reg", &l);
> +       rp = (unsigned int *) get_property(np, "linux,usable-memory", &l);
> +       if (rp == NULL)
> +               rp = (unsigned int *) get_property(np, "reg", &l);
> +
>         if (rp != 0 && l >= rpsize) {
>                 i = 0;
>                 adr = (struct address_range *) (*mem_start);
> @@ -1275,7 +1278,9 @@ static int __init early_init_dt_scan_mem
>         } else if (strcmp(type, "memory") != 0)
>                 return 0;
>
> -       reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
> +       reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
> +       if (reg == NULL)
> +               reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
>         if (reg == NULL)
>                 return 0;
>
> Index: kexec/arch/powerpc/mm/numa.c
> ===================================================================
> --- kexec.orig/arch/powerpc/mm/numa.c
> +++ kexec/arch/powerpc/mm/numa.c
> @@ -423,7 +423,12 @@ static int __init parse_numa_properties(
>                 unsigned int *memcell_buf;
>                 unsigned int len;
>
> -               memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
> +               memcell_buf = (unsigned int *)get_property(memory,
> +                       "linux,usable-memory", &len);
> +               if (!memcell_buf || len <= 0)
> +                       memcell_buf =
> +                               (unsigned int *)get_property(memory, "reg",
> +                                       &len);
>                 if (!memcell_buf || len <= 0)
>                         continue;
>
>
>
> ------------------------------
>
> _______________________________________________
> Linuxppc64-dev mailing list
> Linuxppc64-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc64-dev
>
>
> End of Linuxppc64-dev Digest, Vol 16, Issue 11
> **********************************************
>



More information about the Linuxppc64-dev mailing list