@@ -4544,6 +4544,9 @@ static bool retry_instruction(struct x86_emulate_ctxt *ctxt,
4544
4544
return true;
4545
4545
}
4546
4546
4547
+ static int complete_emulated_mmio (struct kvm_vcpu * vcpu );
4548
+ static int complete_emulated_pio (struct kvm_vcpu * vcpu );
4549
+
4547
4550
int x86_emulate_instruction (struct kvm_vcpu * vcpu ,
4548
4551
unsigned long cr2 ,
4549
4552
int emulation_type ,
@@ -4614,13 +4617,16 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
4614
4617
} else if (vcpu -> arch .pio .count ) {
4615
4618
if (!vcpu -> arch .pio .in )
4616
4619
vcpu -> arch .pio .count = 0 ;
4617
- else
4620
+ else {
4618
4621
writeback = false;
4622
+ vcpu -> arch .complete_userspace_io = complete_emulated_pio ;
4623
+ }
4619
4624
r = EMULATE_DO_MMIO ;
4620
4625
} else if (vcpu -> mmio_needed ) {
4621
4626
if (!vcpu -> mmio_is_write )
4622
4627
writeback = false;
4623
4628
r = EMULATE_DO_MMIO ;
4629
+ vcpu -> arch .complete_userspace_io = complete_emulated_mmio ;
4624
4630
} else if (r == EMULATION_RESTART )
4625
4631
goto restart ;
4626
4632
else
@@ -5476,6 +5482,24 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
5476
5482
return r ;
5477
5483
}
5478
5484
5485
+ static inline int complete_emulated_io (struct kvm_vcpu * vcpu )
5486
+ {
5487
+ int r ;
5488
+ vcpu -> srcu_idx = srcu_read_lock (& vcpu -> kvm -> srcu );
5489
+ r = emulate_instruction (vcpu , EMULTYPE_NO_DECODE );
5490
+ srcu_read_unlock (& vcpu -> kvm -> srcu , vcpu -> srcu_idx );
5491
+ if (r != EMULATE_DONE )
5492
+ return 0 ;
5493
+ return 1 ;
5494
+ }
5495
+
5496
+ static int complete_emulated_pio (struct kvm_vcpu * vcpu )
5497
+ {
5498
+ BUG_ON (!vcpu -> arch .pio .count );
5499
+
5500
+ return complete_emulated_io (vcpu );
5501
+ }
5502
+
5479
5503
/*
5480
5504
* Implements the following, as a state machine:
5481
5505
*
@@ -5492,47 +5516,37 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
5492
5516
* copy data
5493
5517
* exit
5494
5518
*/
5495
- static int complete_mmio (struct kvm_vcpu * vcpu )
5519
+ static int complete_emulated_mmio (struct kvm_vcpu * vcpu )
5496
5520
{
5497
5521
struct kvm_run * run = vcpu -> run ;
5498
5522
struct kvm_mmio_fragment * frag ;
5499
- int r ;
5500
5523
5501
- if (!(vcpu -> arch .pio .count || vcpu -> mmio_needed ))
5502
- return 1 ;
5524
+ BUG_ON (!vcpu -> mmio_needed );
5503
5525
5504
- if (vcpu -> mmio_needed ) {
5505
- /* Complete previous fragment */
5506
- frag = & vcpu -> mmio_fragments [vcpu -> mmio_cur_fragment ++ ];
5507
- if (!vcpu -> mmio_is_write )
5508
- memcpy (frag -> data , run -> mmio .data , frag -> len );
5509
- if (vcpu -> mmio_cur_fragment == vcpu -> mmio_nr_fragments ) {
5510
- vcpu -> mmio_needed = 0 ;
5511
- if (vcpu -> mmio_is_write )
5512
- return 1 ;
5513
- vcpu -> mmio_read_completed = 1 ;
5514
- goto done ;
5515
- }
5516
- /* Initiate next fragment */
5517
- ++ frag ;
5518
- run -> exit_reason = KVM_EXIT_MMIO ;
5519
- run -> mmio .phys_addr = frag -> gpa ;
5526
+ /* Complete previous fragment */
5527
+ frag = & vcpu -> mmio_fragments [vcpu -> mmio_cur_fragment ++ ];
5528
+ if (!vcpu -> mmio_is_write )
5529
+ memcpy (frag -> data , run -> mmio .data , frag -> len );
5530
+ if (vcpu -> mmio_cur_fragment == vcpu -> mmio_nr_fragments ) {
5531
+ vcpu -> mmio_needed = 0 ;
5520
5532
if (vcpu -> mmio_is_write )
5521
- memcpy (run -> mmio .data , frag -> data , frag -> len );
5522
- run -> mmio .len = frag -> len ;
5523
- run -> mmio .is_write = vcpu -> mmio_is_write ;
5524
- return 0 ;
5525
-
5526
- }
5527
- done :
5528
- vcpu -> srcu_idx = srcu_read_lock (& vcpu -> kvm -> srcu );
5529
- r = emulate_instruction (vcpu , EMULTYPE_NO_DECODE );
5530
- srcu_read_unlock (& vcpu -> kvm -> srcu , vcpu -> srcu_idx );
5531
- if (r != EMULATE_DONE )
5532
- return 0 ;
5533
- return 1 ;
5533
+ return 1 ;
5534
+ vcpu -> mmio_read_completed = 1 ;
5535
+ return complete_emulated_io (vcpu );
5536
+ }
5537
+ /* Initiate next fragment */
5538
+ ++ frag ;
5539
+ run -> exit_reason = KVM_EXIT_MMIO ;
5540
+ run -> mmio .phys_addr = frag -> gpa ;
5541
+ if (vcpu -> mmio_is_write )
5542
+ memcpy (run -> mmio .data , frag -> data , frag -> len );
5543
+ run -> mmio .len = frag -> len ;
5544
+ run -> mmio .is_write = vcpu -> mmio_is_write ;
5545
+ vcpu -> arch .complete_userspace_io = complete_emulated_mmio ;
5546
+ return 0 ;
5534
5547
}
5535
5548
5549
+
5536
5550
int kvm_arch_vcpu_ioctl_run (struct kvm_vcpu * vcpu , struct kvm_run * kvm_run )
5537
5551
{
5538
5552
int r ;
@@ -5559,9 +5573,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
5559
5573
}
5560
5574
}
5561
5575
5562
- r = complete_mmio (vcpu );
5563
- if (r <= 0 )
5564
- goto out ;
5576
+ if (unlikely (vcpu -> arch .complete_userspace_io )) {
5577
+ int (* cui )(struct kvm_vcpu * ) = vcpu -> arch .complete_userspace_io ;
5578
+ vcpu -> arch .complete_userspace_io = NULL ;
5579
+ r = cui (vcpu );
5580
+ if (r <= 0 )
5581
+ goto out ;
5582
+ } else
5583
+ WARN_ON (vcpu -> arch .pio .count || vcpu -> mmio_needed );
5565
5584
5566
5585
r = __vcpu_run (vcpu );
5567
5586
0 commit comments