@@ -157,7 +157,7 @@ static int kvm_handle_csr(struct kvm_vcpu *vcpu, larch_inst inst)
157
157
int kvm_emu_iocsr (larch_inst inst , struct kvm_run * run , struct kvm_vcpu * vcpu )
158
158
{
159
159
int ret ;
160
- unsigned long val ;
160
+ unsigned long * val ;
161
161
u32 addr , rd , rj , opcode ;
162
162
163
163
/*
@@ -170,6 +170,7 @@ int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu)
170
170
ret = EMULATE_DO_IOCSR ;
171
171
run -> iocsr_io .phys_addr = addr ;
172
172
run -> iocsr_io .is_write = 0 ;
173
+ val = & vcpu -> arch .gprs [rd ];
173
174
174
175
/* LoongArch is Little endian */
175
176
switch (opcode ) {
@@ -202,16 +203,25 @@ int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu)
202
203
run -> iocsr_io .is_write = 1 ;
203
204
break ;
204
205
default :
205
- ret = EMULATE_FAIL ;
206
- break ;
206
+ return EMULATE_FAIL ;
207
207
}
208
208
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 );
215
225
}
216
226
217
227
return ret ;
@@ -447,19 +457,33 @@ int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst)
447
457
}
448
458
449
459
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
+
450
475
/* Set for kvm_complete_mmio_read() use */
451
476
vcpu -> arch .io_gpr = rd ;
452
477
run -> mmio .is_write = 0 ;
453
478
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 ;
461
480
}
462
481
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
+
463
487
return ret ;
464
488
}
465
489
@@ -600,19 +624,29 @@ int kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst)
600
624
}
601
625
602
626
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
+
603
638
run -> mmio .is_write = 1 ;
604
639
vcpu -> mmio_needed = 1 ;
605
640
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 ;
614
642
}
615
643
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
+
616
650
return ret ;
617
651
}
618
652
0 commit comments