|
1 | | -/* $Id: NEMR3Native-linux-x86.cpp 113168 2026-02-26 08:53:43Z alexander.eichner@oracle.com $ */ |
| 1 | +/* $Id: NEMR3Native-linux-x86.cpp 113606 2026-03-27 07:25:58Z alexander.eichner@oracle.com $ */ |
2 | 2 | /** @file |
3 | 3 | * NEM - Native execution manager, native ring-3 Linux backend. |
4 | 4 | */ |
@@ -692,42 +692,43 @@ static int nemHCLnxImportState(PVMCPUCC pVCpu, uint64_t fWhat, PCPUMCTX pCtx, st |
692 | 692 | /* |
693 | 693 | * FPU, SSE, AVX, ++. |
694 | 694 | */ |
| 695 | + if (fWhat & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE)) |
| 696 | + { |
| 697 | + fWhat |= CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE; /* we do all or nothing at all */ |
| 698 | + |
| 699 | + AssertCompile(sizeof(pCtx->XState) >= sizeof(struct kvm_xsave)); |
| 700 | + int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_GET_XSAVE, &pCtx->XState); |
| 701 | + AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3); |
| 702 | + } |
| 703 | + |
| 704 | + /* |
| 705 | + * XCRs. |
| 706 | + */ |
695 | 707 | bool fUpdateXcr0 = false; |
696 | 708 | uint64_t u64Xcr0 = 0; |
697 | | - if (fWhat & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx)) |
| 709 | + if ( pVM->nem.s.fXcrs |
| 710 | + && (fWhat & CPUMCTX_EXTRN_XCRx)) |
698 | 711 | { |
699 | | - if (fWhat & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE)) |
700 | | - { |
701 | | - fWhat |= CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE; /* we do all or nothing at all */ |
| 712 | + struct kvm_xcrs Xcrs = |
| 713 | + { /*.nr_xcrs = */ 2, |
| 714 | + /*.flags = */ 0, |
| 715 | + /*.xcrs= */ { |
| 716 | + { /*.xcr =*/ 0, /*.reserved=*/ 0, /*.value=*/ pCtx->aXcr[0] }, |
| 717 | + { /*.xcr =*/ 1, /*.reserved=*/ 0, /*.value=*/ pCtx->aXcr[1] }, |
| 718 | + } |
| 719 | + }; |
702 | 720 |
|
703 | | - AssertCompile(sizeof(pCtx->XState) >= sizeof(struct kvm_xsave)); |
704 | | - int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_GET_XSAVE, &pCtx->XState); |
705 | | - AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3); |
706 | | - } |
| 721 | + int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_GET_XCRS, &Xcrs); |
| 722 | + AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3); |
707 | 723 |
|
708 | | - if (fWhat & CPUMCTX_EXTRN_XCRx) |
| 724 | + if (pCtx->aXcr[0] != Xcrs.xcrs[0].value) |
709 | 725 | { |
710 | | - struct kvm_xcrs Xcrs = |
711 | | - { /*.nr_xcrs = */ 2, |
712 | | - /*.flags = */ 0, |
713 | | - /*.xcrs= */ { |
714 | | - { /*.xcr =*/ 0, /*.reserved=*/ 0, /*.value=*/ pCtx->aXcr[0] }, |
715 | | - { /*.xcr =*/ 1, /*.reserved=*/ 0, /*.value=*/ pCtx->aXcr[1] }, |
716 | | - } |
717 | | - }; |
718 | | - |
719 | | - int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_GET_XCRS, &Xcrs); |
720 | | - AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3); |
721 | | - |
722 | | - if (pCtx->aXcr[0] != Xcrs.xcrs[0].value) |
723 | | - { |
724 | | - u64Xcr0 = Xcrs.xcrs[0].value; |
725 | | - fUpdateXcr0 = true; |
726 | | - } |
727 | | - |
728 | | - /** @todo Same logic for XCR1 when it becomes necessary. */ |
729 | | - pCtx->aXcr[1] = Xcrs.xcrs[1].value; |
| 726 | + u64Xcr0 = Xcrs.xcrs[0].value; |
| 727 | + fUpdateXcr0 = true; |
730 | 728 | } |
| 729 | + |
| 730 | + /** @todo Same logic for XCR1 when it becomes necessary. */ |
| 731 | + pCtx->aXcr[1] = Xcrs.xcrs[1].value; |
731 | 732 | } |
732 | 733 |
|
733 | 734 | /* |
@@ -1150,33 +1151,34 @@ static int nemHCLnxExportState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, struct kvm_ |
1150 | 1151 | /* |
1151 | 1152 | * FPU, SSE, AVX, ++. |
1152 | 1153 | */ |
1153 | | - if (fExtrn & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx)) |
| 1154 | + if (fExtrn & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE)) |
1154 | 1155 | { |
1155 | | - if (fExtrn & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE)) |
1156 | | - { |
1157 | | - /** @todo could IEM just grab state partial control in some situations? */ |
1158 | | - Assert( (fExtrn & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE)) |
1159 | | - == (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE)); /* no partial states */ |
| 1156 | + /** @todo could IEM just grab state partial control in some situations? */ |
| 1157 | + Assert( (fExtrn & (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE)) |
| 1158 | + == (CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE)); /* no partial states */ |
1160 | 1159 |
|
1161 | | - AssertCompile(sizeof(pCtx->XState) >= sizeof(struct kvm_xsave)); |
1162 | | - int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_SET_XSAVE, &pCtx->XState); |
1163 | | - AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3); |
1164 | | - } |
| 1160 | + AssertCompile(sizeof(pCtx->XState) >= sizeof(struct kvm_xsave)); |
| 1161 | + int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_SET_XSAVE, &pCtx->XState); |
| 1162 | + AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3); |
| 1163 | + } |
1165 | 1164 |
|
1166 | | - if (fExtrn & CPUMCTX_EXTRN_XCRx) |
1167 | | - { |
1168 | | - struct kvm_xcrs Xcrs = |
1169 | | - { /*.nr_xcrs = */ 2, |
1170 | | - /*.flags = */ 0, |
1171 | | - /*.xcrs= */ { |
1172 | | - { /*.xcr =*/ 0, /*.reserved=*/ 0, /*.value=*/ pCtx->aXcr[0] }, |
1173 | | - { /*.xcr =*/ 1, /*.reserved=*/ 0, /*.value=*/ pCtx->aXcr[1] }, |
1174 | | - } |
1175 | | - }; |
| 1165 | + /* |
| 1166 | + * XCR. |
| 1167 | + */ |
| 1168 | + if ( pVM->nem.s.fXcrs |
| 1169 | + && (fExtrn & CPUMCTX_EXTRN_XCRx)) |
| 1170 | + { |
| 1171 | + struct kvm_xcrs Xcrs = |
| 1172 | + { /*.nr_xcrs = */ 2, |
| 1173 | + /*.flags = */ 0, |
| 1174 | + /*.xcrs= */ { |
| 1175 | + { /*.xcr =*/ 0, /*.reserved=*/ 0, /*.value=*/ pCtx->aXcr[0] }, |
| 1176 | + { /*.xcr =*/ 1, /*.reserved=*/ 0, /*.value=*/ pCtx->aXcr[1] }, |
| 1177 | + } |
| 1178 | + }; |
1176 | 1179 |
|
1177 | | - int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_SET_XCRS, &Xcrs); |
1178 | | - AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3); |
1179 | | - } |
| 1180 | + int rc = ioctl(pVCpu->nem.s.fdVCpu, KVM_SET_XCRS, &Xcrs); |
| 1181 | + AssertMsgReturn(rc == 0, ("rc=%d errno=%d\n", rc, errno), VERR_NEM_IPE_3); |
1180 | 1182 | } |
1181 | 1183 |
|
1182 | 1184 | /* |
|
0 commit comments