public inbox for linux-arm-kernel@lists.infradead.org 
 help / color / mirror / Atom feed
From: marc.zyngier@arm•com (Marc Zyngier)
To: linux-arm-kernel@lists•infradead.org
Subject: [RFC PATCH 3/3] arm64: KVM: use ID map with increased VA range if required
Date: Thu, 26 Feb 2015 18:51:17 +0000	[thread overview]
Message-ID: <54EF6B25.5010103@arm.com> (raw)
In-Reply-To: <CAKv+Gu8=tAb7+d1qkmY47AvKjs_mjkK=NCMqutPJg9hLV5DY0Q@mail.gmail.com>

On 26/02/15 18:17, Ard Biesheuvel wrote:
> On 26 February 2015 at 18:06, Marc Zyngier <marc.zyngier@arm•com> wrote:
>> On 26/02/15 15:29, Ard Biesheuvel wrote:
>>> This patch modifies the HYP init code so it can deal with system
>>> RAM residing at an offset which exceeds the reach of VA_BITS.
>>>
>>> Like for EL1, this involves configuring an additional level of
>>> translation for the ID map. However, in case of EL2, this implies
>>> that all translations use the extra level, as we cannot seamlessly
>>> switch between translation tables with different numbers of
>>> translation levels. For this reason, the ID map is merged with
>>> the runtime HYP map, since they don't overlap anyway.
>>>
>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro•org>
>>> ---
>>>  arch/arm64/kvm/hyp-init.S | 40 ++++++++++++++++++++++++++++++++++++++--
>>>  1 file changed, 38 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
>>> index c3191168a994..0af16bce6316 100644
>>> --- a/arch/arm64/kvm/hyp-init.S
>>> +++ b/arch/arm64/kvm/hyp-init.S
>>> @@ -20,6 +20,7 @@
>>>  #include <asm/assembler.h>
>>>  #include <asm/kvm_arm.h>
>>>  #include <asm/kvm_mmu.h>
>>> +#include <asm/pgtable-hwdef.h>
>>>
>>>       .text
>>>       .pushsection    .hyp.idmap.text, "ax"
>>> @@ -58,13 +59,44 @@ __invalid:
>>>        */
>>>  __do_hyp_init:
>>>
>>> -     msr     ttbr0_el2, x0
>>> -
>>>       mrs     x4, tcr_el1
>>>       ldr     x5, =TCR_EL2_MASK
>>>       and     x4, x4, x5
>>>       ldr     x5, =TCR_EL2_FLAGS
>>>       orr     x4, x4, x5
>>> +
>>> +#ifndef CONFIG_ARM64_VA_BITS_48
>>> +     /*
>>> +      * If we are running with VA_BITS < 48, we may be running with an extra
>>> +      * level of translation in the ID map. This is only the case if system
>>> +      * RAM is out of range for the currently configured page size and number
>>> +      * of translation levels, in which case we will also need the extra
>>> +      * level for the HYP ID map, or we won't be able to enable the EL2 MMU.
>>> +      *
>>> +      * However, at EL2, there is only one TTBR register, and we can't switch
>>> +      * between translation tables *and* update TCR_EL2.T0SZ at the same
>>> +      * time. Bottom line: we need the extra level in *both* our translation
>>> +      * tables.
>>> +      *
>>> +      * Fortunately, there is an easy way out: the existing ID map, with the
>>> +      * extra level, can be reused for both. The kernel image is already
>>> +      * identity mapped at a high virtual offset, which leaves VA_BITS of
>>> +      * address space at the low end to put our runtime HYP mappings.
>>> +      */
>>> +     adrp    x5, idmap_t0sz                  // get ID map TCR.T0SZ
>>> +     ldr     x5, [x5, :lo12:idmap_t0sz]
>>> +     cmp     x5, TCR_T0SZ(VA_BITS)           // extra level configured?
>>> +     b.ge    1f                              // if not, skip
>>> +
>>> +     bfi     x4, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH
>>> +
>>> +     adrp    x0, idmap_pg_dir        // get root of ID map
>>> +     orr     x5, x1, PMD_TYPE_TABLE  // table entry pointing at HYP pgd
>>> +     str     x5, [x0]                // store at offset #0
>>> +     mov     x1, #0
>>> +1:
>>
>> Wow. This is making my head spin a bit.
>>
>> Nitpick: shouldn't you use PUD_TYPE_TABLE instead of PMD_TYPE_TABLE
>> (yeah, I know, that's the same thing...)?
>>
> 
> I think both are equally inappropriate, considering that this is the
> level above PGD. But I am happy to switch one for the other ...

Yeah, brainfart here. We'd need a PGD_TYPE_TABLE, but I don't think it's
worth the hassle.

> 
>>> +#endif
>>> +     msr     ttbr0_el2, x0
>>>       msr     tcr_el2, x4
>>>
>>>       ldr     x4, =VTCR_EL2_FLAGS
>>> @@ -91,6 +123,9 @@ __do_hyp_init:
>>>       msr     sctlr_el2, x4
>>>       isb
>>>
>>> +     /* Skip the trampoline dance if we merged the boot and runtime PGDs */
>>> +     cbz     x1, merged
>>> +
>>>       /* MMU is now enabled. Get ready for the trampoline dance */
>>>       ldr     x4, =TRAMPOLINE_VA
>>>       adr     x5, target
>>> @@ -105,6 +140,7 @@ target: /* We're now in the trampoline code, switch page tables */
>>>       tlbi    alle2
>>>       dsb     sy
>>>
>>> +merged:
>>>       /* Set the stack and new vectors */
>>>       kern_hyp_va     x2
>>>       mov     sp, x2
>>>
>>
>> The one thing that worries here is that our EL1 idmap is not a strict
>> idmap anymore. I really wonder what we can break with that...
>>
> 
> Yes, that is the question I had myself. The other issue is that we
> never remove the entry we add at the root level in this code, which I
> don't think matters that much but it would be good if someone could
> confirm.

Do you mean having both the idmap and the runtime mappings in EL2? I'm
trying to break it, but I don't see any obvious issues, except for the
semi-religious fear of keeping unused mappings around....

Worse case, we could have a hyp-specific idmap, and nuke/populate the
idmap pgd entry as we see fit. One thing at a time...

	M.
-- 
Jazz is not dead. It just smells funny...

  reply	other threads:[~2015-02-26 18:51 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-26 15:29 [RFC PATCH 0/3] arm64: KVM: use increased VA range if needed Ard Biesheuvel
2015-02-26 15:29 ` [RFC PATCH 1/3] ARM, arm64: kvm: get rid of the bounce page Ard Biesheuvel
2015-02-26 16:10   ` Marc Zyngier
2015-02-26 17:31     ` Ard Biesheuvel
2015-02-26 18:24       ` Marc Zyngier
2015-02-26 18:41         ` Ard Biesheuvel
2015-02-27  8:19           ` Ard Biesheuvel
2015-02-26 15:29 ` [RFC PATCH 2/3] arm64: make ID map shareable with EL2 Ard Biesheuvel
2015-02-26 15:29 ` [RFC PATCH 3/3] arm64: KVM: use ID map with increased VA range if required Ard Biesheuvel
2015-02-26 16:11   ` Catalin Marinas
2015-02-26 16:29     ` Catalin Marinas
2015-02-26 16:56     ` Ard Biesheuvel
2015-02-26 18:07       ` Catalin Marinas
2015-02-26 18:06   ` Marc Zyngier
2015-02-26 18:17     ` Ard Biesheuvel
2015-02-26 18:51       ` Marc Zyngier [this message]
2015-02-26 19:04         ` Ard Biesheuvel

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=54EF6B25.5010103@arm.com \
    --to=marc.zyngier@arm$(echo .)com \
    --cc=linux-arm-kernel@lists$(echo .)infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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