@@ -792,22 +792,6 @@ static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt)
792792 do_early_exception (ctxt -> regs , trapnr );
793793}
794794
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-
811795static long * vc_insn_get_rm (struct es_em_ctxt * ctxt )
812796{
813797 long * reg_array ;
@@ -855,76 +839,6 @@ static enum es_result vc_do_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
855839 return sev_es_ghcb_hv_call (ghcb , true, ctxt , exit_code , exit_info_1 , exit_info_2 );
856840}
857841
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-
928842/*
929843 * The MOVS instruction has two memory operands, which raises the
930844 * 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,
992906 return ES_RETRY ;
993907}
994908
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 )
997910{
998911 struct insn * insn = & ctxt -> insn ;
999912 unsigned int bytes = 0 ;
913+ enum mmio_type mmio ;
1000914 enum es_result ret ;
915+ u8 sign_byte ;
1001916 long * reg_data ;
1002917
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 ;
1011921
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 );
1013924 if (!reg_data )
1014925 return ES_DECODE_FAILED ;
926+ }
1015927
928+ switch (mmio ) {
929+ case MMIO_WRITE :
1016930 memcpy (ghcb -> shared_buffer , reg_data , bytes );
1017-
1018931 ret = vc_do_mmio (ghcb , ctxt , bytes , false);
1019932 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 :
1028934 memcpy (ghcb -> shared_buffer , insn -> immediate1 .bytes , bytes );
1029-
1030935 ret = vc_do_mmio (ghcb , ctxt , bytes , false);
1031936 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 :
1041938 ret = vc_do_mmio (ghcb , ctxt , bytes , true);
1042939 if (ret )
1043940 break ;
1044941
1045- reg_data = vc_insn_get_reg (ctxt );
1046- if (!reg_data )
1047- return ES_DECODE_FAILED ;
1048-
1049942 /* Zero-extend for 32-bit operation */
1050943 if (bytes == 4 )
1051944 * reg_data = 0 ;
1052945
1053946 memcpy (reg_data , ghcb -> shared_buffer , bytes );
1054947 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 ;
1055961
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 ;
1063964
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 );
1065975 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 );
1069978 break ;
1070979 default :
1071980 ret = ES_UNSUPPORTED ;
981+ break ;
1072982 }
1073983
1074984 return ret ;
0 commit comments