From: dave.martin@linaro.org (Dave Martin)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 4/6] ARM: reset: add reset functionality for jumping to a physical address
Date: Tue, 7 Jun 2011 16:36:54 +0100 [thread overview]
Message-ID: <20110607153654.GA19855@arm.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1106071435020.2247@localhost6.localdomain6>
On Tue, Jun 07, 2011 at 02:54:53PM +0100, Frank Hofmann wrote:
>
>
> On Tue, 7 Jun 2011, Will Deacon wrote:
>
> >Hi Frank,
> >
> >Thanks for looking at this.
>
> Thanks for posting it ;-)
>
> [ ... ]
> >>>>+ /* Switch to the identity mapping. */
> >>>>+ ((typeof(cpu_reset) *)virt_to_phys((void *)cpu_reset))(reset_code_phys);
> >>>
> >>>void (*reset_func)(unsigned long) = virt_to_phys(cpu_reset)
> >>
> >>Sorry, pressed wrong key ... posted too early.
> >
> >No problem.
> >
> >>I meant to say this line is magic, why not decouple the declaration bit
> >>from the invocation so that at least the function call looks "normal" ?
> >
> >You mean you don't like the LISP-ish look of it?! I take your point, I'll rework
> >that.
>
> typeof(cpu_reset)(*phys_reset) =
> (typeof(cpu_reset) *)virt_to_phys(cpu_reset);
This is a declaration, but the extra parentheses confuse me.
How about:
typeof(cpu_reset) *phys_reset =
(typeof(cpu_reset) *)virt_to_phys(cpu_reset);
or even:
typedef typeof(cpu_reset) *phys_reset_t;
phys_reset_t phys_reset = (phys_reset_t)virt_to_phys(cpu_reset);
>
> reset_func(reset_code_phys);
Do you mean reset_func(phys_reset) ?
>
> Works for me. Was experimenting with this when I pressed the wrong key.
>
> >
> >>Regarding the use of local_irq/fiq_disable - is it safe to call these
> >>multiple times, i.e. is it safe to invoke the reset function from a
> >>context where IRQ/FIQ are already off ?
> >
> >Yes, they just mask at the CPSR level.
>
> Good, thx for the confirmation.
>
> >
> >>
> >>Another question regarding the MMU tables.
> >>
> >>prepare_for_reboot / setup_mm_for_reboot assume that current->mm is
> >>available _and_ lowmem / user area there can be blotted over.
> >>
> >>Wrt. to hibernation, that's a stretch unless some way is found to fully
> >>"fake a context". With that I mean to create a threadinfo and pagedir
> >>that's guaranteed to sit outside the target kernel heap.
> >
> >Ouch, ok.
> >
> >>Currently, the hibernation code switches to swapper_pg_dir and puts the
> >>1:1 mappings in there; I'm starting to think that is safe if for no other
> >>reason than swapper_pg_dir having _nothing_ in the user area ?
> >
> >That sounds ok providing that, when you come out of hibernate, the 1:1 mapping
> >doesn't persist in swapper_pg_dir.
>
> I can delete those mappings - as they're created by
> identity_mapping_add() they can be ditched with
> identity_mapping_del() - which might be sufficient, provided, and
> there's the critical bit why I ask, that swapper_pg_dir _normally_
> has nothing in the range anyway.
>
> Thing is, just because something appears to work doesn't mean it has
> no unexpected/undesired side effects ... and I'm no ARM VM guru.
>
>
> >
> >However, stepping back a bit here, there is a bigger problem to tackle. If the
> >physical address of cpu_reset is bigger than TASK_SIZE, then we fail to map it
> >using the current identity mapping code [that piggy backs on the current task].
> >If PHYS_OFFSET > TASK_SIZE, this will *always* be the case and is probably quite
> >common for a 2:2 split.
> >
> >I can think of two ways to get around this:
> >
> >(1) Use /another/ set of page tables for mapping the cpu_reset code only [and
> > nothing else]. This is tricky since it will need to be set extremely late-on
> > where we don't care about mapping in the rest of the kernel, data, stack etc.
> >
> >(2) Make the assumption that the physical address of cpu_reset will not conflict
> > with a virtual address that points at the kernel text via the linear mapping.
> > This is probably a reasonable thing to assume, given that the kernel lives
> > near the start of memory on most platforms. We could then take out the ID map
> > but leaving the kernel text alone. We'd probably have to change to a new stack,
> > which we could place immediately after the kernel text.
> >
> >What do you reckon?
>
> cpu_reset itself is relocatable, isn't it ? Maybe one could do the
> same thing with/for it as for the reset code itself. I.e. relocate
> to a "suitable" page if the 1:1 mapping for all of lowmem isn't
> possible. The catch with that is of course somehow, such a "1:1
> candidate page" must be found.
If cpu_reset is guaranteed to be position-independent and self-contained, we could
just copy it (with fncpy() for example). We would still need to know the length
of that function somehow though. Maybe just assuming that it's not longer than
a page would be safe enough.
In this case we would just need to find an identity-mappable target location to
copy the code to; we can find such a location in the same way as that used to
find space for the alternate stack, i.e., somewhere after the end of the kernel
image.
Cheers
---Dave
next prev parent reply other threads:[~2011-06-07 15:36 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-06 17:04 [PATCH 0/6] MMU disabling code and kexec fixes Will Deacon
2011-06-06 17:04 ` [PATCH 1/6] ARM: l2x0: fix disabling function to avoid livelock Will Deacon
2011-06-06 17:04 ` [PATCH 2/6] ARM: l2x0: fix invalidate-all " Will Deacon
2011-06-06 17:04 ` [PATCH 3/6] ARM: proc-v7: add definition of cpu_reset for ARMv7 cores Will Deacon
2011-06-06 17:04 ` [PATCH 4/6] ARM: reset: add reset functionality for jumping to a physical address Will Deacon
2011-06-07 11:22 ` Frank Hofmann
2011-06-07 11:37 ` Frank Hofmann
2011-06-07 13:22 ` Will Deacon
2011-06-07 13:54 ` Frank Hofmann
2011-06-07 15:36 ` Dave Martin [this message]
2011-06-07 16:21 ` Frank Hofmann
2011-06-08 15:55 ` Frank Hofmann
2011-06-08 16:05 ` Will Deacon
2011-06-08 16:10 ` Frank Hofmann
2011-06-08 16:14 ` Will Deacon
2011-06-08 16:24 ` Dave Martin
2011-06-09 10:00 ` Frank Hofmann
2011-06-09 10:06 ` Will Deacon
2011-06-06 17:04 ` [PATCH 5/6] ARM: kexec: use arm_machine_reset for branching to the reboot buffer Will Deacon
2011-06-06 17:04 ` [PATCH 6/6] ARM: stop: execute platform callback from cpu_stop code Will Deacon
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=20110607153654.GA19855@arm.com \
--to=dave.martin@linaro.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).