@@ -776,22 +776,6 @@ static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt)
776
776
do_early_exception (ctxt -> regs , trapnr );
777
777
}
778
778
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
-
795
779
static long * vc_insn_get_rm (struct es_em_ctxt * ctxt )
796
780
{
797
781
long * reg_array ;
@@ -839,76 +823,6 @@ static enum es_result vc_do_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
839
823
return sev_es_ghcb_hv_call (ghcb , true, ctxt , exit_code , exit_info_1 , exit_info_2 );
840
824
}
841
825
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
-
912
826
/*
913
827
* The MOVS instruction has two memory operands, which raises the
914
828
* 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,
976
890
return ES_RETRY ;
977
891
}
978
892
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 )
981
894
{
982
895
struct insn * insn = & ctxt -> insn ;
983
896
unsigned int bytes = 0 ;
897
+ enum mmio_type mmio ;
984
898
enum es_result ret ;
899
+ u8 sign_byte ;
985
900
long * reg_data ;
986
901
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 ;
995
905
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 );
997
908
if (!reg_data )
998
909
return ES_DECODE_FAILED ;
910
+ }
999
911
912
+ switch (mmio ) {
913
+ case MMIO_WRITE :
1000
914
memcpy (ghcb -> shared_buffer , reg_data , bytes );
1001
-
1002
915
ret = vc_do_mmio (ghcb , ctxt , bytes , false);
1003
916
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 :
1012
918
memcpy (ghcb -> shared_buffer , insn -> immediate1 .bytes , bytes );
1013
-
1014
919
ret = vc_do_mmio (ghcb , ctxt , bytes , false);
1015
920
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 :
1025
922
ret = vc_do_mmio (ghcb , ctxt , bytes , true);
1026
923
if (ret )
1027
924
break ;
1028
925
1029
- reg_data = vc_insn_get_reg (ctxt );
1030
- if (!reg_data )
1031
- return ES_DECODE_FAILED ;
1032
-
1033
926
/* Zero-extend for 32-bit operation */
1034
927
if (bytes == 4 )
1035
928
* reg_data = 0 ;
1036
929
1037
930
memcpy (reg_data , ghcb -> shared_buffer , bytes );
1038
931
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 ;
1039
945
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 ;
1047
948
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 );
1049
959
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 );
1053
962
break ;
1054
963
default :
1055
964
ret = ES_UNSUPPORTED ;
965
+ break ;
1056
966
}
1057
967
1058
968
return ret ;
0 commit comments