@@ -792,22 +792,6 @@ static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt)
792
792
do_early_exception (ctxt -> regs , trapnr );
793
793
}
794
794
795
- static long * vc_insn_get_reg (struct es_em_ctxt * ctxt )
796
- {
797
- long * reg_array ;
798
- int offset ;
799
-
800
- reg_array = (long * )ctxt -> regs ;
801
- offset = insn_get_modrm_reg_off (& ctxt -> insn , ctxt -> regs );
802
-
803
- if (offset < 0 )
804
- return NULL ;
805
-
806
- offset /= sizeof (long );
807
-
808
- return reg_array + offset ;
809
- }
810
-
811
795
static long * vc_insn_get_rm (struct es_em_ctxt * ctxt )
812
796
{
813
797
long * reg_array ;
@@ -855,76 +839,6 @@ static enum es_result vc_do_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
855
839
return sev_es_ghcb_hv_call (ghcb , true, ctxt , exit_code , exit_info_1 , exit_info_2 );
856
840
}
857
841
858
- static enum es_result vc_handle_mmio_twobyte_ops (struct ghcb * ghcb ,
859
- struct es_em_ctxt * ctxt )
860
- {
861
- struct insn * insn = & ctxt -> insn ;
862
- unsigned int bytes = 0 ;
863
- enum es_result ret ;
864
- int sign_byte ;
865
- long * reg_data ;
866
-
867
- switch (insn -> opcode .bytes [1 ]) {
868
- /* MMIO Read w/ zero-extension */
869
- case 0xb6 :
870
- bytes = 1 ;
871
- fallthrough ;
872
- case 0xb7 :
873
- if (!bytes )
874
- bytes = 2 ;
875
-
876
- ret = vc_do_mmio (ghcb , ctxt , bytes , true);
877
- if (ret )
878
- break ;
879
-
880
- /* Zero extend based on operand size */
881
- reg_data = vc_insn_get_reg (ctxt );
882
- if (!reg_data )
883
- return ES_DECODE_FAILED ;
884
-
885
- memset (reg_data , 0 , insn -> opnd_bytes );
886
-
887
- memcpy (reg_data , ghcb -> shared_buffer , bytes );
888
- break ;
889
-
890
- /* MMIO Read w/ sign-extension */
891
- case 0xbe :
892
- bytes = 1 ;
893
- fallthrough ;
894
- case 0xbf :
895
- if (!bytes )
896
- bytes = 2 ;
897
-
898
- ret = vc_do_mmio (ghcb , ctxt , bytes , true);
899
- if (ret )
900
- break ;
901
-
902
- /* Sign extend based on operand size */
903
- reg_data = vc_insn_get_reg (ctxt );
904
- if (!reg_data )
905
- return ES_DECODE_FAILED ;
906
-
907
- if (bytes == 1 ) {
908
- u8 * val = (u8 * )ghcb -> shared_buffer ;
909
-
910
- sign_byte = (* val & 0x80 ) ? 0xff : 0x00 ;
911
- } else {
912
- u16 * val = (u16 * )ghcb -> shared_buffer ;
913
-
914
- sign_byte = (* val & 0x8000 ) ? 0xff : 0x00 ;
915
- }
916
- memset (reg_data , sign_byte , insn -> opnd_bytes );
917
-
918
- memcpy (reg_data , ghcb -> shared_buffer , bytes );
919
- break ;
920
-
921
- default :
922
- ret = ES_UNSUPPORTED ;
923
- }
924
-
925
- return ret ;
926
- }
927
-
928
842
/*
929
843
* The MOVS instruction has two memory operands, which raises the
930
844
* problem that it is not known whether the access to the source or the
@@ -992,83 +906,79 @@ static enum es_result vc_handle_mmio_movs(struct es_em_ctxt *ctxt,
992
906
return ES_RETRY ;
993
907
}
994
908
995
- static enum es_result vc_handle_mmio (struct ghcb * ghcb ,
996
- struct es_em_ctxt * ctxt )
909
+ static enum es_result vc_handle_mmio (struct ghcb * ghcb , struct es_em_ctxt * ctxt )
997
910
{
998
911
struct insn * insn = & ctxt -> insn ;
999
912
unsigned int bytes = 0 ;
913
+ enum mmio_type mmio ;
1000
914
enum es_result ret ;
915
+ u8 sign_byte ;
1001
916
long * reg_data ;
1002
917
1003
- switch (insn -> opcode .bytes [0 ]) {
1004
- /* MMIO Write */
1005
- case 0x88 :
1006
- bytes = 1 ;
1007
- fallthrough ;
1008
- case 0x89 :
1009
- if (!bytes )
1010
- bytes = insn -> opnd_bytes ;
918
+ mmio = insn_decode_mmio (insn , & bytes );
919
+ if (mmio == MMIO_DECODE_FAILED )
920
+ return ES_DECODE_FAILED ;
1011
921
1012
- reg_data = vc_insn_get_reg (ctxt );
922
+ if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS ) {
923
+ reg_data = insn_get_modrm_reg_ptr (insn , ctxt -> regs );
1013
924
if (!reg_data )
1014
925
return ES_DECODE_FAILED ;
926
+ }
1015
927
928
+ switch (mmio ) {
929
+ case MMIO_WRITE :
1016
930
memcpy (ghcb -> shared_buffer , reg_data , bytes );
1017
-
1018
931
ret = vc_do_mmio (ghcb , ctxt , bytes , false);
1019
932
break ;
1020
-
1021
- case 0xc6 :
1022
- bytes = 1 ;
1023
- fallthrough ;
1024
- case 0xc7 :
1025
- if (!bytes )
1026
- bytes = insn -> opnd_bytes ;
1027
-
933
+ case MMIO_WRITE_IMM :
1028
934
memcpy (ghcb -> shared_buffer , insn -> immediate1 .bytes , bytes );
1029
-
1030
935
ret = vc_do_mmio (ghcb , ctxt , bytes , false);
1031
936
break ;
1032
-
1033
- /* MMIO Read */
1034
- case 0x8a :
1035
- bytes = 1 ;
1036
- fallthrough ;
1037
- case 0x8b :
1038
- if (!bytes )
1039
- bytes = insn -> opnd_bytes ;
1040
-
937
+ case MMIO_READ :
1041
938
ret = vc_do_mmio (ghcb , ctxt , bytes , true);
1042
939
if (ret )
1043
940
break ;
1044
941
1045
- reg_data = vc_insn_get_reg (ctxt );
1046
- if (!reg_data )
1047
- return ES_DECODE_FAILED ;
1048
-
1049
942
/* Zero-extend for 32-bit operation */
1050
943
if (bytes == 4 )
1051
944
* reg_data = 0 ;
1052
945
1053
946
memcpy (reg_data , ghcb -> shared_buffer , bytes );
1054
947
break ;
948
+ case MMIO_READ_ZERO_EXTEND :
949
+ ret = vc_do_mmio (ghcb , ctxt , bytes , true);
950
+ if (ret )
951
+ break ;
952
+
953
+ /* Zero extend based on operand size */
954
+ memset (reg_data , 0 , insn -> opnd_bytes );
955
+ memcpy (reg_data , ghcb -> shared_buffer , bytes );
956
+ break ;
957
+ case MMIO_READ_SIGN_EXTEND :
958
+ ret = vc_do_mmio (ghcb , ctxt , bytes , true);
959
+ if (ret )
960
+ break ;
1055
961
1056
- /* MOVS instruction */
1057
- case 0xa4 :
1058
- bytes = 1 ;
1059
- fallthrough ;
1060
- case 0xa5 :
1061
- if (!bytes )
1062
- bytes = insn -> opnd_bytes ;
962
+ if (bytes == 1 ) {
963
+ u8 * val = (u8 * )ghcb -> shared_buffer ;
1063
964
1064
- ret = vc_handle_mmio_movs (ctxt , bytes );
965
+ sign_byte = (* val & 0x80 ) ? 0xff : 0x00 ;
966
+ } else {
967
+ u16 * val = (u16 * )ghcb -> shared_buffer ;
968
+
969
+ sign_byte = (* val & 0x8000 ) ? 0xff : 0x00 ;
970
+ }
971
+
972
+ /* Sign extend based on operand size */
973
+ memset (reg_data , sign_byte , insn -> opnd_bytes );
974
+ memcpy (reg_data , ghcb -> shared_buffer , bytes );
1065
975
break ;
1066
- /* Two-Byte Opcodes */
1067
- case 0x0f :
1068
- ret = vc_handle_mmio_twobyte_ops (ghcb , ctxt );
976
+ case MMIO_MOVS :
977
+ ret = vc_handle_mmio_movs (ctxt , bytes );
1069
978
break ;
1070
979
default :
1071
980
ret = ES_UNSUPPORTED ;
981
+ break ;
1072
982
}
1073
983
1074
984
return ret ;
0 commit comments