@@ -157,7 +157,7 @@ static int kvm_handle_csr(struct kvm_vcpu *vcpu, larch_inst inst)
157157int kvm_emu_iocsr (larch_inst inst , struct kvm_run * run , struct kvm_vcpu * vcpu )
158158{
159159 int ret ;
160- unsigned long val ;
160+ unsigned long * val ;
161161 u32 addr , rd , rj , opcode ;
162162
163163 /*
@@ -170,6 +170,7 @@ int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu)
170170 ret = EMULATE_DO_IOCSR ;
171171 run -> iocsr_io .phys_addr = addr ;
172172 run -> iocsr_io .is_write = 0 ;
173+ val = & vcpu -> arch .gprs [rd ];
173174
174175 /* LoongArch is Little endian */
175176 switch (opcode ) {
@@ -202,16 +203,25 @@ int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu)
202203 run -> iocsr_io .is_write = 1 ;
203204 break ;
204205 default :
205- ret = EMULATE_FAIL ;
206- break ;
206+ return EMULATE_FAIL ;
207207 }
208208
209- if (ret == EMULATE_DO_IOCSR ) {
210- if (run -> iocsr_io .is_write ) {
211- val = vcpu -> arch .gprs [rd ];
212- memcpy (run -> iocsr_io .data , & val , run -> iocsr_io .len );
213- }
214- vcpu -> arch .io_gpr = rd ;
209+ if (run -> iocsr_io .is_write ) {
210+ if (!kvm_io_bus_write (vcpu , KVM_IOCSR_BUS , addr , run -> iocsr_io .len , val ))
211+ ret = EMULATE_DONE ;
212+ else
213+ /* Save data and let user space to write it */
214+ memcpy (run -> iocsr_io .data , val , run -> iocsr_io .len );
215+
216+ trace_kvm_iocsr (KVM_TRACE_IOCSR_WRITE , run -> iocsr_io .len , addr , val );
217+ } else {
218+ if (!kvm_io_bus_read (vcpu , KVM_IOCSR_BUS , addr , run -> iocsr_io .len , val ))
219+ ret = EMULATE_DONE ;
220+ else
221+ /* Save register id for iocsr read completion */
222+ vcpu -> arch .io_gpr = rd ;
223+
224+ trace_kvm_iocsr (KVM_TRACE_IOCSR_READ , run -> iocsr_io .len , addr , NULL );
215225 }
216226
217227 return ret ;
@@ -447,19 +457,33 @@ int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst)
447457 }
448458
449459 if (ret == EMULATE_DO_MMIO ) {
460+ trace_kvm_mmio (KVM_TRACE_MMIO_READ , run -> mmio .len , run -> mmio .phys_addr , NULL );
461+
462+ /*
463+ * If mmio device such as PCH-PIC is emulated in KVM,
464+ * it need not return to user space to handle the mmio
465+ * exception.
466+ */
467+ ret = kvm_io_bus_read (vcpu , KVM_MMIO_BUS , vcpu -> arch .badv ,
468+ run -> mmio .len , & vcpu -> arch .gprs [rd ]);
469+ if (!ret ) {
470+ update_pc (& vcpu -> arch );
471+ vcpu -> mmio_needed = 0 ;
472+ return EMULATE_DONE ;
473+ }
474+
450475 /* Set for kvm_complete_mmio_read() use */
451476 vcpu -> arch .io_gpr = rd ;
452477 run -> mmio .is_write = 0 ;
453478 vcpu -> mmio_is_write = 0 ;
454- trace_kvm_mmio (KVM_TRACE_MMIO_READ_UNSATISFIED , run -> mmio .len ,
455- run -> mmio .phys_addr , NULL );
456- } else {
457- kvm_err ("Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\n" ,
458- inst .word , vcpu -> arch .pc , vcpu -> arch .badv );
459- kvm_arch_vcpu_dump_regs (vcpu );
460- vcpu -> mmio_needed = 0 ;
479+ return EMULATE_DO_MMIO ;
461480 }
462481
482+ kvm_err ("Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\n" ,
483+ inst .word , vcpu -> arch .pc , vcpu -> arch .badv );
484+ kvm_arch_vcpu_dump_regs (vcpu );
485+ vcpu -> mmio_needed = 0 ;
486+
463487 return ret ;
464488}
465489
@@ -600,19 +624,29 @@ int kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst)
600624 }
601625
602626 if (ret == EMULATE_DO_MMIO ) {
627+ trace_kvm_mmio (KVM_TRACE_MMIO_WRITE , run -> mmio .len , run -> mmio .phys_addr , data );
628+
629+ /*
630+ * If mmio device such as PCH-PIC is emulated in KVM,
631+ * it need not return to user space to handle the mmio
632+ * exception.
633+ */
634+ ret = kvm_io_bus_write (vcpu , KVM_MMIO_BUS , vcpu -> arch .badv , run -> mmio .len , data );
635+ if (!ret )
636+ return EMULATE_DONE ;
637+
603638 run -> mmio .is_write = 1 ;
604639 vcpu -> mmio_needed = 1 ;
605640 vcpu -> mmio_is_write = 1 ;
606- trace_kvm_mmio (KVM_TRACE_MMIO_WRITE , run -> mmio .len ,
607- run -> mmio .phys_addr , data );
608- } else {
609- vcpu -> arch .pc = curr_pc ;
610- kvm_err ("Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\n" ,
611- inst .word , vcpu -> arch .pc , vcpu -> arch .badv );
612- kvm_arch_vcpu_dump_regs (vcpu );
613- /* Rollback PC if emulation was unsuccessful */
641+ return EMULATE_DO_MMIO ;
614642 }
615643
644+ vcpu -> arch .pc = curr_pc ;
645+ kvm_err ("Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\n" ,
646+ inst .word , vcpu -> arch .pc , vcpu -> arch .badv );
647+ kvm_arch_vcpu_dump_regs (vcpu );
648+ /* Rollback PC if emulation was unsuccessful */
649+
616650 return ret ;
617651}
618652
0 commit comments