From: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: Dave Martin <dave.martin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Russell King <linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org>,
Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>,
Kyungmin Park <kmpark-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
"linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org"
<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>,
Marek Szyprowski
<m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Subject: Re: Bindings for SMC/HVC firmware interfaces on ARM (Re: [RFC PATCH] ARM: Make a compile trustzone conditionally)
Date: Wed, 20 Jun 2012 10:14:01 -0500 [thread overview]
Message-ID: <4FE1E8B9.2020200@gmail.com> (raw)
In-Reply-To: <20120620105116.GA2179-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On 06/20/2012 05:51 AM, Dave Martin wrote:
> On Wed, Jun 20, 2012 at 10:43:34AM +0100, Will Deacon wrote:
>> Hi Stephen,
>>
>> On Wed, Jun 20, 2012 at 02:22:14AM +0100, Stephen Boyd wrote:
>>> On 06/18/12 07:10, Arnd Bergmann wrote:
>>>> Instead of checking for trustzone_enabled() in each place where
>>>> we call into smc, we can have a generic implementation that
>>>> we call for the disabled case, and provide a vendor specific
>>>> version of that struct with functions that call into smp
>>>> where necessary.
>>>>
>>>
>>> What if we tried to read the SCR.NS bit to determine if we're running in
>>> secure state or not? It looks like reading SCR is UNDEFINED (i.e. causes
>>> an undefined instruction exception) if we're running in the non-secure
>>> state so I propose we set up an undef hook that traps the SCR access and
>>> lies about the value of the NS bit to indicate we're non-secure.
>>> Basically this:
>>
>> Well, I can't resist reviewing the code, but I don't think we should be
>> trying to detect this (see below).
>>
>>> static int scr_trap(struct pt_regs *regs, unsigned int instr)
>>> {
>>> int reg = (instr >> 12) & 15;
>>> if (reg == 15)
>>> return 1;
>>
>> Eek -- surely GCC won't allocate PC for the destination register?!
>>
>>> regs->uregs[reg] = BIT(0); /* Trapped = non-secure */
>>> regs->ARM_pc += 4;
>>> return 0;
>>> }
>>>
>>> static struct undef_hook scr_hook = {
>>> .instr_mask = 0x0fff0fff,
>>> .instr_val = 0x0e110f11,
>>> .fn = scr_trap,
>>> };
>
> (you'd also need to handle the Thumb case; I digress...)
>
>>>
>>> int in_secure_state(void)
>>> {
>>> unsigned int scr;
>>>
>>> register_undef_hook(&scr_hook);
>>>
>>> asm volatile(
>>> " mrc p15, 0, %0, c1, c1, 0\n"
>>> : "=r" (scr)
>>> :
>>> : "cc");
>>
>> I don't think you need this clobber either.
>>> It seems to mostly work, although I haven't figured out what you do
>>> about the hypervisor case when the hypervisor has disabled the smc
>>> instruction entirely (SCR.SCD=1). At that point I throw up my hands.
>>> Maybe Will has some idea.
Perhaps there are other registers with fewer/different bits in
non-secure mode. IIRC, the A9 GIC has different secure and non-secure
enable bits in a mirrored register. This wouldn't be the best choice
given it is A9 specific and in the GIC.
>>
>> I think this is part of a bigger problem, which is about how we know where
>> we live in the privilege hierarchy and what we have sitting above us. We
>> have exactly the same issue with hypervisors and the hvc instruction.
>>
>> Rather than try to probe the instruction (which by itself isn't enough,
>> since we can't guarantee that the exception will be handled by the upper
>> layers) I would personally prefer to see this described in the device tree.
>> We could have a simple property in the CPU node that says what the interface
>> looks like:
>>
>> smc-interface = "samsung, exynos";
You already know you're on samsung,exynos, so you minimally only need to
know non-secure or secure. Presence of the property can indicate
non-secure mode and then the value can be something meaningful to that
platform like version.
>>
>> or whatever you need to identify the interface uniquely. You could have a
>> corresponding entry for hvc-interface (and something like KVM could pass
>> its version to the guest for paravirualisation). If the property is missing,
>> then we take that to mean that the instruction shouldn't be executed on that
>> core -- it may be undefined or there may not be anything to pick up the
>> exception.
>
> I concur.
>
> The firmware is the only thing that really knows what's there,
> and in reality there's no safe way to probe. Even if we know we're in the
> Normal World, we have no idea what's on the other side of SMC. One
> firmware's "probe" call may be another firmware's "halt and catch fire"
> call.
That reminds me. I need to go write the halt and catch fire call.
>
> So DT bindings permitting the firmware to tell us what's there make a lot
> of sense.
>
>
> Fleshing this out a bit...
>
> Since the SMC and HVC instructions are features of the architecture, it may
> make sense for the names to be:
>
> arm,smc = "vendor,interface-name";
> arm,hvc = "vendor,interface-name";
>
> Some platforms may not fully service SMC on all CPUs, so there might be a
> need to set this per CPU node. This can be topologically determined, so
> you might have:
You would know this by knowing the type of firmware.
>
> cluster@0 {
> arm,smc = "vendor,platform-basic-firmware";
>
> cpu@0 {
> arm,smc = "vendor,platform-fancy-firmware";
> };
>
> cpu@1 {
> // no arm,smc property
> };
>
> cpu@2 {
> // no arm,smc property
> };
>
> // ...
> }
>
> The set of supported SMC calls on a CPU would then be determined by the
> list of all strings on arm,smc properties on that CPU node and its
> ancestors.
>
> If the arm,smc or arm,hvc property is absent at all levels of the
> topology, this does not mean that there is nothing there, but it does
> mean that nothing is known about what's there. Platform code would fall
> back to the legacy case in that situation.
>
>
> If additional properties are needed, like version or capability info,
> we could have nodes instead:
>
> cluster@0 {
> arm,smc {
> basic-firmware {
> compatible = "vendor,platform-basic-firmware";
> };
> }
>
> cpu@0 {
> arm,smc {
> fancy-firmware {
> compatible = "vendor,platform-fancy-firmware";
> version = <1 12>;
> capabilities = "whizz", "bang", "kapow";
> };
>
> common-firmware {
> compatible = "standards-body,common-firmware";
> version = <1 0>;
> }
> };
> };
>
> // ...
> };
>
> ...or something equally esoteric.
>
This seems overly complex. While all of these conditions could happen,
what is reality?
I hope this smc mess is getting standardized for v8...
Rob
> (If node names like "arm,smc" are acceptable ... we could have something
> else if not.)
>
> It would be up to the platform's code handling "vendor,platform-fancy-
> firmware" etc. to know about and deal with the precise calling
> conventions for that firmware, though if there are generic firmware
> interfaces someday, then those nodes' support code could be shared.
>
> Cheers
> ---Dave
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
next prev parent reply other threads:[~2012-06-20 15:14 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20120611051502.GA24030@july>
[not found] ` <CAOesGMgGQMwQTUy2g-XSYFrQ-p+x9g2q8kAd-ZYq=TBgVFu0Zw@mail.gmail.com>
[not found] ` <CAH9JG2X=15G6wDX5SGJkDEVohkQQkzfBoL3Qv7HVuBUMqYnwRg@mail.gmail.com>
[not found] ` <201206181410.39267.arnd@arndb.de>
[not found] ` <4FE125C6.3030401@codeaurora.org>
[not found] ` <20120620094334.GA32666@mudshark.cambridge.arm.com>
[not found] ` <20120620094334.GA32666-MRww78TxoiP5vMa5CHWGZ34zcgK1vI+I0E9HWUfgJXw@public.gmane.org>
2012-06-20 10:51 ` Bindings for SMC/HVC firmware interfaces on ARM (Re: [RFC PATCH] ARM: Make a compile trustzone conditionally) Dave Martin
[not found] ` <20120620105116.GA2179-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2012-06-20 15:14 ` Rob Herring [this message]
[not found] ` <4FE1E8B9.2020200-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-06-20 15:34 ` Dave Martin
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=4FE1E8B9.2020200@gmail.com \
--to=robherring2-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
--cc=dave.martin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \
--cc=kmpark-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org \
--cc=m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org \
--cc=sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=will.deacon-5wv7dgnIgG8@public.gmane.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).