[PATCH v2 3/7] target/ppc: Fix move-to timebase SPR access permissions

Nicholas Piggin posted 7 patches 1 year ago
Maintainers: Nicholas Piggin <npiggin@gmail.com>, Daniel Henrique Barboza <danielhb413@gmail.com>, "Cédric Le Goater" <clg@kaod.org>, "Frédéric Barrat" <fbarrat@linux.ibm.com>
There is a newer version of this series
[PATCH v2 3/7] target/ppc: Fix move-to timebase SPR access permissions
Posted by Nicholas Piggin 1 year ago
The move-to timebase registers TBU and TBL can not be read, and they
can not be written in supervisor mode on hypervisor-capable CPUs.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 target/ppc/helper_regs.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 6f190ab13b..f1493ddca0 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -468,18 +468,33 @@ void register_generic_sprs(PowerPCCPU *cpu)
                  &spr_read_tbl, SPR_NOACCESS,
                  &spr_read_tbl, SPR_NOACCESS,
                  0x00000000);
-    spr_register(env, SPR_WR_TBL, "TBL",
-                 &spr_read_tbl, SPR_NOACCESS,
-                 &spr_read_tbl, &spr_write_tbl,
-                 0x00000000);
     spr_register(env, SPR_TBU, "TBU",
                  &spr_read_tbu, SPR_NOACCESS,
                  &spr_read_tbu, SPR_NOACCESS,
                  0x00000000);
-    spr_register(env, SPR_WR_TBU, "TBU",
-                 &spr_read_tbu, SPR_NOACCESS,
-                 &spr_read_tbu, &spr_write_tbu,
-                 0x00000000);
+#ifndef CONFIG_USER_ONLY
+    if (env->has_hv_mode) {
+        spr_register_hv(env, SPR_WR_TBL, "TBL",
+                        SPR_NOACCESS, SPR_NOACCESS,
+                        SPR_NOACCESS, SPR_NOACCESS,
+                        SPR_NOACCESS, &spr_write_tbl,
+                        0x00000000);
+        spr_register_hv(env, SPR_WR_TBU, "TBU",
+                        SPR_NOACCESS, SPR_NOACCESS,
+                        SPR_NOACCESS, SPR_NOACCESS,
+                        SPR_NOACCESS, &spr_write_tbu,
+                        0x00000000);
+    } else {
+        spr_register(env, SPR_WR_TBL, "TBL",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     SPR_NOACCESS, &spr_write_tbl,
+                     0x00000000);
+        spr_register(env, SPR_WR_TBU, "TBU",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     SPR_NOACCESS, &spr_write_tbu,
+                     0x00000000);
+    }
+#endif
 }
 
 void register_non_embedded_sprs(CPUPPCState *env)
-- 
2.42.0
Re: [PATCH v2 3/7] target/ppc: Fix move-to timebase SPR access permissions
Posted by Cédric Le Goater 1 year ago
On 11/24/23 07:39, Nicholas Piggin wrote:
> The move-to timebase registers TBU and TBL can not be read, and they
> can not be written in supervisor mode on hypervisor-capable CPUs.
> 
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>


Reviewed-by: Cédric Le Goater <clg@kaod.org>

Thanks,

C.


> ---
>   target/ppc/helper_regs.c | 31 +++++++++++++++++++++++--------
>   1 file changed, 23 insertions(+), 8 deletions(-)
> 
> diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
> index 6f190ab13b..f1493ddca0 100644
> --- a/target/ppc/helper_regs.c
> +++ b/target/ppc/helper_regs.c
> @@ -468,18 +468,33 @@ void register_generic_sprs(PowerPCCPU *cpu)
>                    &spr_read_tbl, SPR_NOACCESS,
>                    &spr_read_tbl, SPR_NOACCESS,
>                    0x00000000);
> -    spr_register(env, SPR_WR_TBL, "TBL",
> -                 &spr_read_tbl, SPR_NOACCESS,
> -                 &spr_read_tbl, &spr_write_tbl,
> -                 0x00000000);
>       spr_register(env, SPR_TBU, "TBU",
>                    &spr_read_tbu, SPR_NOACCESS,
>                    &spr_read_tbu, SPR_NOACCESS,
>                    0x00000000);
> -    spr_register(env, SPR_WR_TBU, "TBU",
> -                 &spr_read_tbu, SPR_NOACCESS,
> -                 &spr_read_tbu, &spr_write_tbu,
> -                 0x00000000);
> +#ifndef CONFIG_USER_ONLY
> +    if (env->has_hv_mode) {
> +        spr_register_hv(env, SPR_WR_TBL, "TBL",
> +                        SPR_NOACCESS, SPR_NOACCESS,
> +                        SPR_NOACCESS, SPR_NOACCESS,
> +                        SPR_NOACCESS, &spr_write_tbl,
> +                        0x00000000);
> +        spr_register_hv(env, SPR_WR_TBU, "TBU",
> +                        SPR_NOACCESS, SPR_NOACCESS,
> +                        SPR_NOACCESS, SPR_NOACCESS,
> +                        SPR_NOACCESS, &spr_write_tbu,
> +                        0x00000000);
> +    } else {
> +        spr_register(env, SPR_WR_TBL, "TBL",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     SPR_NOACCESS, &spr_write_tbl,
> +                     0x00000000);
> +        spr_register(env, SPR_WR_TBU, "TBU",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     SPR_NOACCESS, &spr_write_tbu,
> +                     0x00000000);
> +    }
> +#endif
>   }
>   
>   void register_non_embedded_sprs(CPUPPCState *env)