161 lines
5.9 KiB
Diff
161 lines
5.9 KiB
Diff
|
|
From c174f8c60cd372301200cdecaaae345b079cf589 Mon Sep 17 00:00:00 2001
|
||
|
|
From: lixianglai <lixianglai@loongson.cn>
|
||
|
|
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 <lixianglai@loongson.cn>
|
||
|
|
---
|
||
|
|
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
|
||
|
|
|