diff mbox series

target/arm: Implement ARMv8.1-VMID16 extension

Message ID 20200210120146.17631-1-peter.maydell@linaro.org
State Superseded
Headers show
Series target/arm: Implement ARMv8.1-VMID16 extension | expand

Commit Message

Peter Maydell Feb. 10, 2020, 12:01 p.m. UTC
The ARMv8.1-VMID16 extension extends the VMID from 8 bits to 16 bits:

 * the ID_AA64MMFR1_EL1.VMIDBits field specifies whether the VMID is
   8 or 16 bits
 * the VMID field in VTTBR_EL2 is extended to 16 bits
 * VTCR_EL2.VS lets the guest specify whether to use the full 16 bits,
   or use the backwards-compatible 8 bits

For QEMU implementing this is trivial:
 * we do not track VMIDs in TLB entries, so we never use the VMID field
 * we treat any write to VTTBR_EL2, not just a change to the VMID field
   bits, as a "possible VMID change" that causes us to throw away TLB
   entries, so that code doesn't need changing
 * we allow the guest to read/write the VTCR_EL2.VS bit already

So all that's missing is the ID register part: report that we support
VMID16 in our 'max' CPU.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

---
Not something anybody's been asking for, but worthwhile as
a step towards finishing off support for all the v8.1 extensions.

 target/arm/cpu64.c | 1 +
 1 file changed, 1 insertion(+)

-- 
2.20.1

Comments

Alex Bennée Feb. 10, 2020, 12:23 p.m. UTC | #1
Peter Maydell <peter.maydell@linaro.org> writes:

> The ARMv8.1-VMID16 extension extends the VMID from 8 bits to 16 bits:

>

>  * the ID_AA64MMFR1_EL1.VMIDBits field specifies whether the VMID is

>    8 or 16 bits

>  * the VMID field in VTTBR_EL2 is extended to 16 bits

>  * VTCR_EL2.VS lets the guest specify whether to use the full 16 bits,

>    or use the backwards-compatible 8 bits

>

> For QEMU implementing this is trivial:

>  * we do not track VMIDs in TLB entries, so we never use the VMID

> field


Not currently but does the VMID allow you to have per-guest page table
caching? Last time I chatted to rth about potential performance wins we
discussed how easy it would be to support this in the softmmu now we
have indirect TLB lookups anyway. Given how much time is currently spent
expensively re-populating tables we could keep the last couple of id
tagged tables around for faster switching between sets of tables.

>  * we treat any write to VTTBR_EL2, not just a change to the VMID field

>    bits, as a "possible VMID change" that causes us to throw away TLB

>    entries, so that code doesn't need changing

>  * we allow the guest to read/write the VTCR_EL2.VS bit already

>

> So all that's missing is the ID register part: report that we support

> VMID16 in our 'max' CPU.

>

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

> ---

> Not something anybody's been asking for, but worthwhile as

> a step towards finishing off support for all the v8.1 extensions.

>

>  target/arm/cpu64.c | 1 +

>  1 file changed, 1 insertion(+)

>

> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c

> index 2d97bf45e1e..bf2cf278c03 100644

> --- a/target/arm/cpu64.c

> +++ b/target/arm/cpu64.c

> @@ -672,6 +672,7 @@ static void aarch64_max_initfn(Object *obj)

>          t = cpu->isar.id_aa64mmfr1;

>          t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */

>          t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);

> +        t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */

>          cpu->isar.id_aa64mmfr1 = t;

>  

>          /* Replicate the same data to the 32-bit id registers.  */


I guess we can easily add the isar_feature_aa64_ functions when we need
them.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>


-- 
Alex Bennée
Peter Maydell Feb. 10, 2020, 1:19 p.m. UTC | #2
On Mon, 10 Feb 2020 at 12:23, Alex Bennée <alex.bennee@linaro.org> wrote:
>

>

> Peter Maydell <peter.maydell@linaro.org> writes:

>

> > The ARMv8.1-VMID16 extension extends the VMID from 8 bits to 16 bits:

> >

> >  * the ID_AA64MMFR1_EL1.VMIDBits field specifies whether the VMID is

> >    8 or 16 bits

> >  * the VMID field in VTTBR_EL2 is extended to 16 bits

> >  * VTCR_EL2.VS lets the guest specify whether to use the full 16 bits,

> >    or use the backwards-compatible 8 bits

> >

> > For QEMU implementing this is trivial:

> >  * we do not track VMIDs in TLB entries, so we never use the VMID

> > field

>

> Not currently but does the VMID allow you to have per-guest page table

> caching? Last time I chatted to rth about potential performance wins we

> discussed how easy it would be to support this in the softmmu now we

> have indirect TLB lookups anyway. Given how much time is currently spent

> expensively re-populating tables we could keep the last couple of id

> tagged tables around for faster switching between sets of tables.


Yeah, in hardware the whole point of the VMID is to have per-guest
caching of VA-to-PA mappings in the TLB so you don't have to blow
them all away when you switch VM (just as ASID does for processes).
The difficulty with QEMU has always been that adding the "and is this
the right VMID/ASID" to the softmmu fastpath code would be expensive,
AIUI. If we ever come up with a clever plan for this it should be
no different if the VMID field is 16 vs 8 bits, though.

thanks
-- PMM
Richard Henderson Feb. 10, 2020, 5:05 p.m. UTC | #3
On 2/10/20 1:19 PM, Peter Maydell wrote:
> On Mon, 10 Feb 2020 at 12:23, Alex Bennée <alex.bennee@linaro.org> wrote:

>>

>>

>> Peter Maydell <peter.maydell@linaro.org> writes:

>>

>>> The ARMv8.1-VMID16 extension extends the VMID from 8 bits to 16 bits:

>>>

>>>  * the ID_AA64MMFR1_EL1.VMIDBits field specifies whether the VMID is

>>>    8 or 16 bits

>>>  * the VMID field in VTTBR_EL2 is extended to 16 bits

>>>  * VTCR_EL2.VS lets the guest specify whether to use the full 16 bits,

>>>    or use the backwards-compatible 8 bits

>>>

>>> For QEMU implementing this is trivial:

>>>  * we do not track VMIDs in TLB entries, so we never use the VMID

>>> field

>>

>> Not currently but does the VMID allow you to have per-guest page table

>> caching? Last time I chatted to rth about potential performance wins we

>> discussed how easy it would be to support this in the softmmu now we

>> have indirect TLB lookups anyway. Given how much time is currently spent

>> expensively re-populating tables we could keep the last couple of id

>> tagged tables around for faster switching between sets of tables.

> 

> Yeah, in hardware the whole point of the VMID is to have per-guest

> caching of VA-to-PA mappings in the TLB so you don't have to blow

> them all away when you switch VM (just as ASID does for processes).


Yep.

> The difficulty with QEMU has always been that adding the "and is this

> the right VMID/ASID" to the softmmu fastpath code would be expensive,


Yep.  My current half-baked idea for this does not involve changing the
fastpath, but swapping out softmmu tlbs in bulk.
Which is possible now that there's a pointer involved, and not 8k of data in an
array.

> AIUI. If we ever come up with a clever plan for this it should be

> no different if the VMID field is 16 vs 8 bits, though.


Yep.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>



r~
Philippe Mathieu-Daudé Feb. 12, 2020, 6:33 a.m. UTC | #4
On 2/10/20 1:01 PM, Peter Maydell wrote:
> The ARMv8.1-VMID16 extension extends the VMID from 8 bits to 16 bits:

> 

>   * the ID_AA64MMFR1_EL1.VMIDBits field specifies whether the VMID is

>     8 or 16 bits

>   * the VMID field in VTTBR_EL2 is extended to 16 bits

>   * VTCR_EL2.VS lets the guest specify whether to use the full 16 bits,

>     or use the backwards-compatible 8 bits

> 

> For QEMU implementing this is trivial:

>   * we do not track VMIDs in TLB entries, so we never use the VMID field

>   * we treat any write to VTTBR_EL2, not just a change to the VMID field

>     bits, as a "possible VMID change" that causes us to throw away TLB

>     entries, so that code doesn't need changing

>   * we allow the guest to read/write the VTCR_EL2.VS bit already

> 

> So all that's missing is the ID register part: report that we support

> VMID16 in our 'max' CPU.

> 

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

> ---

> Not something anybody's been asking for, but worthwhile as

> a step towards finishing off support for all the v8.1 extensions.

> 

>   target/arm/cpu64.c | 1 +

>   1 file changed, 1 insertion(+)

> 

> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c

> index 2d97bf45e1e..bf2cf278c03 100644

> --- a/target/arm/cpu64.c

> +++ b/target/arm/cpu64.c

> @@ -672,6 +672,7 @@ static void aarch64_max_initfn(Object *obj)

>           t = cpu->isar.id_aa64mmfr1;

>           t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */

>           t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);

> +        t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */

>           cpu->isar.id_aa64mmfr1 = t;

>   

>           /* Replicate the same data to the 32-bit id registers.  */

> 


Trivial conflict with:

commit cd3f80aba0c559a6291f7c3e686422b15381f6b7
Author: Richard Henderson <richard.henderson@linaro.org>
Date:   Fri Feb 7 14:04:27 2020 +0000

     target/arm: Enable ARMv8.1-VHE in -cpu max

     Tested-by: Alex Bennée <alex.bennee@linaro.org>

     Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

     Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

     Message-id: 20200206105448.4726-38-richard.henderson@linaro.org
     Signed-off-by: Peter Maydell <peter.maydell@linaro.org>


diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 2d97bf45e1..c80fb5fd43 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -672,6 +672,7 @@ static void aarch64_max_initfn(Object *obj)
          t = cpu->isar.id_aa64mmfr1;
          t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
          t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
+        t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
          cpu->isar.id_aa64mmfr1 = t;

          /* Replicate the same data to the 32-bit id registers.  */
diff mbox series

Patch

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 2d97bf45e1e..bf2cf278c03 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -672,6 +672,7 @@  static void aarch64_max_initfn(Object *obj)
         t = cpu->isar.id_aa64mmfr1;
         t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
         t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
+        t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
         cpu->isar.id_aa64mmfr1 = t;
 
         /* Replicate the same data to the 32-bit id registers.  */