linux-arm-kernel.lists.infradead.org archive mirror
 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:06:42 +0000	[thread overview]
Message-ID: <54EF60B2.1050401@arm.com> (raw)
In-Reply-To: <1424964547-2118-4-git-send-email-ard.biesheuvel@linaro.org>

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...)?

> +#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...

But hey, it's so mad I like it! ;-)

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

  parent reply	other threads:[~2015-02-26 18:06 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 [this message]
2015-02-26 18:17     ` Ard Biesheuvel
2015-02-26 18:51       ` Marc Zyngier
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=54EF60B2.1050401@arm.com \
    --to=marc.zyngier@arm.com \
    --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).