lkml.org 
[lkml]   [2023]   [Jun]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [PATCH v14 21/30] LoongArch: KVM: Implement handle iocsr exception
From
Date

在 2023/6/19 下午6:13, Huacai Chen 写道:
> Hi, Tianrui,
>
> On Mon, Jun 19, 2023 at 4:33 PM Tianrui Zhao <zhaotianrui@loongson.cn> wrote:
>> Implement kvm handle vcpu iocsr exception, setting the iocsr info into
>> vcpu_run and return to user space to handle it.
>>
>> Reviewed-by: Bibo Mao <maobibo@loongson.cn>
>> Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
>> ---
>> arch/loongarch/include/asm/inst.h | 16 ++++++
>> arch/loongarch/kvm/exit.c | 92 +++++++++++++++++++++++++++++++
>> 2 files changed, 108 insertions(+)
>>
>> diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h
>> index b09887ffcd15..db5857796432 100644
>> --- a/arch/loongarch/include/asm/inst.h
>> +++ b/arch/loongarch/include/asm/inst.h
>> @@ -56,6 +56,14 @@ enum reg2_op {
>> revbd_op = 0x0f,
>> revh2w_op = 0x10,
>> revhd_op = 0x11,
>> + iocsrrdb_op = 0x19200,
>> + iocsrrdh_op = 0x19201,
>> + iocsrrdw_op = 0x19202,
>> + iocsrrdd_op = 0x19203,
>> + iocsrwrb_op = 0x19204,
>> + iocsrwrh_op = 0x19205,
>> + iocsrwrw_op = 0x19206,
>> + iocsrwrd_op = 0x19207,
>> };
>>
>> enum reg2i5_op {
>> @@ -298,6 +306,13 @@ struct reg3sa2_format {
>> unsigned int opcode : 15;
>> };
>>
>> +struct reg2csr_format {
>> + unsigned int rd : 5;
>> + unsigned int rj : 5;
>> + unsigned int csr : 14;
>> + unsigned int opcode : 8;
>> +};
> Put it before reg3_format.
Thanks, I will re-order it.
>
>> +
>> union loongarch_instruction {
>> unsigned int word;
>> struct reg0i15_format reg0i15_format;
>> @@ -313,6 +328,7 @@ union loongarch_instruction {
>> struct reg2bstrd_format reg2bstrd_format;
>> struct reg3_format reg3_format;
>> struct reg3sa2_format reg3sa2_format;
>> + struct reg2csr_format reg2csr_format;
> The same, thanks.
>
> Huacai
I will exchange them too.

Thanks
Tianrui Zhao
>> };
>>
>> #define LOONGARCH_INSN_SIZE sizeof(union loongarch_instruction)
>> diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c
>> index 18635333fc9a..32edd915ebcb 100644
>> --- a/arch/loongarch/kvm/exit.c
>> +++ b/arch/loongarch/kvm/exit.c
>> @@ -96,3 +96,95 @@ static int _kvm_handle_csr(struct kvm_vcpu *vcpu, larch_inst inst)
>>
>> return EMULATE_DONE;
>> }
>> +
>> +int _kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu)
>> +{
>> + u32 rd, rj, opcode;
>> + u32 addr;
>> + unsigned long val;
>> + int ret;
>> +
>> + /*
>> + * Each IOCSR with different opcode
>> + */
>> + rd = inst.reg2_format.rd;
>> + rj = inst.reg2_format.rj;
>> + opcode = inst.reg2_format.opcode;
>> + addr = vcpu->arch.gprs[rj];
>> + ret = EMULATE_DO_IOCSR;
>> + run->iocsr_io.phys_addr = addr;
>> + run->iocsr_io.is_write = 0;
>> +
>> + /* LoongArch is Little endian */
>> + switch (opcode) {
>> + case iocsrrdb_op:
>> + run->iocsr_io.len = 1;
>> + break;
>> + case iocsrrdh_op:
>> + run->iocsr_io.len = 2;
>> + break;
>> + case iocsrrdw_op:
>> + run->iocsr_io.len = 4;
>> + break;
>> + case iocsrrdd_op:
>> + run->iocsr_io.len = 8;
>> + break;
>> + case iocsrwrb_op:
>> + run->iocsr_io.len = 1;
>> + run->iocsr_io.is_write = 1;
>> + break;
>> + case iocsrwrh_op:
>> + run->iocsr_io.len = 2;
>> + run->iocsr_io.is_write = 1;
>> + break;
>> + case iocsrwrw_op:
>> + run->iocsr_io.len = 4;
>> + run->iocsr_io.is_write = 1;
>> + break;
>> + case iocsrwrd_op:
>> + run->iocsr_io.len = 8;
>> + run->iocsr_io.is_write = 1;
>> + break;
>> + default:
>> + ret = EMULATE_FAIL;
>> + break;
>> + }
>> +
>> + if (ret == EMULATE_DO_IOCSR) {
>> + if (run->iocsr_io.is_write) {
>> + val = vcpu->arch.gprs[rd];
>> + memcpy(run->iocsr_io.data, &val, run->iocsr_io.len);
>> + }
>> + vcpu->arch.io_gpr = rd;
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +int _kvm_complete_iocsr_read(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +{
>> + unsigned long *gpr = &vcpu->arch.gprs[vcpu->arch.io_gpr];
>> + enum emulation_result er = EMULATE_DONE;
>> +
>> + switch (run->iocsr_io.len) {
>> + case 8:
>> + *gpr = *(s64 *)run->iocsr_io.data;
>> + break;
>> + case 4:
>> + *gpr = *(int *)run->iocsr_io.data;
>> + break;
>> + case 2:
>> + *gpr = *(short *)run->iocsr_io.data;
>> + break;
>> + case 1:
>> + *gpr = *(char *) run->iocsr_io.data;
>> + break;
>> + default:
>> + kvm_err("Bad IOCSR length: %d,addr is 0x%lx",
>> + run->iocsr_io.len, vcpu->arch.badv);
>> + er = EMULATE_FAIL;
>> + break;
>> + }
>> +
>> + return er;
>> +}
>> --
>> 2.39.1
>>
>>

\
 
 \ /
  Last update: 2023-06-20 03:56    [W:0.057 / U:3.140 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site