From c174f8c60cd372301200cdecaaae345b079cf589 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Wed, 24 May 2023 23:28:41 -0400 Subject: [PATCH] Add lbt support for kvm. Add lbt registers get and put function. Signed-off-by: lixianglai --- hw/loongarch/larch_3a.c | 3 ++- linux-headers/asm-loongarch64/kvm.h | 15 +++++++++++++ target/loongarch64/cpu.h | 10 +++++++++ target/loongarch64/kvm.c | 35 +++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c index cef1a6f3d2..95bb224664 100644 --- a/hw/loongarch/larch_3a.c +++ b/hw/loongarch/larch_3a.c @@ -356,7 +356,8 @@ struct kvm_cpucfg ls3a5k_cpucfgs = { .cpucfg[LOONGARCH_CPUCFG2] = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | CPUCFG2_FPVERS | CPUCFG2_LSX | CPUCFG2_LASX | CPUCFG2_COMPLEX | CPUCFG2_CRYPTO | - CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_LSPW | CPUCFG2_LAM, + CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_X86BT | CPUCFG2_ARMBT | + CPUCFG2_MIPSBT | CPUCFG2_LSPW | CPUCFG2_LAM, .cpucfg[LOONGARCH_CPUCFG3] = CPUCFG3_CCDMA | CPUCFG3_SFB | CPUCFG3_UCACC | CPUCFG3_LLEXC | CPUCFG3_SCDLY | CPUCFG3_LLDBAR | CPUCFG3_ITLBT | CPUCFG3_ICACHET | diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h index a473916d50..a036ea57cd 100644 --- a/linux-headers/asm-loongarch64/kvm.h +++ b/linux-headers/asm-loongarch64/kvm.h @@ -82,6 +82,7 @@ struct kvm_fpu { * Register set = 2: KVM specific registers (see definitions below). * * Register set = 3: FPU / MSA registers (see definitions below). + * Register set = 4: LBT registers (see definitions below). * * Other sets registers may be added in the future. Each set would * have its own identifier in bits[31..16]. @@ -91,6 +92,7 @@ struct kvm_fpu { #define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x0000000000010000ULL) #define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x0000000000020000ULL) #define KVM_REG_LOONGARCH_FPU (KVM_REG_LOONGARCH | 0x0000000000030000ULL) +#define KVM_REG_LOONGARCH_LBT (KVM_REG_LOONGARCH | 0x0000000000040000ULL) /* * KVM_REG_LOONGARCH_GP - General purpose registers from kvm_regs. @@ -174,6 +176,19 @@ struct kvm_fpu { #define KVM_REG_LOONGARCH_VCPU_RESET \ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 4) +#define KVM_REG_LBT_SCR0 \ + (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1) +#define KVM_REG_LBT_SCR1 \ + (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2) +#define KVM_REG_LBT_SCR2 \ + (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3) +#define KVM_REG_LBT_SCR3 \ + (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4) +#define KVM_REG_LBT_FLAGS \ + (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5) +#define KVM_REG_LBT_FTOP \ + (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6) + struct kvm_iocsr_entry { __u32 addr; __u32 pad; diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h index bf5b36d404..8a29a507b1 100644 --- a/target/loongarch64/cpu.h +++ b/target/loongarch64/cpu.h @@ -75,6 +75,7 @@ typedef struct CPULOONGARCHFPUContext { uint32_t fcsr0; uint32_t fcsr0_rw_bitmask; uint32_t vcsr16; + uint64_t ftop; } CPULOONGARCHFPUContext; /* fp control and status register definition */ @@ -196,6 +197,15 @@ struct CPULOONGARCHState { struct { uint64_t guest_addr; } st; + struct { + /* scratch registers */ + unsigned long scr0; + unsigned long scr1; + unsigned long scr2; + unsigned long scr3; + /* loongarch eflag */ + unsigned long eflag; + } lbt; }; /* diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c index 21f6d5695f..0a4dc86421 100644 --- a/target/loongarch64/kvm.c +++ b/target/loongarch64/kvm.c @@ -1277,6 +1277,39 @@ int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu) return 0; } + +static int kvm_loongarch_put_lbt_registers(CPUState *cs) +{ + int ret = 0; + LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); + CPULOONGARCHState *env = &cpu->env; + + ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR0, &env->lbt.scr0); + ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR1, &env->lbt.scr1); + ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR2, &env->lbt.scr2); + ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR3, &env->lbt.scr3); + ret |= kvm_larch_putq(cs, KVM_REG_LBT_FLAGS, &env->lbt.eflag); + ret |= kvm_larch_putq(cs, KVM_REG_LBT_FTOP, &env->active_fpu.ftop); + + return ret; +} + +static int kvm_loongarch_get_lbt_registers(CPUState *cs) +{ + int ret = 0; + LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); + CPULOONGARCHState *env = &cpu->env; + + ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR0, &env->lbt.scr0); + ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR1, &env->lbt.scr1); + ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR2, &env->lbt.scr2); + ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR3, &env->lbt.scr3); + ret |= kvm_larch_getq(cs, KVM_REG_LBT_FLAGS, &env->lbt.eflag); + ret |= kvm_larch_getq(cs, KVM_REG_LBT_FTOP, &env->active_fpu.ftop); + + return ret; +} + int kvm_arch_put_registers(CPUState *cs, int level) { LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); @@ -1308,6 +1341,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) return ret; } + kvm_loongarch_put_lbt_registers(cs); return ret; } @@ -1334,6 +1368,7 @@ int kvm_arch_get_registers(CPUState *cs) kvm_loongarch_get_csr_registers(cs); kvm_loongarch_get_fpu_registers(cs); + kvm_loongarch_get_lbt_registers(cs); return ret; } -- 2.41.0.windows.1