1
0
mirror of https://gitlab.com/qemu-project/qemu synced 2024-07-08 20:17:27 +00:00

target/loongarch: Implement kvm get/set registers

Implement kvm_arch_get/set_registers interfaces, many regs
can be get/set in the function, such as core regs, csr regs,
fpu regs, mp state, etc.

Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
Signed-off-by: xianglai li <lixianglai@loongson.cn>
Reviewed-by: Song Gao <gaosong@loongson.cn>
Change-Id: Ia8fc48fe08b1768853f7729e77d37cdf270031e4
Message-Id: <20240105075804.1228596-5-zhaotianrui@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
This commit is contained in:
Tianrui Zhao 2024-01-05 15:57:59 +08:00 committed by Song Gao
parent 6278465696
commit f8447436d3
7 changed files with 599 additions and 3 deletions

View File

@ -3329,6 +3329,7 @@ if have_system or have_user
'target/hppa',
'target/i386',
'target/i386/kvm',
'target/loongarch',
'target/mips/tcg',
'target/nios2',
'target/ppc',

View File

@ -540,6 +540,9 @@ static void loongarch_cpu_reset_hold(Object *obj)
#ifndef CONFIG_USER_ONLY
env->pc = 0x1c000000;
memset(env->tlb, 0, sizeof(env->tlb));
if (kvm_enabled()) {
kvm_arch_reset_vcpu(env);
}
#endif
restore_fp_status(env);

View File

@ -360,6 +360,7 @@ typedef struct CPUArchState {
MemoryRegion iocsr_mem;
bool load_elf;
uint64_t elf_address;
uint32_t mp_state;
/* Store ipistate to access from this struct */
DeviceState *ipistate;
#endif

View File

@ -31,8 +31,10 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env,
const char *loongarch_exception_name(int32_t exception);
#ifdef CONFIG_TCG
int ieee_ex_to_loongarch(int xcpt);
void restore_fp_status(CPULoongArchState *env);
#endif
#ifndef CONFIG_USER_ONLY
extern const VMStateDescription vmstate_loongarch_cpu;
@ -44,12 +46,13 @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu);
uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu);
void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
uint64_t value);
#ifdef CONFIG_TCG
bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif
#endif /* !CONFIG_USER_ONLY */
uint64_t read_fcc(CPULoongArchState *env);

View File

@ -26,19 +26,595 @@
#include "sysemu/runstate.h"
#include "cpu-csr.h"
#include "kvm_loongarch.h"
#include "trace.h"
static bool cap_has_mp_state;
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
static int kvm_loongarch_get_regs_core(CPUState *cs)
{
int ret = 0;
int i;
struct kvm_regs regs;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
/* Get the current register set as KVM seems it */
ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
if (ret < 0) {
trace_kvm_failed_get_regs_core(strerror(errno));
return ret;
}
/* gpr[0] value is always 0 */
env->gpr[0] = 0;
for (i = 1; i < 32; i++) {
env->gpr[i] = regs.gpr[i];
}
env->pc = regs.pc;
return ret;
}
static int kvm_loongarch_put_regs_core(CPUState *cs)
{
int ret = 0;
int i;
struct kvm_regs regs;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
/* Set the registers based on QEMU's view of things */
for (i = 0; i < 32; i++) {
regs.gpr[i] = env->gpr[i];
}
regs.pc = env->pc;
ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
if (ret < 0) {
trace_kvm_failed_put_regs_core(strerror(errno));
}
return ret;
}
static int kvm_loongarch_get_csr(CPUState *cs)
{
int ret = 0;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
&env->CSR_CRMD);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
&env->CSR_PRMD);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
&env->CSR_EUEN);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
&env->CSR_MISC);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
&env->CSR_ECFG);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
&env->CSR_ESTAT);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
&env->CSR_ERA);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
&env->CSR_BADV);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
&env->CSR_BADI);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
&env->CSR_EENTRY);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
&env->CSR_TLBIDX);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
&env->CSR_TLBEHI);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
&env->CSR_TLBELO0);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
&env->CSR_TLBELO1);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
&env->CSR_ASID);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
&env->CSR_PGDL);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
&env->CSR_PGDH);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
&env->CSR_PGD);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
&env->CSR_PWCL);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
&env->CSR_PWCH);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
&env->CSR_STLBPS);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
&env->CSR_RVACFG);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
&env->CSR_CPUID);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
&env->CSR_PRCFG1);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
&env->CSR_PRCFG2);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
&env->CSR_PRCFG3);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
&env->CSR_SAVE[0]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
&env->CSR_SAVE[1]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
&env->CSR_SAVE[2]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
&env->CSR_SAVE[3]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
&env->CSR_SAVE[4]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
&env->CSR_SAVE[5]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
&env->CSR_SAVE[6]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
&env->CSR_SAVE[7]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
&env->CSR_TID);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
&env->CSR_CNTC);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
&env->CSR_TICLR);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
&env->CSR_LLBCTL);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
&env->CSR_IMPCTL1);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
&env->CSR_IMPCTL2);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
&env->CSR_TLBRENTRY);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
&env->CSR_TLBRBADV);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
&env->CSR_TLBRERA);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
&env->CSR_TLBRSAVE);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
&env->CSR_TLBRELO0);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
&env->CSR_TLBRELO1);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
&env->CSR_TLBREHI);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
&env->CSR_TLBRPRMD);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
&env->CSR_DMW[0]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
&env->CSR_DMW[1]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
&env->CSR_DMW[2]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
&env->CSR_DMW[3]);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
&env->CSR_TVAL);
ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
&env->CSR_TCFG);
return ret;
}
static int kvm_loongarch_put_csr(CPUState *cs)
{
int ret = 0;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
&env->CSR_CRMD);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
&env->CSR_PRMD);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
&env->CSR_EUEN);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
&env->CSR_MISC);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
&env->CSR_ECFG);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
&env->CSR_ESTAT);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
&env->CSR_ERA);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
&env->CSR_BADV);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
&env->CSR_BADI);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
&env->CSR_EENTRY);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
&env->CSR_TLBIDX);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
&env->CSR_TLBEHI);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
&env->CSR_TLBELO0);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
&env->CSR_TLBELO1);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
&env->CSR_ASID);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
&env->CSR_PGDL);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
&env->CSR_PGDH);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
&env->CSR_PGD);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
&env->CSR_PWCL);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
&env->CSR_PWCH);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
&env->CSR_STLBPS);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
&env->CSR_RVACFG);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
&env->CSR_CPUID);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
&env->CSR_PRCFG1);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
&env->CSR_PRCFG2);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
&env->CSR_PRCFG3);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
&env->CSR_SAVE[0]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
&env->CSR_SAVE[1]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
&env->CSR_SAVE[2]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
&env->CSR_SAVE[3]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
&env->CSR_SAVE[4]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
&env->CSR_SAVE[5]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
&env->CSR_SAVE[6]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
&env->CSR_SAVE[7]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
&env->CSR_TID);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
&env->CSR_CNTC);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
&env->CSR_TICLR);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
&env->CSR_LLBCTL);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
&env->CSR_IMPCTL1);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
&env->CSR_IMPCTL2);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
&env->CSR_TLBRENTRY);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
&env->CSR_TLBRBADV);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
&env->CSR_TLBRERA);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
&env->CSR_TLBRSAVE);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
&env->CSR_TLBRELO0);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
&env->CSR_TLBRELO1);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
&env->CSR_TLBREHI);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
&env->CSR_TLBRPRMD);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
&env->CSR_DMW[0]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
&env->CSR_DMW[1]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
&env->CSR_DMW[2]);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
&env->CSR_DMW[3]);
/*
* timer cfg must be put at last since it is used to enable
* guest timer
*/
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
&env->CSR_TVAL);
ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
&env->CSR_TCFG);
return ret;
}
static int kvm_loongarch_get_regs_fp(CPUState *cs)
{
int ret, i;
struct kvm_fpu fpu;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
ret = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu);
if (ret < 0) {
trace_kvm_failed_get_fpu(strerror(errno));
return ret;
}
env->fcsr0 = fpu.fcsr;
for (i = 0; i < 32; i++) {
env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
}
for (i = 0; i < 8; i++) {
env->cf[i] = fpu.fcc & 0xFF;
fpu.fcc = fpu.fcc >> 8;
}
return ret;
}
static int kvm_loongarch_put_regs_fp(CPUState *cs)
{
int ret, i;
struct kvm_fpu fpu;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
fpu.fcsr = env->fcsr0;
fpu.fcc = 0;
for (i = 0; i < 32; i++) {
fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
}
for (i = 0; i < 8; i++) {
fpu.fcc |= env->cf[i] << (8 * i);
}
ret = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu);
if (ret < 0) {
trace_kvm_failed_put_fpu(strerror(errno));
}
return ret;
}
void kvm_arch_reset_vcpu(CPULoongArchState *env)
{
env->mp_state = KVM_MP_STATE_RUNNABLE;
}
static int kvm_loongarch_get_mpstate(CPUState *cs)
{
int ret = 0;
struct kvm_mp_state mp_state;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
if (cap_has_mp_state) {
ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state);
if (ret) {
trace_kvm_failed_get_mpstate(strerror(errno));
return ret;
}
env->mp_state = mp_state.mp_state;
}
return ret;
}
static int kvm_loongarch_put_mpstate(CPUState *cs)
{
int ret = 0;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
struct kvm_mp_state mp_state = {
.mp_state = env->mp_state
};
if (cap_has_mp_state) {
ret = kvm_vcpu_ioctl(cs, KVM_SET_MP_STATE, &mp_state);
if (ret) {
trace_kvm_failed_put_mpstate(strerror(errno));
}
}
return ret;
}
static int kvm_loongarch_get_cpucfg(CPUState *cs)
{
int i, ret = 0;
uint64_t val;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
for (i = 0; i < 21; i++) {
ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
if (ret < 0) {
trace_kvm_failed_get_cpucfg(strerror(errno));
}
env->cpucfg[i] = (uint32_t)val;
}
return ret;
}
static int kvm_loongarch_put_cpucfg(CPUState *cs)
{
int i, ret = 0;
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
uint64_t val;
for (i = 0; i < 21; i++) {
val = env->cpucfg[i];
/* LSX and LASX and LBT are not supported in kvm now */
if (i == 2) {
val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT));
val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) |
BIT(R_CPUCFG2_LBT_ARM_SHIFT) |
BIT(R_CPUCFG2_LBT_MIPS_SHIFT));
}
ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
if (ret < 0) {
trace_kvm_failed_put_cpucfg(strerror(errno));
}
}
return ret;
}
int kvm_arch_get_registers(CPUState *cs)
{
return 0;
int ret;
ret = kvm_loongarch_get_regs_core(cs);
if (ret) {
return ret;
}
ret = kvm_loongarch_get_csr(cs);
if (ret) {
return ret;
}
ret = kvm_loongarch_get_regs_fp(cs);
if (ret) {
return ret;
}
ret = kvm_loongarch_get_mpstate(cs);
if (ret) {
return ret;
}
ret = kvm_loongarch_get_cpucfg(cs);
return ret;
}
int kvm_arch_put_registers(CPUState *cs, int level)
{
return 0;
int ret;
ret = kvm_loongarch_put_regs_core(cs);
if (ret) {
return ret;
}
ret = kvm_loongarch_put_csr(cs);
if (ret) {
return ret;
}
ret = kvm_loongarch_put_regs_fp(cs);
if (ret) {
return ret;
}
ret = kvm_loongarch_put_mpstate(cs);
if (ret) {
return ret;
}
ret = kvm_loongarch_put_cpucfg(cs);
return ret;
}
int kvm_arch_init_vcpu(CPUState *cs)

View File

@ -0,0 +1,11 @@
# See docs/devel/tracing.rst for syntax documentation.
#kvm.c
kvm_failed_get_regs_core(const char *msg) "Failed to get core regs from KVM: %s"
kvm_failed_put_regs_core(const char *msg) "Failed to put core regs into KVM: %s"
kvm_failed_get_fpu(const char *msg) "Failed to get fpu from KVM: %s"
kvm_failed_put_fpu(const char *msg) "Failed to put fpu into KVM: %s"
kvm_failed_get_mpstate(const char *msg) "Failed to get mp_state from KVM: %s"
kvm_failed_put_mpstate(const char *msg) "Failed to put mp_state into KVM: %s"
kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s"
kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s"

1
target/loongarch/trace.h Normal file
View File

@ -0,0 +1 @@
#include "trace/trace-target_loongarch.h"