diff --git a/include/os/windows/spl/sys/simd.h b/include/os/windows/spl/sys/simd.h index ed46cabd3770..cf13da1ceab0 100644 --- a/include/os/windows/spl/sys/simd.h +++ b/include/os/windows/spl/sys/simd.h @@ -116,6 +116,14 @@ extern uint32_t kfpu_state; if (NT_SUCCESS(saveStatus)) \ KeRestoreExtendedProcessorState(&SaveState); +#define kfpu_begin_ctx(O) \ + (O)->saveStatus = \ + KeSaveExtendedProcessorState(kfpu_state, &(O)->SaveState); + +#define kfpu_end_ctx(O) \ + if (NT_SUCCESS(((O)->saveStatus))) \ + KeRestoreExtendedProcessorState(&(O)->SaveState); + /* * CPUID feature tests for user-space. Linux kernel provides an interface for * CPU feature testing. diff --git a/include/sys/zio_checksum.h b/include/sys/zio_checksum.h index 9fb79ab4a54b..b00deb290e46 100644 --- a/include/sys/zio_checksum.h +++ b/include/sys/zio_checksum.h @@ -69,6 +69,10 @@ typedef struct zio_abd_checksum_data { fletcher_4_ctx_t *acd_ctx; zio_cksum_t *acd_zcp; void *acd_private; +#if defined(_WIN32) && defined(_KERNEL) + NTSTATUS saveStatus; + XSTATE_SAVE SaveState; +#endif } zio_abd_checksum_data_t; typedef void zio_abd_checksum_init_t(zio_abd_checksum_data_t *); diff --git a/module/zcommon/zfs_fletcher.c b/module/zcommon/zfs_fletcher.c index fa65f4c584dc..3c23ddd99d88 100644 --- a/module/zcommon/zfs_fletcher.c +++ b/module/zcommon/zfs_fletcher.c @@ -457,12 +457,14 @@ fletcher_4_native_impl(const void *buf, uint64_t size, zio_cksum_t *zcp) if (ops->uses_fpu == B_TRUE) { kfpu_begin(); - } - ops->init_native(&ctx); - ops->compute_native(&ctx, buf, size); - ops->fini_native(&ctx, zcp); - if (ops->uses_fpu == B_TRUE) { + ops->init_native(&ctx); + ops->compute_native(&ctx, buf, size); + ops->fini_native(&ctx, zcp); kfpu_end(); + } else { + ops->init_native(&ctx); + ops->compute_native(&ctx, buf, size); + ops->fini_native(&ctx, zcp); } } @@ -505,12 +507,14 @@ fletcher_4_byteswap_impl(const void *buf, uint64_t size, zio_cksum_t *zcp) if (ops->uses_fpu == B_TRUE) { kfpu_begin(); - } - ops->init_byteswap(&ctx); - ops->compute_byteswap(&ctx, buf, size); - ops->fini_byteswap(&ctx, zcp); - if (ops->uses_fpu == B_TRUE) { + ops->init_byteswap(&ctx); + ops->compute_byteswap(&ctx, buf, size); + ops->fini_byteswap(&ctx, zcp); kfpu_end(); + } else { + ops->init_byteswap(&ctx); + ops->compute_byteswap(&ctx, buf, size); + ops->fini_byteswap(&ctx, zcp); } } @@ -827,7 +831,11 @@ abd_fletcher_4_init(zio_abd_checksum_data_t *cdp) cdp->acd_private = (void *) ops; if (ops->uses_fpu == B_TRUE) { +#if defined(_WIN32) && defined(_KERNEL) + kfpu_begin_ctx(cdp); +#else kfpu_begin(); +#endif } if (cdp->acd_byteorder == ZIO_CHECKSUM_NATIVE) ops->init_native(cdp->acd_ctx); @@ -849,7 +857,11 @@ abd_fletcher_4_fini(zio_abd_checksum_data_t *cdp) ops->fini_byteswap(cdp->acd_ctx, cdp->acd_zcp); if (ops->uses_fpu == B_TRUE) { +#if defined(_WIN32) && defined(_KERNEL) + kfpu_end_ctx(cdp); +#else kfpu_end(); +#endif } }