@@ -776,22 +776,6 @@ static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt)
776776 do_early_exception (ctxt -> regs , trapnr );
777777}
778778
779- static long * vc_insn_get_reg (struct es_em_ctxt * ctxt )
780- {
781- long * reg_array ;
782- int offset ;
783-
784- reg_array = (long * )ctxt -> regs ;
785- offset = insn_get_modrm_reg_off (& ctxt -> insn , ctxt -> regs );
786-
787- if (offset < 0 )
788- return NULL ;
789-
790- offset /= sizeof (long );
791-
792- return reg_array + offset ;
793- }
794-
795779static long * vc_insn_get_rm (struct es_em_ctxt * ctxt )
796780{
797781 long * reg_array ;
@@ -839,76 +823,6 @@ static enum es_result vc_do_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
839823 return sev_es_ghcb_hv_call (ghcb , true, ctxt , exit_code , exit_info_1 , exit_info_2 );
840824}
841825
842- static enum es_result vc_handle_mmio_twobyte_ops (struct ghcb * ghcb ,
843- struct es_em_ctxt * ctxt )
844- {
845- struct insn * insn = & ctxt -> insn ;
846- unsigned int bytes = 0 ;
847- enum es_result ret ;
848- int sign_byte ;
849- long * reg_data ;
850-
851- switch (insn -> opcode .bytes [1 ]) {
852- /* MMIO Read w/ zero-extension */
853- case 0xb6 :
854- bytes = 1 ;
855- fallthrough ;
856- case 0xb7 :
857- if (!bytes )
858- bytes = 2 ;
859-
860- ret = vc_do_mmio (ghcb , ctxt , bytes , true);
861- if (ret )
862- break ;
863-
864- /* Zero extend based on operand size */
865- reg_data = vc_insn_get_reg (ctxt );
866- if (!reg_data )
867- return ES_DECODE_FAILED ;
868-
869- memset (reg_data , 0 , insn -> opnd_bytes );
870-
871- memcpy (reg_data , ghcb -> shared_buffer , bytes );
872- break ;
873-
874- /* MMIO Read w/ sign-extension */
875- case 0xbe :
876- bytes = 1 ;
877- fallthrough ;
878- case 0xbf :
879- if (!bytes )
880- bytes = 2 ;
881-
882- ret = vc_do_mmio (ghcb , ctxt , bytes , true);
883- if (ret )
884- break ;
885-
886- /* Sign extend based on operand size */
887- reg_data = vc_insn_get_reg (ctxt );
888- if (!reg_data )
889- return ES_DECODE_FAILED ;
890-
891- if (bytes == 1 ) {
892- u8 * val = (u8 * )ghcb -> shared_buffer ;
893-
894- sign_byte = (* val & 0x80 ) ? 0xff : 0x00 ;
895- } else {
896- u16 * val = (u16 * )ghcb -> shared_buffer ;
897-
898- sign_byte = (* val & 0x8000 ) ? 0xff : 0x00 ;
899- }
900- memset (reg_data , sign_byte , insn -> opnd_bytes );
901-
902- memcpy (reg_data , ghcb -> shared_buffer , bytes );
903- break ;
904-
905- default :
906- ret = ES_UNSUPPORTED ;
907- }
908-
909- return ret ;
910- }
911-
912826/*
913827 * The MOVS instruction has two memory operands, which raises the
914828 * problem that it is not known whether the access to the source or the
@@ -976,83 +890,79 @@ static enum es_result vc_handle_mmio_movs(struct es_em_ctxt *ctxt,
976890 return ES_RETRY ;
977891}
978892
979- static enum es_result vc_handle_mmio (struct ghcb * ghcb ,
980- struct es_em_ctxt * ctxt )
893+ static enum es_result vc_handle_mmio (struct ghcb * ghcb , struct es_em_ctxt * ctxt )
981894{
982895 struct insn * insn = & ctxt -> insn ;
983896 unsigned int bytes = 0 ;
897+ enum mmio_type mmio ;
984898 enum es_result ret ;
899+ u8 sign_byte ;
985900 long * reg_data ;
986901
987- switch (insn -> opcode .bytes [0 ]) {
988- /* MMIO Write */
989- case 0x88 :
990- bytes = 1 ;
991- fallthrough ;
992- case 0x89 :
993- if (!bytes )
994- bytes = insn -> opnd_bytes ;
902+ mmio = insn_decode_mmio (insn , & bytes );
903+ if (mmio == MMIO_DECODE_FAILED )
904+ return ES_DECODE_FAILED ;
995905
996- reg_data = vc_insn_get_reg (ctxt );
906+ if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS ) {
907+ reg_data = insn_get_modrm_reg_ptr (insn , ctxt -> regs );
997908 if (!reg_data )
998909 return ES_DECODE_FAILED ;
910+ }
999911
912+ switch (mmio ) {
913+ case MMIO_WRITE :
1000914 memcpy (ghcb -> shared_buffer , reg_data , bytes );
1001-
1002915 ret = vc_do_mmio (ghcb , ctxt , bytes , false);
1003916 break ;
1004-
1005- case 0xc6 :
1006- bytes = 1 ;
1007- fallthrough ;
1008- case 0xc7 :
1009- if (!bytes )
1010- bytes = insn -> opnd_bytes ;
1011-
917+ case MMIO_WRITE_IMM :
1012918 memcpy (ghcb -> shared_buffer , insn -> immediate1 .bytes , bytes );
1013-
1014919 ret = vc_do_mmio (ghcb , ctxt , bytes , false);
1015920 break ;
1016-
1017- /* MMIO Read */
1018- case 0x8a :
1019- bytes = 1 ;
1020- fallthrough ;
1021- case 0x8b :
1022- if (!bytes )
1023- bytes = insn -> opnd_bytes ;
1024-
921+ case MMIO_READ :
1025922 ret = vc_do_mmio (ghcb , ctxt , bytes , true);
1026923 if (ret )
1027924 break ;
1028925
1029- reg_data = vc_insn_get_reg (ctxt );
1030- if (!reg_data )
1031- return ES_DECODE_FAILED ;
1032-
1033926 /* Zero-extend for 32-bit operation */
1034927 if (bytes == 4 )
1035928 * reg_data = 0 ;
1036929
1037930 memcpy (reg_data , ghcb -> shared_buffer , bytes );
1038931 break ;
932+ case MMIO_READ_ZERO_EXTEND :
933+ ret = vc_do_mmio (ghcb , ctxt , bytes , true);
934+ if (ret )
935+ break ;
936+
937+ /* Zero extend based on operand size */
938+ memset (reg_data , 0 , insn -> opnd_bytes );
939+ memcpy (reg_data , ghcb -> shared_buffer , bytes );
940+ break ;
941+ case MMIO_READ_SIGN_EXTEND :
942+ ret = vc_do_mmio (ghcb , ctxt , bytes , true);
943+ if (ret )
944+ break ;
1039945
1040- /* MOVS instruction */
1041- case 0xa4 :
1042- bytes = 1 ;
1043- fallthrough ;
1044- case 0xa5 :
1045- if (!bytes )
1046- bytes = insn -> opnd_bytes ;
946+ if (bytes == 1 ) {
947+ u8 * val = (u8 * )ghcb -> shared_buffer ;
1047948
1048- ret = vc_handle_mmio_movs (ctxt , bytes );
949+ sign_byte = (* val & 0x80 ) ? 0xff : 0x00 ;
950+ } else {
951+ u16 * val = (u16 * )ghcb -> shared_buffer ;
952+
953+ sign_byte = (* val & 0x8000 ) ? 0xff : 0x00 ;
954+ }
955+
956+ /* Sign extend based on operand size */
957+ memset (reg_data , sign_byte , insn -> opnd_bytes );
958+ memcpy (reg_data , ghcb -> shared_buffer , bytes );
1049959 break ;
1050- /* Two-Byte Opcodes */
1051- case 0x0f :
1052- ret = vc_handle_mmio_twobyte_ops (ghcb , ctxt );
960+ case MMIO_MOVS :
961+ ret = vc_handle_mmio_movs (ctxt , bytes );
1053962 break ;
1054963 default :
1055964 ret = ES_UNSUPPORTED ;
965+ break ;
1056966 }
1057967
1058968 return ret ;
0 commit comments