0107-target-riscv-Force-to-set-mstatus_hs.-SD-VS-bits-in-.patch 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. From a64af206b15f9b7ffc16e0b9b7bba3cb26d20194 Mon Sep 17 00:00:00 2001
  2. From: Frank Chang <frank.chang@sifive.com>
  3. Date: Mon, 13 Sep 2021 20:39:21 +0800
  4. Subject: [PATCH 107/107] target/riscv: Force to set mstatus_hs.[SD|VS] bits in
  5. mark_vs_dirty()
  6. When V=1, both vsstauts.VS and HS-level sstatus.VS are in effect.
  7. Modifying the floating-point state when V=1 causes both fields to
  8. be set to 3 (Dirty).
  9. However, it's possible that HS-level sstatus.VS is Clean and VS-level
  10. vsstatus.VS is Dirty at the time mark_vs_dirty() is called when V=1.
  11. We can't early return for this case because we still need to set
  12. sstatus.VS to Dirty according to spec.
  13. Signed-off-by: Frank Chang <frank.chang@sifive.com>
  14. Reviewed-by: Vincent Chen <vincent.chen@sifive.com>
  15. Tested-by: Vincent Chen <vincent.chen@sifive.com>
  16. ---
  17. target/riscv/translate.c | 15 ++++++++++-----
  18. 1 file changed, 10 insertions(+), 5 deletions(-)
  19. diff --git a/target/riscv/translate.c b/target/riscv/translate.c
  20. index f6c534ce47..744b4ffaa7 100644
  21. --- a/target/riscv/translate.c
  22. +++ b/target/riscv/translate.c
  23. @@ -435,9 +435,19 @@ static inline void mark_fs_dirty(DisasContext *ctx) { }
  24. static void mark_vs_dirty(DisasContext *ctx)
  25. {
  26. TCGv tmp;
  27. +
  28. + if (ctx->virt_enabled) {
  29. + tmp = tcg_temp_new();
  30. + tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
  31. + tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS | MSTATUS_SD);
  32. + tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
  33. + tcg_temp_free(tmp);
  34. + }
  35. +
  36. if (ctx->mstatus_vs == MSTATUS_VS) {
  37. return;
  38. }
  39. +
  40. /* Remember the state change for the rest of the TB. */
  41. ctx->mstatus_vs = MSTATUS_VS;
  42. @@ -446,11 +456,6 @@ static void mark_vs_dirty(DisasContext *ctx)
  43. tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS | MSTATUS_SD);
  44. tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
  45. - if (ctx->virt_enabled) {
  46. - tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
  47. - tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS | MSTATUS_SD);
  48. - tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
  49. - }
  50. tcg_temp_free(tmp);
  51. }
  52. #else
  53. --
  54. 2.33.1