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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.