diff mbox series

[for-5.1,V3,5/7] target/mips: Add more CP0 register for save/restore

Message ID 1588501221-1205-6-git-send-email-chenhc@lemote.com
State New
Headers show
Series mips: Add Loongson-3 machine support (with KVM) | expand

Commit Message

chen huacai May 3, 2020, 10:20 a.m. UTC
Add more CP0 register for save/restore, including: EBase, XContext,
PageGrain, PWBase, PWSize, PWField, PWCtl, Config*, KScratch1~KScratch6.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
Co-developed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 target/mips/kvm.c     | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target/mips/machine.c |   6 +-
 2 files changed, 216 insertions(+), 2 deletions(-)

Comments

Aleksandar Markovic May 12, 2020, 1:01 p.m. UTC | #1
нед, 3. мај 2020. у 12:25 Huacai Chen <zltjiangshi@gmail.com> је написао/ла:
>
> Add more CP0 register for save/restore, including: EBase, XContext,
> PageGrain, PWBase, PWSize, PWField, PWCtl, Config*, KScratch1~KScratch6.
>
> Signed-off-by: Huacai Chen <chenhc@lemote.com>
> Co-developed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---

Reviewed-by: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>

>  target/mips/kvm.c     | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  target/mips/machine.c |   6 +-
>  2 files changed, 216 insertions(+), 2 deletions(-)
>
> diff --git a/target/mips/kvm.c b/target/mips/kvm.c
> index de3e26e..96cfa10 100644
> --- a/target/mips/kvm.c
> +++ b/target/mips/kvm.c
> @@ -245,10 +245,16 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level)
>      (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
>
>  #define KVM_REG_MIPS_CP0_INDEX          MIPS_CP0_32(0, 0)
> +#define KVM_REG_MIPS_CP0_RANDOM         MIPS_CP0_32(1, 0)
>  #define KVM_REG_MIPS_CP0_CONTEXT        MIPS_CP0_64(4, 0)
>  #define KVM_REG_MIPS_CP0_USERLOCAL      MIPS_CP0_64(4, 2)
>  #define KVM_REG_MIPS_CP0_PAGEMASK       MIPS_CP0_32(5, 0)
> +#define KVM_REG_MIPS_CP0_PAGEGRAIN      MIPS_CP0_32(5, 1)
> +#define KVM_REG_MIPS_CP0_PWBASE         MIPS_CP0_64(5, 5)
> +#define KVM_REG_MIPS_CP0_PWFIELD        MIPS_CP0_64(5, 6)
> +#define KVM_REG_MIPS_CP0_PWSIZE         MIPS_CP0_64(5, 7)
>  #define KVM_REG_MIPS_CP0_WIRED          MIPS_CP0_32(6, 0)
> +#define KVM_REG_MIPS_CP0_PWCTL          MIPS_CP0_32(6, 6)
>  #define KVM_REG_MIPS_CP0_HWRENA         MIPS_CP0_32(7, 0)
>  #define KVM_REG_MIPS_CP0_BADVADDR       MIPS_CP0_64(8, 0)
>  #define KVM_REG_MIPS_CP0_COUNT          MIPS_CP0_32(9, 0)
> @@ -258,13 +264,22 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level)
>  #define KVM_REG_MIPS_CP0_CAUSE          MIPS_CP0_32(13, 0)
>  #define KVM_REG_MIPS_CP0_EPC            MIPS_CP0_64(14, 0)
>  #define KVM_REG_MIPS_CP0_PRID           MIPS_CP0_32(15, 0)
> +#define KVM_REG_MIPS_CP0_EBASE          MIPS_CP0_64(15, 1)
>  #define KVM_REG_MIPS_CP0_CONFIG         MIPS_CP0_32(16, 0)
>  #define KVM_REG_MIPS_CP0_CONFIG1        MIPS_CP0_32(16, 1)
>  #define KVM_REG_MIPS_CP0_CONFIG2        MIPS_CP0_32(16, 2)
>  #define KVM_REG_MIPS_CP0_CONFIG3        MIPS_CP0_32(16, 3)
>  #define KVM_REG_MIPS_CP0_CONFIG4        MIPS_CP0_32(16, 4)
>  #define KVM_REG_MIPS_CP0_CONFIG5        MIPS_CP0_32(16, 5)
> +#define KVM_REG_MIPS_CP0_CONFIG6        MIPS_CP0_32(16, 6)
> +#define KVM_REG_MIPS_CP0_XCONTEXT       MIPS_CP0_64(20, 0)
>  #define KVM_REG_MIPS_CP0_ERROREPC       MIPS_CP0_64(30, 0)
> +#define KVM_REG_MIPS_CP0_KSCRATCH1      MIPS_CP0_64(31, 2)
> +#define KVM_REG_MIPS_CP0_KSCRATCH2      MIPS_CP0_64(31, 3)
> +#define KVM_REG_MIPS_CP0_KSCRATCH3      MIPS_CP0_64(31, 4)
> +#define KVM_REG_MIPS_CP0_KSCRATCH4      MIPS_CP0_64(31, 5)
> +#define KVM_REG_MIPS_CP0_KSCRATCH5      MIPS_CP0_64(31, 6)
> +#define KVM_REG_MIPS_CP0_KSCRATCH6      MIPS_CP0_64(31, 7)
>
>  static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
>                                         int32_t *addr)
> @@ -394,6 +409,29 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, uint64_t reg_id,
>                                           (1U << CP0C5_UFE) | \
>                                           (1U << CP0C5_FRE) | \
>                                           (1U << CP0C5_UFR))
> +#define KVM_REG_MIPS_CP0_CONFIG6_MASK   ((1U << CP0C6_BPPASS) | \
> +                                         (0x3fU << CP0C6_KPOS) | \
> +                                         (1U << CP0C6_KE) | \
> +                                         (1U << CP0C6_VTLBONLY) | \
> +                                         (1U << CP0C6_LASX) | \
> +                                         (1U << CP0C6_SSEN) | \
> +                                         (1U << CP0C6_DISDRTIME) | \
> +                                         (1U << CP0C6_PIXNUEN) | \
> +                                         (1U << CP0C6_SCRAND) | \
> +                                         (1U << CP0C6_LLEXCEN) | \
> +                                         (1U << CP0C6_DISVC) | \
> +                                         (1U << CP0C6_VCLRU) | \
> +                                         (1U << CP0C6_DCLRU) | \
> +                                         (1U << CP0C6_PIXUEN) | \
> +                                         (1U << CP0C6_DISBLKLYEN) | \
> +                                         (1U << CP0C6_UMEMUALEN) | \
> +                                         (1U << CP0C6_SFBEN) | \
> +                                         (1U << CP0C6_FLTINT) | \
> +                                         (1U << CP0C6_VLTINT) | \
> +                                         (1U << CP0C6_DISBTB) | \
> +                                         (3U << CP0C6_STPREFCTL) | \
> +                                         (1U << CP0C6_INSTPREF) | \
> +                                         (1U << CP0C6_DATAPREF))
>
>  static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
>                                            int32_t *addr, int32_t mask)
> @@ -729,6 +767,11 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
>          DPRINTF("%s: Failed to put CP0_INDEX (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_RANDOM, &env->CP0_Random);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_RANDOM (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
>                                   &env->CP0_Context);
>      if (err < 0) {
> @@ -747,11 +790,40 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
>          DPRINTF("%s: Failed to put CP0_PAGEMASK (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PAGEGRAIN,
> +                               &env->CP0_PageGrain);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PAGEGRAIN (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_PWBASE,
> +                               &env->CP0_PWBase);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PWBASE (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_PWFIELD,
> +                               &env->CP0_PWField);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PWField (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_PWSIZE,
> +                               &env->CP0_PWSize);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PWSIZE (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
>      if (err < 0) {
>          DPRINTF("%s: Failed to put CP0_WIRED (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PWCTL, &env->CP0_PWCtl);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PWCTL (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
>      if (err < 0) {
>          DPRINTF("%s: Failed to put CP0_HWRENA (%d)\n", __func__, err);
> @@ -799,6 +871,11 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
>          DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_EBASE, &env->CP0_EBase);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_EBASE (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG,
>                                    &env->CP0_Config0,
>                                    KVM_REG_MIPS_CP0_CONFIG_MASK);
> @@ -841,12 +918,61 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
>          DPRINTF("%s: Failed to change CP0_CONFIG5 (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG6,
> +                                  &env->CP0_Config6,
> +                                  KVM_REG_MIPS_CP0_CONFIG6_MASK);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to change CP0_CONFIG6 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_XCONTEXT,
> +                                 &env->CP0_XContext);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_XCONTEXT (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
>                                   &env->CP0_ErrorEPC);
>      if (err < 0) {
>          DPRINTF("%s: Failed to put CP0_ERROREPC (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH1,
> +                                 &env->CP0_KScratch[0]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH1 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH2,
> +                                 &env->CP0_KScratch[1]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH2 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH3,
> +                                 &env->CP0_KScratch[2]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH3 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH4,
> +                                 &env->CP0_KScratch[3]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH4 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH5,
> +                                 &env->CP0_KScratch[4]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH5 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH6,
> +                                 &env->CP0_KScratch[5]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH6 (%d)\n", __func__, err);
> +        ret = err;
> +    }
>
>      return ret;
>  }
> @@ -862,6 +988,11 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
>          DPRINTF("%s: Failed to get CP0_INDEX (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_RANDOM, &env->CP0_Random);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_RANDOM (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
>                                   &env->CP0_Context);
>      if (err < 0) {
> @@ -880,11 +1011,40 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
>          DPRINTF("%s: Failed to get CP0_PAGEMASK (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PAGEGRAIN,
> +                               &env->CP0_PageGrain);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PAGEGRAIN (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_PWBASE,
> +                               &env->CP0_PWBase);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PWBASE (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_PWFIELD,
> +                               &env->CP0_PWField);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PWFIELD (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_PWSIZE,
> +                               &env->CP0_PWSize);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PWSIZE (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
>      if (err < 0) {
>          DPRINTF("%s: Failed to get CP0_WIRED (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PWCTL, &env->CP0_PWCtl);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PWCtl (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
>      if (err < 0) {
>          DPRINTF("%s: Failed to get CP0_HWRENA (%d)\n", __func__, err);
> @@ -932,6 +1092,11 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
>          DPRINTF("%s: Failed to get CP0_PRID (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_EBASE, &env->CP0_EBase);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_EBASE (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG, &env->CP0_Config0);
>      if (err < 0) {
>          DPRINTF("%s: Failed to get CP0_CONFIG (%d)\n", __func__, err);
> @@ -962,12 +1127,59 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
>          DPRINTF("%s: Failed to get CP0_CONFIG5 (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG6, &env->CP0_Config6);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_CONFIG6 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_XCONTEXT,
> +                                 &env->CP0_XContext);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_XCONTEXT (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
>                                   &env->CP0_ErrorEPC);
>      if (err < 0) {
>          DPRINTF("%s: Failed to get CP0_ERROREPC (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH1,
> +                                 &env->CP0_KScratch[0]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH1 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH2,
> +                                 &env->CP0_KScratch[1]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH2 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH3,
> +                                 &env->CP0_KScratch[2]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH3 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH4,
> +                                 &env->CP0_KScratch[3]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH4 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH5,
> +                                 &env->CP0_KScratch[4]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH5 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH6,
> +                                 &env->CP0_KScratch[5]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH6 (%d)\n", __func__, err);
> +        ret = err;
> +    }
>
>      return ret;
>  }
> diff --git a/target/mips/machine.c b/target/mips/machine.c
> index 8d5b18b..5b23e3e 100644
> --- a/target/mips/machine.c
> +++ b/target/mips/machine.c
> @@ -212,8 +212,8 @@ const VMStateDescription vmstate_tlb = {
>
>  const VMStateDescription vmstate_mips_cpu = {
>      .name = "cpu",
> -    .version_id = 19,
> -    .minimum_version_id = 19,
> +    .version_id = 20,
> +    .minimum_version_id = 20,
>      .post_load = cpu_post_load,
>      .fields = (VMStateField[]) {
>          /* Active TC */
> @@ -289,6 +289,8 @@ const VMStateDescription vmstate_mips_cpu = {
>          VMSTATE_INT32(env.CP0_Config1, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config2, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config3, MIPSCPU),
> +        VMSTATE_INT32(env.CP0_Config4, MIPSCPU),
> +        VMSTATE_INT32(env.CP0_Config5, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config6, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config7, MIPSCPU),
>          VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU),
> --
> 2.7.0
>
Aleksandar Markovic June 1, 2020, 9:05 a.m. UTC | #2
On Sun, May 3, 2020 at 12:28 PM Huacai Chen <zltjiangshi@gmail.com> wrote:
>
> Add more CP0 register for save/restore, including: EBase, XContext,
> PageGrain, PWBase, PWSize, PWField, PWCtl, Config*, KScratch1~KScratch6.
>
> Signed-off-by: Huacai Chen <chenhc@lemote.com>
> Co-developed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---

Applied to MIPS queue.

Many thanks!
Aleksandar

>  target/mips/kvm.c     | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  target/mips/machine.c |   6 +-
>  2 files changed, 216 insertions(+), 2 deletions(-)
>
> diff --git a/target/mips/kvm.c b/target/mips/kvm.c
> index de3e26e..96cfa10 100644
> --- a/target/mips/kvm.c
> +++ b/target/mips/kvm.c
> @@ -245,10 +245,16 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level)
>      (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
>
>  #define KVM_REG_MIPS_CP0_INDEX          MIPS_CP0_32(0, 0)
> +#define KVM_REG_MIPS_CP0_RANDOM         MIPS_CP0_32(1, 0)
>  #define KVM_REG_MIPS_CP0_CONTEXT        MIPS_CP0_64(4, 0)
>  #define KVM_REG_MIPS_CP0_USERLOCAL      MIPS_CP0_64(4, 2)
>  #define KVM_REG_MIPS_CP0_PAGEMASK       MIPS_CP0_32(5, 0)
> +#define KVM_REG_MIPS_CP0_PAGEGRAIN      MIPS_CP0_32(5, 1)
> +#define KVM_REG_MIPS_CP0_PWBASE         MIPS_CP0_64(5, 5)
> +#define KVM_REG_MIPS_CP0_PWFIELD        MIPS_CP0_64(5, 6)
> +#define KVM_REG_MIPS_CP0_PWSIZE         MIPS_CP0_64(5, 7)
>  #define KVM_REG_MIPS_CP0_WIRED          MIPS_CP0_32(6, 0)
> +#define KVM_REG_MIPS_CP0_PWCTL          MIPS_CP0_32(6, 6)
>  #define KVM_REG_MIPS_CP0_HWRENA         MIPS_CP0_32(7, 0)
>  #define KVM_REG_MIPS_CP0_BADVADDR       MIPS_CP0_64(8, 0)
>  #define KVM_REG_MIPS_CP0_COUNT          MIPS_CP0_32(9, 0)
> @@ -258,13 +264,22 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level)
>  #define KVM_REG_MIPS_CP0_CAUSE          MIPS_CP0_32(13, 0)
>  #define KVM_REG_MIPS_CP0_EPC            MIPS_CP0_64(14, 0)
>  #define KVM_REG_MIPS_CP0_PRID           MIPS_CP0_32(15, 0)
> +#define KVM_REG_MIPS_CP0_EBASE          MIPS_CP0_64(15, 1)
>  #define KVM_REG_MIPS_CP0_CONFIG         MIPS_CP0_32(16, 0)
>  #define KVM_REG_MIPS_CP0_CONFIG1        MIPS_CP0_32(16, 1)
>  #define KVM_REG_MIPS_CP0_CONFIG2        MIPS_CP0_32(16, 2)
>  #define KVM_REG_MIPS_CP0_CONFIG3        MIPS_CP0_32(16, 3)
>  #define KVM_REG_MIPS_CP0_CONFIG4        MIPS_CP0_32(16, 4)
>  #define KVM_REG_MIPS_CP0_CONFIG5        MIPS_CP0_32(16, 5)
> +#define KVM_REG_MIPS_CP0_CONFIG6        MIPS_CP0_32(16, 6)
> +#define KVM_REG_MIPS_CP0_XCONTEXT       MIPS_CP0_64(20, 0)
>  #define KVM_REG_MIPS_CP0_ERROREPC       MIPS_CP0_64(30, 0)
> +#define KVM_REG_MIPS_CP0_KSCRATCH1      MIPS_CP0_64(31, 2)
> +#define KVM_REG_MIPS_CP0_KSCRATCH2      MIPS_CP0_64(31, 3)
> +#define KVM_REG_MIPS_CP0_KSCRATCH3      MIPS_CP0_64(31, 4)
> +#define KVM_REG_MIPS_CP0_KSCRATCH4      MIPS_CP0_64(31, 5)
> +#define KVM_REG_MIPS_CP0_KSCRATCH5      MIPS_CP0_64(31, 6)
> +#define KVM_REG_MIPS_CP0_KSCRATCH6      MIPS_CP0_64(31, 7)
>
>  static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
>                                         int32_t *addr)
> @@ -394,6 +409,29 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, uint64_t reg_id,
>                                           (1U << CP0C5_UFE) | \
>                                           (1U << CP0C5_FRE) | \
>                                           (1U << CP0C5_UFR))
> +#define KVM_REG_MIPS_CP0_CONFIG6_MASK   ((1U << CP0C6_BPPASS) | \
> +                                         (0x3fU << CP0C6_KPOS) | \
> +                                         (1U << CP0C6_KE) | \
> +                                         (1U << CP0C6_VTLBONLY) | \
> +                                         (1U << CP0C6_LASX) | \
> +                                         (1U << CP0C6_SSEN) | \
> +                                         (1U << CP0C6_DISDRTIME) | \
> +                                         (1U << CP0C6_PIXNUEN) | \
> +                                         (1U << CP0C6_SCRAND) | \
> +                                         (1U << CP0C6_LLEXCEN) | \
> +                                         (1U << CP0C6_DISVC) | \
> +                                         (1U << CP0C6_VCLRU) | \
> +                                         (1U << CP0C6_DCLRU) | \
> +                                         (1U << CP0C6_PIXUEN) | \
> +                                         (1U << CP0C6_DISBLKLYEN) | \
> +                                         (1U << CP0C6_UMEMUALEN) | \
> +                                         (1U << CP0C6_SFBEN) | \
> +                                         (1U << CP0C6_FLTINT) | \
> +                                         (1U << CP0C6_VLTINT) | \
> +                                         (1U << CP0C6_DISBTB) | \
> +                                         (3U << CP0C6_STPREFCTL) | \
> +                                         (1U << CP0C6_INSTPREF) | \
> +                                         (1U << CP0C6_DATAPREF))
>
>  static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
>                                            int32_t *addr, int32_t mask)
> @@ -729,6 +767,11 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
>          DPRINTF("%s: Failed to put CP0_INDEX (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_RANDOM, &env->CP0_Random);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_RANDOM (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
>                                   &env->CP0_Context);
>      if (err < 0) {
> @@ -747,11 +790,40 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
>          DPRINTF("%s: Failed to put CP0_PAGEMASK (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PAGEGRAIN,
> +                               &env->CP0_PageGrain);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PAGEGRAIN (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_PWBASE,
> +                               &env->CP0_PWBase);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PWBASE (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_PWFIELD,
> +                               &env->CP0_PWField);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PWField (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_PWSIZE,
> +                               &env->CP0_PWSize);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PWSIZE (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
>      if (err < 0) {
>          DPRINTF("%s: Failed to put CP0_WIRED (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PWCTL, &env->CP0_PWCtl);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_PWCTL (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
>      if (err < 0) {
>          DPRINTF("%s: Failed to put CP0_HWRENA (%d)\n", __func__, err);
> @@ -799,6 +871,11 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
>          DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_EBASE, &env->CP0_EBase);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_EBASE (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG,
>                                    &env->CP0_Config0,
>                                    KVM_REG_MIPS_CP0_CONFIG_MASK);
> @@ -841,12 +918,61 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
>          DPRINTF("%s: Failed to change CP0_CONFIG5 (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG6,
> +                                  &env->CP0_Config6,
> +                                  KVM_REG_MIPS_CP0_CONFIG6_MASK);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to change CP0_CONFIG6 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_XCONTEXT,
> +                                 &env->CP0_XContext);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_XCONTEXT (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
>                                   &env->CP0_ErrorEPC);
>      if (err < 0) {
>          DPRINTF("%s: Failed to put CP0_ERROREPC (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH1,
> +                                 &env->CP0_KScratch[0]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH1 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH2,
> +                                 &env->CP0_KScratch[1]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH2 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH3,
> +                                 &env->CP0_KScratch[2]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH3 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH4,
> +                                 &env->CP0_KScratch[3]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH4 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH5,
> +                                 &env->CP0_KScratch[4]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH5 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH6,
> +                                 &env->CP0_KScratch[5]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to put CP0_KSCRATCH6 (%d)\n", __func__, err);
> +        ret = err;
> +    }
>
>      return ret;
>  }
> @@ -862,6 +988,11 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
>          DPRINTF("%s: Failed to get CP0_INDEX (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_RANDOM, &env->CP0_Random);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_RANDOM (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
>                                   &env->CP0_Context);
>      if (err < 0) {
> @@ -880,11 +1011,40 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
>          DPRINTF("%s: Failed to get CP0_PAGEMASK (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PAGEGRAIN,
> +                               &env->CP0_PageGrain);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PAGEGRAIN (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_PWBASE,
> +                               &env->CP0_PWBase);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PWBASE (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_PWFIELD,
> +                               &env->CP0_PWField);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PWFIELD (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_PWSIZE,
> +                               &env->CP0_PWSize);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PWSIZE (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
>      if (err < 0) {
>          DPRINTF("%s: Failed to get CP0_WIRED (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PWCTL, &env->CP0_PWCtl);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_PWCtl (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
>      if (err < 0) {
>          DPRINTF("%s: Failed to get CP0_HWRENA (%d)\n", __func__, err);
> @@ -932,6 +1092,11 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
>          DPRINTF("%s: Failed to get CP0_PRID (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_EBASE, &env->CP0_EBase);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_EBASE (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG, &env->CP0_Config0);
>      if (err < 0) {
>          DPRINTF("%s: Failed to get CP0_CONFIG (%d)\n", __func__, err);
> @@ -962,12 +1127,59 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
>          DPRINTF("%s: Failed to get CP0_CONFIG5 (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG6, &env->CP0_Config6);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_CONFIG6 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_XCONTEXT,
> +                                 &env->CP0_XContext);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_XCONTEXT (%d)\n", __func__, err);
> +        ret = err;
> +    }
>      err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
>                                   &env->CP0_ErrorEPC);
>      if (err < 0) {
>          DPRINTF("%s: Failed to get CP0_ERROREPC (%d)\n", __func__, err);
>          ret = err;
>      }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH1,
> +                                 &env->CP0_KScratch[0]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH1 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH2,
> +                                 &env->CP0_KScratch[1]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH2 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH3,
> +                                 &env->CP0_KScratch[2]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH3 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH4,
> +                                 &env->CP0_KScratch[3]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH4 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH5,
> +                                 &env->CP0_KScratch[4]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH5 (%d)\n", __func__, err);
> +        ret = err;
> +    }
> +    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH6,
> +                                 &env->CP0_KScratch[5]);
> +    if (err < 0) {
> +        DPRINTF("%s: Failed to get CP0_KSCRATCH6 (%d)\n", __func__, err);
> +        ret = err;
> +    }
>
>      return ret;
>  }
> diff --git a/target/mips/machine.c b/target/mips/machine.c
> index 8d5b18b..5b23e3e 100644
> --- a/target/mips/machine.c
> +++ b/target/mips/machine.c
> @@ -212,8 +212,8 @@ const VMStateDescription vmstate_tlb = {
>
>  const VMStateDescription vmstate_mips_cpu = {
>      .name = "cpu",
> -    .version_id = 19,
> -    .minimum_version_id = 19,
> +    .version_id = 20,
> +    .minimum_version_id = 20,
>      .post_load = cpu_post_load,
>      .fields = (VMStateField[]) {
>          /* Active TC */
> @@ -289,6 +289,8 @@ const VMStateDescription vmstate_mips_cpu = {
>          VMSTATE_INT32(env.CP0_Config1, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config2, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config3, MIPSCPU),
> +        VMSTATE_INT32(env.CP0_Config4, MIPSCPU),
> +        VMSTATE_INT32(env.CP0_Config5, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config6, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config7, MIPSCPU),
>          VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU),
> --
> 2.7.0
>
>
diff mbox series

Patch

diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index de3e26e..96cfa10 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -245,10 +245,16 @@  int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level)
     (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
 
 #define KVM_REG_MIPS_CP0_INDEX          MIPS_CP0_32(0, 0)
+#define KVM_REG_MIPS_CP0_RANDOM         MIPS_CP0_32(1, 0)
 #define KVM_REG_MIPS_CP0_CONTEXT        MIPS_CP0_64(4, 0)
 #define KVM_REG_MIPS_CP0_USERLOCAL      MIPS_CP0_64(4, 2)
 #define KVM_REG_MIPS_CP0_PAGEMASK       MIPS_CP0_32(5, 0)
+#define KVM_REG_MIPS_CP0_PAGEGRAIN      MIPS_CP0_32(5, 1)
+#define KVM_REG_MIPS_CP0_PWBASE         MIPS_CP0_64(5, 5)
+#define KVM_REG_MIPS_CP0_PWFIELD        MIPS_CP0_64(5, 6)
+#define KVM_REG_MIPS_CP0_PWSIZE         MIPS_CP0_64(5, 7)
 #define KVM_REG_MIPS_CP0_WIRED          MIPS_CP0_32(6, 0)
+#define KVM_REG_MIPS_CP0_PWCTL          MIPS_CP0_32(6, 6)
 #define KVM_REG_MIPS_CP0_HWRENA         MIPS_CP0_32(7, 0)
 #define KVM_REG_MIPS_CP0_BADVADDR       MIPS_CP0_64(8, 0)
 #define KVM_REG_MIPS_CP0_COUNT          MIPS_CP0_32(9, 0)
@@ -258,13 +264,22 @@  int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level)
 #define KVM_REG_MIPS_CP0_CAUSE          MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPC            MIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_PRID           MIPS_CP0_32(15, 0)
+#define KVM_REG_MIPS_CP0_EBASE          MIPS_CP0_64(15, 1)
 #define KVM_REG_MIPS_CP0_CONFIG         MIPS_CP0_32(16, 0)
 #define KVM_REG_MIPS_CP0_CONFIG1        MIPS_CP0_32(16, 1)
 #define KVM_REG_MIPS_CP0_CONFIG2        MIPS_CP0_32(16, 2)
 #define KVM_REG_MIPS_CP0_CONFIG3        MIPS_CP0_32(16, 3)
 #define KVM_REG_MIPS_CP0_CONFIG4        MIPS_CP0_32(16, 4)
 #define KVM_REG_MIPS_CP0_CONFIG5        MIPS_CP0_32(16, 5)
+#define KVM_REG_MIPS_CP0_CONFIG6        MIPS_CP0_32(16, 6)
+#define KVM_REG_MIPS_CP0_XCONTEXT       MIPS_CP0_64(20, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC       MIPS_CP0_64(30, 0)
+#define KVM_REG_MIPS_CP0_KSCRATCH1      MIPS_CP0_64(31, 2)
+#define KVM_REG_MIPS_CP0_KSCRATCH2      MIPS_CP0_64(31, 3)
+#define KVM_REG_MIPS_CP0_KSCRATCH3      MIPS_CP0_64(31, 4)
+#define KVM_REG_MIPS_CP0_KSCRATCH4      MIPS_CP0_64(31, 5)
+#define KVM_REG_MIPS_CP0_KSCRATCH5      MIPS_CP0_64(31, 6)
+#define KVM_REG_MIPS_CP0_KSCRATCH6      MIPS_CP0_64(31, 7)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
                                        int32_t *addr)
@@ -394,6 +409,29 @@  static inline int kvm_mips_get_one_ureg64(CPUState *cs, uint64_t reg_id,
                                          (1U << CP0C5_UFE) | \
                                          (1U << CP0C5_FRE) | \
                                          (1U << CP0C5_UFR))
+#define KVM_REG_MIPS_CP0_CONFIG6_MASK   ((1U << CP0C6_BPPASS) | \
+                                         (0x3fU << CP0C6_KPOS) | \
+                                         (1U << CP0C6_KE) | \
+                                         (1U << CP0C6_VTLBONLY) | \
+                                         (1U << CP0C6_LASX) | \
+                                         (1U << CP0C6_SSEN) | \
+                                         (1U << CP0C6_DISDRTIME) | \
+                                         (1U << CP0C6_PIXNUEN) | \
+                                         (1U << CP0C6_SCRAND) | \
+                                         (1U << CP0C6_LLEXCEN) | \
+                                         (1U << CP0C6_DISVC) | \
+                                         (1U << CP0C6_VCLRU) | \
+                                         (1U << CP0C6_DCLRU) | \
+                                         (1U << CP0C6_PIXUEN) | \
+                                         (1U << CP0C6_DISBLKLYEN) | \
+                                         (1U << CP0C6_UMEMUALEN) | \
+                                         (1U << CP0C6_SFBEN) | \
+                                         (1U << CP0C6_FLTINT) | \
+                                         (1U << CP0C6_VLTINT) | \
+                                         (1U << CP0C6_DISBTB) | \
+                                         (3U << CP0C6_STPREFCTL) | \
+                                         (1U << CP0C6_INSTPREF) | \
+                                         (1U << CP0C6_DATAPREF))
 
 static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
                                           int32_t *addr, int32_t mask)
@@ -729,6 +767,11 @@  static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
         DPRINTF("%s: Failed to put CP0_INDEX (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_RANDOM, &env->CP0_Random);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_RANDOM (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
                                  &env->CP0_Context);
     if (err < 0) {
@@ -747,11 +790,40 @@  static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
         DPRINTF("%s: Failed to put CP0_PAGEMASK (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PAGEGRAIN,
+                               &env->CP0_PageGrain);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_PAGEGRAIN (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_PWBASE,
+                               &env->CP0_PWBase);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_PWBASE (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_PWFIELD,
+                               &env->CP0_PWField);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_PWField (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_PWSIZE,
+                               &env->CP0_PWSize);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_PWSIZE (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
     if (err < 0) {
         DPRINTF("%s: Failed to put CP0_WIRED (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PWCTL, &env->CP0_PWCtl);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_PWCTL (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
     if (err < 0) {
         DPRINTF("%s: Failed to put CP0_HWRENA (%d)\n", __func__, err);
@@ -799,6 +871,11 @@  static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
         DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_EBASE, &env->CP0_EBase);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_EBASE (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG,
                                   &env->CP0_Config0,
                                   KVM_REG_MIPS_CP0_CONFIG_MASK);
@@ -841,12 +918,61 @@  static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
         DPRINTF("%s: Failed to change CP0_CONFIG5 (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG6,
+                                  &env->CP0_Config6,
+                                  KVM_REG_MIPS_CP0_CONFIG6_MASK);
+    if (err < 0) {
+        DPRINTF("%s: Failed to change CP0_CONFIG6 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_XCONTEXT,
+                                 &env->CP0_XContext);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_XCONTEXT (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
                                  &env->CP0_ErrorEPC);
     if (err < 0) {
         DPRINTF("%s: Failed to put CP0_ERROREPC (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH1,
+                                 &env->CP0_KScratch[0]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_KSCRATCH1 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH2,
+                                 &env->CP0_KScratch[1]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_KSCRATCH2 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH3,
+                                 &env->CP0_KScratch[2]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_KSCRATCH3 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH4,
+                                 &env->CP0_KScratch[3]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_KSCRATCH4 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH5,
+                                 &env->CP0_KScratch[4]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_KSCRATCH5 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH6,
+                                 &env->CP0_KScratch[5]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to put CP0_KSCRATCH6 (%d)\n", __func__, err);
+        ret = err;
+    }
 
     return ret;
 }
@@ -862,6 +988,11 @@  static int kvm_mips_get_cp0_registers(CPUState *cs)
         DPRINTF("%s: Failed to get CP0_INDEX (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_RANDOM, &env->CP0_Random);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_RANDOM (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
                                  &env->CP0_Context);
     if (err < 0) {
@@ -880,11 +1011,40 @@  static int kvm_mips_get_cp0_registers(CPUState *cs)
         DPRINTF("%s: Failed to get CP0_PAGEMASK (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PAGEGRAIN,
+                               &env->CP0_PageGrain);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_PAGEGRAIN (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_PWBASE,
+                               &env->CP0_PWBase);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_PWBASE (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_PWFIELD,
+                               &env->CP0_PWField);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_PWFIELD (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_PWSIZE,
+                               &env->CP0_PWSize);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_PWSIZE (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
     if (err < 0) {
         DPRINTF("%s: Failed to get CP0_WIRED (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PWCTL, &env->CP0_PWCtl);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_PWCtl (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
     if (err < 0) {
         DPRINTF("%s: Failed to get CP0_HWRENA (%d)\n", __func__, err);
@@ -932,6 +1092,11 @@  static int kvm_mips_get_cp0_registers(CPUState *cs)
         DPRINTF("%s: Failed to get CP0_PRID (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_EBASE, &env->CP0_EBase);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_EBASE (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG, &env->CP0_Config0);
     if (err < 0) {
         DPRINTF("%s: Failed to get CP0_CONFIG (%d)\n", __func__, err);
@@ -962,12 +1127,59 @@  static int kvm_mips_get_cp0_registers(CPUState *cs)
         DPRINTF("%s: Failed to get CP0_CONFIG5 (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG6, &env->CP0_Config6);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_CONFIG6 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_XCONTEXT,
+                                 &env->CP0_XContext);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_XCONTEXT (%d)\n", __func__, err);
+        ret = err;
+    }
     err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
                                  &env->CP0_ErrorEPC);
     if (err < 0) {
         DPRINTF("%s: Failed to get CP0_ERROREPC (%d)\n", __func__, err);
         ret = err;
     }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH1,
+                                 &env->CP0_KScratch[0]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_KSCRATCH1 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH2,
+                                 &env->CP0_KScratch[1]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_KSCRATCH2 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH3,
+                                 &env->CP0_KScratch[2]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_KSCRATCH3 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH4,
+                                 &env->CP0_KScratch[3]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_KSCRATCH4 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH5,
+                                 &env->CP0_KScratch[4]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_KSCRATCH5 (%d)\n", __func__, err);
+        ret = err;
+    }
+    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_KSCRATCH6,
+                                 &env->CP0_KScratch[5]);
+    if (err < 0) {
+        DPRINTF("%s: Failed to get CP0_KSCRATCH6 (%d)\n", __func__, err);
+        ret = err;
+    }
 
     return ret;
 }
diff --git a/target/mips/machine.c b/target/mips/machine.c
index 8d5b18b..5b23e3e 100644
--- a/target/mips/machine.c
+++ b/target/mips/machine.c
@@ -212,8 +212,8 @@  const VMStateDescription vmstate_tlb = {
 
 const VMStateDescription vmstate_mips_cpu = {
     .name = "cpu",
-    .version_id = 19,
-    .minimum_version_id = 19,
+    .version_id = 20,
+    .minimum_version_id = 20,
     .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
         /* Active TC */
@@ -289,6 +289,8 @@  const VMStateDescription vmstate_mips_cpu = {
         VMSTATE_INT32(env.CP0_Config1, MIPSCPU),
         VMSTATE_INT32(env.CP0_Config2, MIPSCPU),
         VMSTATE_INT32(env.CP0_Config3, MIPSCPU),
+        VMSTATE_INT32(env.CP0_Config4, MIPSCPU),
+        VMSTATE_INT32(env.CP0_Config5, MIPSCPU),
         VMSTATE_INT32(env.CP0_Config6, MIPSCPU),
         VMSTATE_INT32(env.CP0_Config7, MIPSCPU),
         VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU),