From: geoff@infradead.org (Geoff Levand)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v12 08/16] arm64/kexec: Add core kexec support
Date: Tue, 15 Dec 2015 16:14:30 -0800 [thread overview]
Message-ID: <1450224870.24127.130.camel@infradead.org> (raw)
In-Reply-To: <20151215182932.GF353@arm.com>
Hi Will,
I'll post a v12.4 of this patch that addresses your comments.
On Tue, 2015-12-15 at 18:29 +0000, Will Deacon wrote:
> +#if !defined(_ARM64_KEXEC_H)
> > +#define _ARM64_KEXEC_H
>
> Please keep to the style used elsewhere in the arch headers.
OK.
> > +
> > +#define KEXEC_CONTROL_PAGE_SIZE> > > > 4096
>
> Does this work on kernels configured with 64k pages? It looks like the
> kexec core code will end up using order-0 pages, so I worry that we'll
> actually put down 64k and potentially confuse a 4k crash kernel, for
> example.
KEXEC_CONTROL_PAGE_SIZE just tells the core kexec code how big
we need control_code_buffer to be. That buffer is only used by
the arch code of the first stage kernel. With 64k pages the buffer
will be a full page, but we'll only use the first 4k of it.
> > +#define KEXEC_ARCH KEXEC_ARCH_ARM64
> > +
> > +#if !defined(__ASSEMBLY__)
>
> #ifndef
OK.
> > + * machine_kexec - Do the kexec reboot.
> > + *
> > + * Called from the core kexec code for a sys_reboot with LINUX_REBOOT_CMD_KEXEC.
> > + */
> > +void machine_kexec(struct kimage *kimage)
> > +{
> > +> > > > phys_addr_t reboot_code_buffer_phys;
> > +> > > > void *reboot_code_buffer;
> > +
> > +> > > > BUG_ON(num_online_cpus() > 1);
> > +
> > +> > > > reboot_code_buffer_phys = page_to_phys(kimage->control_code_page);
> > +> > > > reboot_code_buffer = phys_to_virt(reboot_code_buffer_phys);
> > +
> > +> > > > /*
> > +> > > > * Copy arm64_relocate_new_kernel to the reboot_code_buffer for use
> > +> > > > * after the kernel is shut down.
> > +> > > > */
> > +> > > > memcpy(reboot_code_buffer, arm64_relocate_new_kernel,
> > +> > > > > > arm64_relocate_new_kernel_size);
>
> At which point does the I-cache get invalidated for this?
I'll add a call to flush_icache_range() for reboot_code_buffer. I
think that should do it.
> > +
> > +> > > > /* Flush the reboot_code_buffer in preparation for its execution. */
> > +> > > > __flush_dcache_area(reboot_code_buffer, arm64_relocate_new_kernel_size);
> > +
> > +> > > > /* Flush the new image. */
> > +> > > > kexec_segment_flush(kimage);
> > +
> > +> > > > /* Flush the kimage list. */
> > +> > > > kexec_list_flush(kimage->head);
> > +
> > +> > > > pr_info("Bye!\n");
> > +
> > +> > > > /* Disable all DAIF exceptions. */
> > +> > > > asm volatile ("msr > > daifset> > , #0xf" : : :
> > "memory");
>
> Can we not use our helpers for this?
Mark Rutland had commented that calling daifset four times
through the different macros took considerable time, and
recommended a single call here.
Would you prefer a new macro for irqflags.h, maybe
#define local_daif_disable() asm("msr daifset, #0xf" : : : "memory")?
> > +/*
> > + * arm64_relocate_new_kernel - Put a 2nd stage image in place and boot it.
> > + *
> > + * The memory that the old kernel occupies may be overwritten when coping the
> > + * new image to its final location. To assure that the
> > + * arm64_relocate_new_kernel routine which does that copy is not overwritten,
> > + * all code and data needed by arm64_relocate_new_kernel must be between the
> > + * symbols arm64_relocate_new_kernel and arm64_relocate_new_kernel_end. The
> > + * machine_kexec() routine will copy arm64_relocate_new_kernel to the kexec
> > + * control_code_page, a special page which has been set up to be preserved
> > + * during the copy operation.
> > + */
> > +.globl arm64_relocate_new_kernel
> > +arm64_relocate_new_kernel:
> > +
> > +> > > > /* Setup the list loop variables. */
> > +> > > > mov> > > > x18, x0> > > > > > > > > > /* x18 = kimage_head */
> > +> > > > mov> > > > x17, x1> > > > > > > > > > /* x17 = kimage_start */
> > +> > > > dcache_line_size x16, x0> > > > > > /* x16 = dcache line size */
>
> Why is this needed?
This was left over from the previous version where we
invalidated pages while copying them. I've since added
that invalidate back, so this is again needed.
>
> > +> > > > mov> > > > x15, xzr> > > > > > > > /* x15 = segment start */
> > +> > > > mov> > > > x14, xzr> > > > > > > > /* x14 = entry ptr */
> > +> > > > mov> > > > x13, xzr> > > > > > > > /* x13 = copy dest */
> > +
> > +> > > > /* Clear the sctlr_el2 flags. */
> > +> > > > mrs> > > > x0, CurrentEL
> > +> > > > cmp> > > > x0, #CurrentEL_EL2
> > +> > > > b.ne> > > > 1f
> > +> > > > mrs> > > > x0, sctlr_el2
> > +> > > > ldr> > > > x1, =SCTLR_EL2_FLAGS
>
> If we're using literal pools, we probably want a .ltorg directive somewhere.
I've added one in at the end of the arm64_relocate_new_kernel
code.
> > +> > > > bic> > > > x0, x0, x1
> > +> > > > msr> > > > sctlr_el2, x0
> > +> > > > isb
> > +1:
> > +
> > +> > > > /* Check if the new image needs relocation. */
> > +> > > > cbz> > > > x18, .Ldone
> > +> > > > tbnz> > > > x18, IND_DONE_BIT, .Ldone
> > +
> > +.Lloop:
> > +> > > > and> > > > x12, x18, PAGE_MASK> > > > > > /* x12 = addr */
> > +
> > +> > > > /* Test the entry flags. */
> > +.Ltest_source:
> > +> > > > tbz> > > > x18, IND_SOURCE_BIT, .Ltest_indirection
> > +
> > +> > > > mov x20, x13> > > > > > > > > > /* x20 = copy dest */
> > +> > > > mov x21, x12> > > > > > > > > > /* x21 = copy src */
>
> Weird indentation.
Fixed.
> > +> > > > /* Copy page. */
> > +1:> > > > ldp> > > > x22, x23, [x21]
> > +> > > > ldp> > > > x24, x25, [x21, #16]
> > +> > > > ldp> > > > x26, x27, [x21, #32]
> > +> > > > ldp> > > > x28, x29, [x21, #48]
> > +> > > > add> > > > x21, x21, #64
> > +> > > > stnp> > > > x22, x23, [x20]
> > +> > > > stnp> > > > x24, x25, [x20, #16]
> > +> > > > stnp> > > > x26, x27, [x20, #32]
> > +> > > > stnp> > > > x28, x29, [x20, #48]
> > +> > > > add> > > > x20, x20, #64
> > +> > > > tst> > > > x21, #(PAGE_SIZE - 1)
> > +> > > > b.ne> > > > 1b
>
> We should macroise this, to save on duplication of a common routine.
So something like this in assembler.h?
+/*
+ * copy_page - copy src to dest using temp registers t1-t8
+ */
+ .macro copy_page dest:req src:req t1:req t2:req t3:req t4:req t5:req t6:req t7:req t8:req
+1: ldp /t1, /t2, [/src]
+ ldp /t3, /t4, [/src, #16]
+ ldp /t5, /t6, [/src, #32]
+ ldp /t7, /t8, [/src, #48]
+ add /src, /src, #64
+ stnp /t1, /t2, [/dest]
+ stnp /t3, /t4, [/dest, #16]
+ stnp /t5, /t6, [/dest, #32]
+ stnp /t7, /t8, [/dest, #48]
+ add /dest, /dest, #64
+ tst /src, #(PAGE_SIZE - 1)
+ b.ne 1b
+ .endm
> You also need to address the caching issues that Mark raised separately.
Cache maintenance has been fixed (reintroduced) in the current code.
>
> > +> > > > /* dest += PAGE_SIZE */
> > +> > > > add> > > > x13, x13, PAGE_SIZE
> > +> > > > b> > > > .Lnext
> > +
> > +.Ltest_indirection:
> > +> > > > tbz> > > > x18, IND_INDIRECTION_BIT, .Ltest_destination
> > +
> > +> > > > /* ptr = addr */
> > +> > > > mov> > > > x14, x12
> > +> > > > b> > > > .Lnext
> > +
> > +.Ltest_destination:
> > +> > > > tbz> > > > x18, IND_DESTINATION_BIT, .Lnext
> > +
> > +> > > > mov> > > > x15, x12
> > +
> > +> > > > /* dest = addr */
> > +> > > > mov> > > > x13, x12
> > +
> > +.Lnext:
> > +> > > > /* entry = *ptr++ */
> > +> > > > ldr> > > > x18, [x14], #8
> > +
> > +> > > > /* while (!(entry & DONE)) */
> > +> > > > tbz> > > > x18, IND_DONE_BIT, .Lloop
> > +
> > +.Ldone:
> > +> > > > dsb> > > > sy
> > +> > > > ic> > > > ialluis
>
> I don't think this needs to be inner-shareable, and these dsbs can probably
> be non-shareable too.
OK.
> > +> > > > dsb> > > > sy
> > +> > > > isb
> > +
> > +> > > > /* Start new image. */
> > +> > > > mov> > > > x0, xzr
> > +> > > > mov> > > > x1, xzr
> > +> > > > mov> > > > x2, xzr
> > +> > > > mov> > > > x3, xzr
> > +> > > > br> > > > x17
> > +
> > +.align 3> > > > /* To keep the 64-bit values below naturally aligned. */
> > +
> > +.Lcopy_end:
> > +.org> > > > KEXEC_CONTROL_PAGE_SIZE
> > +
> > +/*
> > + * arm64_relocate_new_kernel_size - Number of bytes to copy to the
> > + * control_code_page.
> > + */
> > +.globl arm64_relocate_new_kernel_size
> > +arm64_relocate_new_kernel_size:
> > +> > > > .quad> > > > .Lcopy_end - arm64_relocate_new_kernel
> > diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
> > index 99048e5..ccec467 100644
> > --- a/include/uapi/linux/kexec.h
> > +++ b/include/uapi/linux/kexec.h
> > @@ -39,6 +39,7 @@
> > #define KEXEC_ARCH_SH (42 << 16)
> > #define KEXEC_ARCH_MIPS_LE (10 << 16)
> > #define KEXEC_ARCH_MIPS ( 8 << 16)
> > +#define KEXEC_ARCH_ARM64 (183 << 16)
>
> This should probably be called KEXEC_ARCH_AARCH64 for consistency with
> the ELF machine name.
OK.
-Geoff
next prev parent reply other threads:[~2015-12-16 0:14 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-24 22:25 [PATCH v12 00/16] arm64 kexec kernel patches v12 Geoff Levand
2015-11-24 22:25 ` [PATCH v12 06/16] Revert "arm64: mm: remove unused cpu_set_idmap_tcr_t0sz function" Geoff Levand
2015-11-24 22:25 ` [PATCH v12 01/16] arm64: Fold proc-macros.S into assembler.h Geoff Levand
2015-11-24 22:25 ` [PATCH v12 04/16] arm64: kvm: allows kvm cpu hotplug Geoff Levand
2015-11-27 13:54 ` Marc Zyngier
2015-12-02 22:40 ` Ashwin Chaugule
2015-12-03 13:55 ` Ashwin Chaugule
2015-12-03 13:58 ` Marc Zyngier
2015-12-10 18:31 ` Geoff Levand
2015-12-11 16:31 ` Will Deacon
2015-12-15 8:48 ` AKASHI Takahiro
2015-12-10 18:44 ` Shi, Yang
2015-12-11 8:09 ` AKASHI Takahiro
2015-12-14 18:00 ` Shi, Yang
2015-12-11 8:06 ` AKASHI Takahiro
2015-12-11 13:00 ` Shanker Donthineni
2015-12-11 16:28 ` Marc Zyngier
2015-12-11 18:00 ` Shanker Donthineni
2015-12-11 18:11 ` Marc Zyngier
2015-12-11 19:11 ` Shanker Donthineni
2015-12-11 20:13 ` Ashwin Chaugule
2015-12-14 7:33 ` AKASHI Takahiro
2015-12-14 17:33 ` Marc Zyngier
2015-12-15 7:51 ` AKASHI Takahiro
2015-12-15 8:45 ` Marc Zyngier
2015-12-15 9:51 ` AKASHI Takahiro
2015-12-15 10:13 ` Marc Zyngier
2015-11-24 22:25 ` [PATCH v12 05/16] arm64: Add back cpu_reset routines Geoff Levand
2015-11-27 14:19 ` Marc Zyngier
2015-11-30 5:28 ` Pratyush Anand
2015-11-30 10:40 ` Marc Zyngier
2015-12-02 22:57 ` Geoff Levand
2015-12-03 9:32 ` Will Deacon
2015-12-10 0:49 ` Geoff Levand
2015-12-10 10:17 ` Will Deacon
2015-11-30 20:03 ` Geoff Levand
2015-12-01 9:38 ` Marc Zyngier
2015-11-24 22:25 ` [PATCH v12 03/16] arm64: Add new hcall HVC_CALL_FUNC Geoff Levand
2015-11-24 22:25 ` [PATCH v12 07/16] Revert "arm64: remove dead code" Geoff Levand
2015-11-24 22:25 ` [PATCH v12 02/16] arm64: Convert hcalls to use HVC immediate value Geoff Levand
2015-11-24 22:25 ` [PATCH v12 12/16] arm64: kdump: implement machine_crash_shutdown() Geoff Levand
2015-11-27 14:39 ` Marc Zyngier
2015-12-10 11:34 ` AKASHI Takahiro
2015-12-10 11:44 ` Marc Zyngier
2015-12-10 12:55 ` AKASHI Takahiro
2015-12-10 13:43 ` Marc Zyngier
2015-12-03 4:15 ` Pratyush Anand
2015-12-10 11:42 ` AKASHI Takahiro
2015-12-10 11:50 ` Pratyush Anand
2015-11-24 22:25 ` [PATCH v12 13/16] arm64: kdump: add kdump support Geoff Levand
2015-12-15 17:45 ` Will Deacon
2015-12-16 5:41 ` AKASHI Takahiro
2015-11-24 22:25 ` [PATCH v12 09/16] arm64/kexec: Add pr_devel output Geoff Levand
2015-12-15 17:15 ` Will Deacon
2015-12-16 0:45 ` Geoff Levand
2015-12-16 0:46 ` [PATCH v12.4] arm64/kexec: Add pr_debug output Geoff Levand
2015-11-24 22:25 ` [PATCH v12 11/16] arm64: kdump: reserve memory for crash dump kernel Geoff Levand
2015-12-15 17:29 ` Will Deacon
2015-12-16 5:19 ` AKASHI Takahiro
2015-12-16 7:36 ` Pratyush Anand
2015-11-24 22:25 ` [PATCH v12 10/16] arm64/kexec: Enable kexec in the arm64 defconfig Geoff Levand
2015-11-24 22:25 ` [PATCH v12 08/16] arm64/kexec: Add core kexec support Geoff Levand
2015-11-27 13:13 ` Pratyush Anand
2015-11-30 18:51 ` Geoff Levand
2015-12-01 2:16 ` Pratyush Anand
2015-12-01 18:32 ` Azriel Samson
2015-12-02 22:49 ` Geoff Levand
2015-12-03 4:37 ` Azriel Samson
2015-12-03 19:56 ` Geoff Levand
2015-12-04 0:39 ` Azriel Samson
2015-12-04 3:54 ` Pratyush Anand
2015-12-07 18:47 ` Geoff Levand
2015-12-03 6:09 ` Pratyush Anand
2015-12-01 19:03 ` Mark Rutland
2015-12-02 21:08 ` Geoff Levand
2015-12-03 16:06 ` Mark Rutland
2015-12-15 18:29 ` Will Deacon
2015-12-16 0:14 ` Geoff Levand [this message]
2015-12-16 7:18 ` Pratyush Anand
2015-12-16 9:30 ` James Morse
2015-12-16 10:32 ` Pratyush Anand
2015-12-16 0:14 ` [PATCH v12.4] " Geoff Levand
2015-11-24 22:25 ` [PATCH v12 15/16] arm64: kdump: enable kdump in the arm64 defconfig Geoff Levand
2015-11-24 22:25 ` [PATCH v12 14/16] arm64: kdump: update a kernel doc Geoff Levand
2015-12-15 17:17 ` Will Deacon
2015-12-16 5:48 ` AKASHI Takahiro
2015-11-24 22:25 ` [PATCH v12 16/16] arm64: kdump: relax BUG_ON() if more than one cpus are still active Geoff Levand
2015-12-15 17:05 ` Will Deacon
2015-12-16 5:51 ` AKASHI Takahiro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1450224870.24127.130.camel@infradead.org \
--to=geoff@infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).