@@ -6906,18 +6906,16 @@ static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
6906
6906
}
6907
6907
6908
6908
static int emulator_pio_in_out (struct kvm_vcpu * vcpu , int size ,
6909
- unsigned short port , void * val ,
6909
+ unsigned short port ,
6910
6910
unsigned int count , bool in )
6911
6911
{
6912
6912
vcpu -> arch .pio .port = port ;
6913
6913
vcpu -> arch .pio .in = in ;
6914
6914
vcpu -> arch .pio .count = count ;
6915
6915
vcpu -> arch .pio .size = size ;
6916
6916
6917
- if (!kernel_pio (vcpu , vcpu -> arch .pio_data )) {
6918
- vcpu -> arch .pio .count = 0 ;
6917
+ if (!kernel_pio (vcpu , vcpu -> arch .pio_data ))
6919
6918
return 1 ;
6920
- }
6921
6919
6922
6920
vcpu -> run -> exit_reason = KVM_EXIT_IO ;
6923
6921
vcpu -> run -> io .direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT ;
@@ -6929,26 +6927,39 @@ static int emulator_pio_in_out(struct kvm_vcpu *vcpu, int size,
6929
6927
return 0 ;
6930
6928
}
6931
6929
6932
- static int emulator_pio_in (struct kvm_vcpu * vcpu , int size ,
6933
- unsigned short port , void * val , unsigned int count )
6930
+ static int __emulator_pio_in (struct kvm_vcpu * vcpu , int size ,
6931
+ unsigned short port , unsigned int count )
6934
6932
{
6935
- int ret ;
6933
+ WARN_ON (vcpu -> arch .pio .count );
6934
+ memset (vcpu -> arch .pio_data , 0 , size * count );
6935
+ return emulator_pio_in_out (vcpu , size , port , count , true);
6936
+ }
6936
6937
6937
- if (vcpu -> arch .pio .count )
6938
- goto data_avail ;
6938
+ static void complete_emulator_pio_in (struct kvm_vcpu * vcpu , void * val )
6939
+ {
6940
+ int size = vcpu -> arch .pio .size ;
6941
+ unsigned count = vcpu -> arch .pio .count ;
6942
+ memcpy (val , vcpu -> arch .pio_data , size * count );
6943
+ trace_kvm_pio (KVM_PIO_IN , vcpu -> arch .pio .port , size , count , vcpu -> arch .pio_data );
6944
+ vcpu -> arch .pio .count = 0 ;
6945
+ }
6939
6946
6940
- memset (vcpu -> arch .pio_data , 0 , size * count );
6947
+ static int emulator_pio_in (struct kvm_vcpu * vcpu , int size ,
6948
+ unsigned short port , void * val , unsigned int count )
6949
+ {
6950
+ if (vcpu -> arch .pio .count ) {
6951
+ /* Complete previous iteration. */
6952
+ } else {
6953
+ int r = __emulator_pio_in (vcpu , size , port , count );
6954
+ if (!r )
6955
+ return r ;
6941
6956
6942
- ret = emulator_pio_in_out (vcpu , size , port , val , count , true);
6943
- if (ret ) {
6944
- data_avail :
6945
- memcpy (val , vcpu -> arch .pio_data , size * count );
6946
- trace_kvm_pio (KVM_PIO_IN , port , size , count , vcpu -> arch .pio_data );
6947
- vcpu -> arch .pio .count = 0 ;
6948
- return 1 ;
6957
+ /* Results already available, fall through. */
6949
6958
}
6950
6959
6951
- return 0 ;
6960
+ WARN_ON (count != vcpu -> arch .pio .count );
6961
+ complete_emulator_pio_in (vcpu , val );
6962
+ return 1 ;
6952
6963
}
6953
6964
6954
6965
static int emulator_pio_in_emulated (struct x86_emulate_ctxt * ctxt ,
@@ -6963,9 +6974,15 @@ static int emulator_pio_out(struct kvm_vcpu *vcpu, int size,
6963
6974
unsigned short port , const void * val ,
6964
6975
unsigned int count )
6965
6976
{
6977
+ int ret ;
6978
+
6966
6979
memcpy (vcpu -> arch .pio_data , val , size * count );
6967
6980
trace_kvm_pio (KVM_PIO_OUT , port , size , count , vcpu -> arch .pio_data );
6968
- return emulator_pio_in_out (vcpu , size , port , (void * )val , count , false);
6981
+ ret = emulator_pio_in_out (vcpu , size , port , count , false);
6982
+ if (ret )
6983
+ vcpu -> arch .pio .count = 0 ;
6984
+
6985
+ return ret ;
6969
6986
}
6970
6987
6971
6988
static int emulator_pio_out_emulated (struct x86_emulate_ctxt * ctxt ,
@@ -9643,14 +9660,14 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
9643
9660
if (likely (exit_fastpath != EXIT_FASTPATH_REENTER_GUEST ))
9644
9661
break ;
9645
9662
9646
- if (unlikely (kvm_vcpu_exit_request (vcpu ))) {
9663
+ if (vcpu -> arch .apicv_active )
9664
+ static_call (kvm_x86_sync_pir_to_irr )(vcpu );
9665
+
9666
+ if (unlikely (kvm_vcpu_exit_request (vcpu ))) {
9647
9667
exit_fastpath = EXIT_FASTPATH_EXIT_HANDLED ;
9648
9668
break ;
9649
9669
}
9650
-
9651
- if (vcpu -> arch .apicv_active )
9652
- static_call (kvm_x86_sync_pir_to_irr )(vcpu );
9653
- }
9670
+ }
9654
9671
9655
9672
/*
9656
9673
* Do this here before restoring debug registers on the host. And
@@ -12368,53 +12385,92 @@ int kvm_sev_es_mmio_read(struct kvm_vcpu *vcpu, gpa_t gpa, unsigned int bytes,
12368
12385
}
12369
12386
EXPORT_SYMBOL_GPL (kvm_sev_es_mmio_read );
12370
12387
12371
- static int complete_sev_es_emulated_ins (struct kvm_vcpu * vcpu )
12388
+ static int kvm_sev_es_outs (struct kvm_vcpu * vcpu , unsigned int size ,
12389
+ unsigned int port );
12390
+
12391
+ static int complete_sev_es_emulated_outs (struct kvm_vcpu * vcpu )
12372
12392
{
12373
- memcpy (vcpu -> arch .guest_ins_data , vcpu -> arch .pio_data ,
12374
- vcpu -> arch .pio .count * vcpu -> arch .pio .size );
12375
- vcpu -> arch .pio .count = 0 ;
12393
+ int size = vcpu -> arch .pio .size ;
12394
+ int port = vcpu -> arch .pio .port ;
12376
12395
12396
+ vcpu -> arch .pio .count = 0 ;
12397
+ if (vcpu -> arch .sev_pio_count )
12398
+ return kvm_sev_es_outs (vcpu , size , port );
12377
12399
return 1 ;
12378
12400
}
12379
12401
12380
12402
static int kvm_sev_es_outs (struct kvm_vcpu * vcpu , unsigned int size ,
12381
- unsigned int port , void * data , unsigned int count )
12403
+ unsigned int port )
12382
12404
{
12383
- int ret ;
12384
-
12385
- ret = emulator_pio_out_emulated (vcpu -> arch .emulate_ctxt , size , port ,
12386
- data , count );
12387
- if (ret )
12388
- return ret ;
12405
+ for (;;) {
12406
+ unsigned int count =
12407
+ min_t (unsigned int , PAGE_SIZE / size , vcpu -> arch .sev_pio_count );
12408
+ int ret = emulator_pio_out (vcpu , size , port , vcpu -> arch .sev_pio_data , count );
12409
+
12410
+ /* memcpy done already by emulator_pio_out. */
12411
+ vcpu -> arch .sev_pio_count -= count ;
12412
+ vcpu -> arch .sev_pio_data += count * vcpu -> arch .pio .size ;
12413
+ if (!ret )
12414
+ break ;
12389
12415
12390
- vcpu -> arch .pio .count = 0 ;
12416
+ /* Emulation done by the kernel. */
12417
+ if (!vcpu -> arch .sev_pio_count )
12418
+ return 1 ;
12419
+ }
12391
12420
12421
+ vcpu -> arch .complete_userspace_io = complete_sev_es_emulated_outs ;
12392
12422
return 0 ;
12393
12423
}
12394
12424
12395
12425
static int kvm_sev_es_ins (struct kvm_vcpu * vcpu , unsigned int size ,
12396
- unsigned int port , void * data , unsigned int count )
12426
+ unsigned int port );
12427
+
12428
+ static void advance_sev_es_emulated_ins (struct kvm_vcpu * vcpu )
12397
12429
{
12398
- int ret ;
12430
+ unsigned count = vcpu -> arch .pio .count ;
12431
+ complete_emulator_pio_in (vcpu , vcpu -> arch .sev_pio_data );
12432
+ vcpu -> arch .sev_pio_count -= count ;
12433
+ vcpu -> arch .sev_pio_data += count * vcpu -> arch .pio .size ;
12434
+ }
12399
12435
12400
- ret = emulator_pio_in_emulated (vcpu -> arch .emulate_ctxt , size , port ,
12401
- data , count );
12402
- if (ret ) {
12403
- vcpu -> arch .pio .count = 0 ;
12404
- } else {
12405
- vcpu -> arch .guest_ins_data = data ;
12406
- vcpu -> arch .complete_userspace_io = complete_sev_es_emulated_ins ;
12436
+ static int complete_sev_es_emulated_ins (struct kvm_vcpu * vcpu )
12437
+ {
12438
+ int size = vcpu -> arch .pio .size ;
12439
+ int port = vcpu -> arch .pio .port ;
12440
+
12441
+ advance_sev_es_emulated_ins (vcpu );
12442
+ if (vcpu -> arch .sev_pio_count )
12443
+ return kvm_sev_es_ins (vcpu , size , port );
12444
+ return 1 ;
12445
+ }
12446
+
12447
+ static int kvm_sev_es_ins (struct kvm_vcpu * vcpu , unsigned int size ,
12448
+ unsigned int port )
12449
+ {
12450
+ for (;;) {
12451
+ unsigned int count =
12452
+ min_t (unsigned int , PAGE_SIZE / size , vcpu -> arch .sev_pio_count );
12453
+ if (!__emulator_pio_in (vcpu , size , port , count ))
12454
+ break ;
12455
+
12456
+ /* Emulation done by the kernel. */
12457
+ advance_sev_es_emulated_ins (vcpu );
12458
+ if (!vcpu -> arch .sev_pio_count )
12459
+ return 1 ;
12407
12460
}
12408
12461
12462
+ vcpu -> arch .complete_userspace_io = complete_sev_es_emulated_ins ;
12409
12463
return 0 ;
12410
12464
}
12411
12465
12412
12466
int kvm_sev_es_string_io (struct kvm_vcpu * vcpu , unsigned int size ,
12413
12467
unsigned int port , void * data , unsigned int count ,
12414
12468
int in )
12415
12469
{
12416
- return in ? kvm_sev_es_ins (vcpu , size , port , data , count )
12417
- : kvm_sev_es_outs (vcpu , size , port , data , count );
12470
+ vcpu -> arch .sev_pio_data = data ;
12471
+ vcpu -> arch .sev_pio_count = count ;
12472
+ return in ? kvm_sev_es_ins (vcpu , size , port )
12473
+ : kvm_sev_es_outs (vcpu , size , port );
12418
12474
}
12419
12475
EXPORT_SYMBOL_GPL (kvm_sev_es_string_io );
12420
12476
0 commit comments