diff --git a/doc/Makefile b/doc/Makefile
index 1c03ab892e15b2b998621be2bf04039d01e86d48..051b840576cc2ca1fd1434ca82570524f107d03d 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -101,7 +101,7 @@ MANPAGES_3_MD_PMEM2 = libpmem2/pmem2_errormsg.3.md libpmem2/pmem2_config_new.3.m
 		libpmem2/pmem2_config_set_length.3.md libpmem2/pmem2_config_set_offset.3.md \
 		libpmem2/pmem2_map_get_store_granularity.3.md libpmem2/pmem2_get_flush_fn.3.md \
 		libpmem2/pmem2_get_drain_fn.3.md libpmem2/pmem2_get_persist_fn.3.md \
-		libpmem2/pmem2_perror.3.md libpmem2/pmem2_get_memmove_fn.3.md libpmem2/pmem2_memcpy_async.3.md\
+		libpmem2/pmem2_perror.3.md libpmem2/pmem2_get_memmove_fn.3.md libpmem2/pmem2_async.3.md\
 		libpmem2/pmem2_config_set_sharing.3.md libpmem2/pmem2_config_set_vm_reservation.3.md libpmem2/pmem2_vm_reservation_new.3.md \
 		libpmem2/pmem2_vm_reservation_get_address.3.md libpmem2/pmem2_vm_reservation_get_size.3.md \
 		libpmem2/pmem2_badblock_context_new.3.md libpmem2/pmem2_badblock_next.3.md \
@@ -114,7 +114,8 @@ MANPAGES_3_MD_PMEM2 = libpmem2/pmem2_errormsg.3.md libpmem2/pmem2_config_new.3.m
 
 MANPAGES_1_MD_PMEM2 =
 MANPAGES_3_DUMMY += libpmem2/pmem2_config_delete.3 libpmem2/pmem2_config_set_vdm.3 libpmem2/pmem2_source_from_handle.3 libpmem2/pmem2_source_delete.3 \
-	libpmem2/pmem2_get_memset_fn.3 libpmem2/pmem2_get_memcpy_fn.3 libpmem2/pmem2_vm_reservation_delete.3 \
+	libpmem2/pmem2_get_memset_fn.3 libpmem2/pmem2_get_memcpy_fn.3 libpmem2/pmem2_memcpy_async.3 libpmem2/pmem2_memmove_async.3 \
+	libpmem2/pmem2_memset_async.3 libpmem2/pmem2_vm_reservation_delete.3 \
 	libpmem2/pmem2_badblock_context_delete.3 libpmem2/pmem2_vm_reservation_shrink.3 \
 	libpmem2/pmem2_vm_reservation_map_find_first.3 libpmem2/pmem2_vm_reservation_map_find_last.3 \
 	libpmem2/pmem2_vm_reservation_map_find_next.3 libpmem2/pmem2_vm_reservation_map_find_prev.3 \
diff --git a/doc/libpmem2/.gitignore b/doc/libpmem2/.gitignore
index a1b3a358cfaeb4aed5e47516d620811a27b0cd1c..55ed800f212fabcef23dcfc85ae21dfe854437f3 100644
--- a/doc/libpmem2/.gitignore
+++ b/doc/libpmem2/.gitignore
@@ -22,7 +22,7 @@ pmem2_map_new.3
 pmem2_map_get_address.3
 pmem2_map_get_size.3
 pmem2_map_get_store_granularity.3
-pmem2_memcpy_async.3
+pmem2_async.3
 pmem2_source_alignment.3
 pmem2_source_from_fd.3
 pmem2_source_from_anon.3
diff --git a/doc/libpmem2/pmem2_memcpy_async.3.md b/doc/libpmem2/pmem2_async.3.md
similarity index 50%
rename from doc/libpmem2/pmem2_memcpy_async.3.md
rename to doc/libpmem2/pmem2_async.3.md
index 050813bca51f761574a5118f1f5618faaab14b65..d7f1e654fbd4bb9718d19b0d1f933015650c5dda 100644
--- a/doc/libpmem2/pmem2_memcpy_async.3.md
+++ b/doc/libpmem2/pmem2_async.3.md
@@ -1,7 +1,7 @@
 ---
 layout: manual
 Content-Style: 'text/css'
-title: _MP(PMEM2_MEMCPY_ASYNC, 3)
+title: _MP(PMEM2_ASYNC, 3)
 collection: libpmem2
 header: PMDK
 date: pmem2 API version 1.0
@@ -10,7 +10,7 @@ date: pmem2 API version 1.0
 [comment]: <> (SPDX-License-Identifier: BSD-3-Clause
 [comment]: <> (Copyright 2022, Intel Corporation)
 
-[comment]: <> (pmem2_memcpy_async.3 -- man page for pmem2_memcpy_async)
+[comment]: <> (pmem2_async.3 -- man page for pmem2_async operations)
 
 [NAME](#name)<br />
 [SYNOPSIS](#synopsis)<br />
@@ -19,7 +19,7 @@ date: pmem2 API version 1.0
 [SEE ALSO](#see-also)<br />
 
 # NAME #
-**pmem2_config_set_vdm**(), **pmem2_memcpy_async**() - asynchronous data movement operations
+**pmem2_config_set_vdm**(), **pmem2_memcpy_async**(), **pmem2_memmove_async**(), **pmem2_memset_async**() - asynchronous data movement operations
 
 # SYNOPSIS #
 
@@ -30,6 +30,13 @@ int pmem2_config_set_vdm(struct pmem2_config *cfg, struct vdm *vdm);
 
 struct vdm_operation_future pmem2_memcpy_async(struct pmem2_map *map,
 	void *pmemdest, const void *src, size_t len, unsigned flags);
+
+pmem2_memmove_async(struct pmem2_map *map, void *pmemdest, const void *src,
+	size_t len, unsigned flags)
+
+struct vdm_operation_future pmem2_memset_async(struct pmem2_map *map,
+	void *pmemstr,	int c, size_t n, unsigned flags)
+{
 ```
 
 # DESCRIPTION #
@@ -37,19 +44,29 @@ To use those functions, you must have *libminiasync* installed. Those functions
 and vdm (virtual data mover) concepts from this library. Please check **miniasync**(7) for more details.
 
 The **pmem2_config_set_vdm** sets a vdm structure in the *pmem2_config*.
-This structure will be used by pmem2_memcpy_async function, to create a *vdm_operation_future*.
+This structure will be used by pmem2_*_async functions, to create a *vdm_operation_future*.
 If vdm is not set in the config, pmem2_map_new will use a default one which uses a
 pmem2 memory movement functions to perform memory operations. (**pmem2_get_memcpy_fn**(3), **pmem2_get_memmove_fn**(3), **pmem2_get_memsety_fn**(3)).
 
-The **pmem2_memcpy_async** uses *vdm* structure held inside of the *pmem2_map* structure to initialise and return **vdm_operation_future**.
-This future will perform memcpy operation from *vdm* to copy *len* bytes from *src* to *pmemdest*. In the current implementation *flags* are ignored.
+The **pmem2_memcpy_async** uses *vdm* structure held inside the *pmem2_map* structure to initialise and returns **vdm_operation_future**.
+This future will perform memcpy operation defined in *vdm* to copy *len* bytes from *src* to *pmemdest*. In the current implementation *flags* are ignored.
 
-# RETURN VALUE #
+The **pmem2_memmove_async** returns **vdm_operation_future** which
+will perform memmove operation defined in *vdm* to copy *len* bytes from *src* to *pmemdest*. In the current implementation *flags* are ignored.
+
+The **pmem2_memmset_async** returns **vdm_operation_future** which
+will perform memset operation defined in *vdm* to fill *n* bytes from *pmemstr* with value of int *c* interpreted as unsigned char.
+In the current implementation *flags* are ignored.
 
+# RETURN VALUE #
 The **pmem2_config_set_vdm** always return 0.
 
-The **pmem2_memcpy_async** returns a new instance of **vdm_operation_future** which will copy *len* bytes from *src* to *pmemdest*.
-You can execute returned structure using methods from the **libminiasync**() library.
+The **pmem2_memcpy_async** returns a new instance of **vdm_operation_future** performing memcpy operation.
+You can execute returned structure using methods from the **libminiasync**() library such as **FUTURE_BUSY_POLL**(3).
+
+The **pmem2_memmove_async** returns a new instance of **vdm_operation_future** performing memmove operation.
+
+The **pmem2_memset_async** returns a new instance of **vdm_operation_future** performing memset operation.
 
 # SEE ALSO #
 
diff --git a/doc/libpmem2/pmem2_config_set_vdm.3 b/doc/libpmem2/pmem2_config_set_vdm.3
index 8e81274f85cd1576b8bc70188ae53d6c0d5fa9cd..3fd41779c0b6e0dd305488e88ca6c164074c920e 100644
--- a/doc/libpmem2/pmem2_config_set_vdm.3
+++ b/doc/libpmem2/pmem2_config_set_vdm.3
@@ -1 +1 @@
-.so pmem2_memcpy_async.3
+.so pmem2_async.3
diff --git a/doc/libpmem2/pmem2_memcpy_async.3 b/doc/libpmem2/pmem2_memcpy_async.3
new file mode 100644
index 0000000000000000000000000000000000000000..3fd41779c0b6e0dd305488e88ca6c164074c920e
--- /dev/null
+++ b/doc/libpmem2/pmem2_memcpy_async.3
@@ -0,0 +1 @@
+.so pmem2_async.3
diff --git a/doc/libpmem2/pmem2_memmove_async.3 b/doc/libpmem2/pmem2_memmove_async.3
new file mode 100644
index 0000000000000000000000000000000000000000..3fd41779c0b6e0dd305488e88ca6c164074c920e
--- /dev/null
+++ b/doc/libpmem2/pmem2_memmove_async.3
@@ -0,0 +1 @@
+.so pmem2_async.3
diff --git a/doc/libpmem2/pmem2_memset_async.3 b/doc/libpmem2/pmem2_memset_async.3
new file mode 100644
index 0000000000000000000000000000000000000000..3fd41779c0b6e0dd305488e88ca6c164074c920e
--- /dev/null
+++ b/doc/libpmem2/pmem2_memset_async.3
@@ -0,0 +1 @@
+.so pmem2_async.3
diff --git a/src/include/libpmem2.h b/src/include/libpmem2.h
index 162c336dfed5dcefd311fcf70dc3d25b27f1b41d..c880ce64b4f6418273ef124e005a154c84f959d1 100644
--- a/src/include/libpmem2.h
+++ b/src/include/libpmem2.h
@@ -282,6 +282,12 @@ int pmem2_config_set_vdm(struct pmem2_config *cfg, struct vdm *vdm);
 
 struct vdm_operation_future pmem2_memcpy_async(struct pmem2_map *map,
 	void *pmemdest, const void *src, size_t len, unsigned flags);
+
+struct vdm_operation_future pmem2_memmove_async(struct pmem2_map *map,
+    void *pmemdest, const void *src, size_t len, unsigned flags);
+
+struct vdm_operation_future pmem2_memset_async(struct pmem2_map *map,
+    void *str, int c, size_t n, unsigned flags);
 #endif
 
 /* error handling */
diff --git a/src/libpmem2/libpmem2.def b/src/libpmem2/libpmem2.def
index 47692d2bfbcc43bbcbc69fef299fa5f08d11fd9a..ab809738e58a61e2d5ae986fbc8413fc95b3ea11 100644
--- a/src/libpmem2/libpmem2.def
+++ b/src/libpmem2/libpmem2.def
@@ -37,6 +37,8 @@ EXPORTS
 	pmem2_map_from_existing
 	pmem2_map_new
 	pmem2_memcpy_async
+	pmem2_memmove_async
+	pmem2_memset_async
 	pmem2_perrorU
 	pmem2_perrorW
 	pmem2_source_alignment
diff --git a/src/libpmem2/libpmem2.link.in b/src/libpmem2/libpmem2.link.in
index 1e59becc84223b50920a19ec83baec67969b19c1..5c0be977b3ba0166ba34c2c2bde4613f60b405e0 100644
--- a/src/libpmem2/libpmem2.link.in
+++ b/src/libpmem2/libpmem2.link.in
@@ -34,6 +34,8 @@ LIBPMEM2_1.0 {
 		pmem2_map_new;
 		pmem2_map_from_existing;
 		pmem2_memcpy_async;
+		pmem2_memmove_async;
+		pmem2_memset_async;
 		pmem2_perror;
 		pmem2_source_alignment;
 		pmem2_source_delete;
diff --git a/src/libpmem2/mover.c b/src/libpmem2/mover.c
index f57549d2c88ae85726ccc6da99bebe4423b9daf4..5a7157d0582abcde3e07aa667cff313e1e5e9025 100644
--- a/src/libpmem2/mover.c
+++ b/src/libpmem2/mover.c
@@ -41,7 +41,7 @@ sync_operation_check(void *data, const struct vdm_operation *operation)
 
 	int complete;
 	util_atomic_load_explicit32(&sync_op->complete, &complete,
-		memory_order_acquire);
+				    memory_order_acquire);
 
 	return complete ? FUTURE_STATE_COMPLETE : FUTURE_STATE_IDLE;
 }
@@ -57,8 +57,8 @@ sync_operation_new(struct vdm *vdm, const enum vdm_operation_type type)
 	SUPPRESS_UNUSED(type);
 
 	struct data_mover *vdm_sync = (struct data_mover *)vdm;
-	struct data_mover_op *sync_op = membuf_alloc(vdm_sync->membuf,
-		sizeof(struct data_mover_op));
+	struct data_mover_op *sync_op =
+		membuf_alloc(vdm_sync->membuf, sizeof(struct data_mover_op));
 
 	if (sync_op == NULL)
 		return NULL;
@@ -73,24 +73,27 @@ sync_operation_new(struct vdm *vdm, const enum vdm_operation_type type)
  */
 static void
 sync_operation_delete(void *data, const struct vdm_operation *operation,
-	struct vdm_operation_output *output)
+			struct vdm_operation_output *output)
 {
 	output->result = VDM_SUCCESS;
 
 	switch (operation->type) {
-	case VDM_OPERATION_MEMCPY:
-		output->type = VDM_OPERATION_MEMCPY;
-		output->output.memcpy.dest =
-			operation->data.memcpy.dest;
-		break;
-	case VDM_OPERATION_MEMMOVE:
-		output->type = VDM_OPERATION_MEMMOVE;
-		output->output.memmove.dest =
-			operation->data.memcpy.dest;
-		break;
-	default:
-		FATAL("unsupported operation type");
-
+		case VDM_OPERATION_MEMCPY:
+			output->type = VDM_OPERATION_MEMCPY;
+			output->output.memcpy.dest =
+				operation->data.memcpy.dest;
+			break;
+		case VDM_OPERATION_MEMMOVE:
+			output->type = VDM_OPERATION_MEMMOVE;
+			output->output.memmove.dest =
+				operation->data.memcpy.dest;
+			break;
+		case VDM_OPERATION_MEMSET:
+			output->type = VDM_OPERATION_MEMSET;
+			output->output.memset.str = operation->data.memset.str;
+			break;
+		default:
+			FATAL("unsupported operation type");
 	}
 	membuf_free(data);
 }
@@ -100,11 +103,10 @@ sync_operation_delete(void *data, const struct vdm_operation *operation,
  */
 static int
 sync_operation_start(void *data, const struct vdm_operation *operation,
-	struct future_notifier *n)
+			struct future_notifier *n)
 {
 	LOG(3, "data %p op %p, notifier %p", data, operation, n);
-	struct data_mover_op *sync_data =
-		(struct data_mover_op *)data;
+	struct data_mover_op *sync_data = (struct data_mover_op *)data;
 	struct data_mover *mover = membuf_ptr_user_data(data);
 	if (n)
 		n->notifier_used = FUTURE_NOTIFIER_NONE;
@@ -130,11 +132,21 @@ sync_operation_start(void *data, const struct vdm_operation *operation,
 				PMEM2_F_MEM_NONTEMPORAL);
 			break;
 		}
+		case VDM_OPERATION_MEMSET: {
+			pmem2_memset_fn memset_fn;
+			memset_fn = pmem2_get_memset_fn(mover->map);
+
+			memset_fn(operation->data.memset.str,
+				operation->data.memset.c,
+				operation->data.memset.n,
+				PMEM2_F_MEM_NONTEMPORAL);
+			break;
+		}
 		default:
 			FATAL("unsupported operation type");
 	}
-	util_atomic_store_explicit32(&sync_data->complete,
-		1, memory_order_release);
+	util_atomic_store_explicit32(&sync_data->complete, 1,
+					memory_order_release);
 
 	return 0;
 }
@@ -189,11 +201,37 @@ mover_delete(struct vdm *dms)
  * pmem2_memcpy_async -- returns a memcpy future
  */
 struct vdm_operation_future
-pmem2_memcpy_async(struct pmem2_map *map,
-	void *pmemdest,	const void *src, size_t len, unsigned flags)
+pmem2_memcpy_async(struct pmem2_map *map, void *pmemdest, const void *src,
+			size_t len, unsigned flags)
 {
-	LOG(3, "map %p, pmemdest %p, src %p, len %" PRIu64 ", flags %u",
-		map, pmemdest, src, len, flags);
+	LOG(3, "map %p, pmemdest %p, src %p, len %" PRIu64 ", flags %u", map,
+		pmemdest, src, len, flags);
 	SUPPRESS_UNUSED(flags);
 	return vdm_memcpy(map->vdm, pmemdest, (void *)src, len, 0);
 }
+
+/*
+ * pmem2_memove_async -- returns a memmove future
+ */
+struct vdm_operation_future
+pmem2_memmove_async(struct pmem2_map *map, void *pmemdest, const void *src,
+			size_t len, unsigned flags)
+{
+	LOG(3, "map %p, pmemdest %p, src %p, len %" PRIu64 ", flags %u", map,
+		pmemdest, src, len, flags);
+	SUPPRESS_UNUSED(flags);
+	return vdm_memmove(map->vdm, pmemdest, (void *)src, len, 0);
+}
+
+/*
+ * pmem2_memset_async -- returns a memset future
+ */
+struct vdm_operation_future
+pmem2_memset_async(struct pmem2_map *map, void *pmemstr, int c, size_t n,
+			unsigned flags)
+{
+	LOG(3, "map %p, pmemstr %p, c %d, len %" PRIu64 ", flags %u", map,
+		pmemstr, c, n, flags);
+	SUPPRESS_UNUSED(flags);
+	return vdm_memset(map->vdm, pmemstr, c, n, 0);
+}
diff --git a/src/test/pmem2_mover/TESTS.py b/src/test/pmem2_mover/TESTS.py
index e0243780a6779904d0bac1ba549a466f881897bf..90c358453e05149f842caaf6465ebfd71719d7a1 100644
--- a/src/test/pmem2_mover/TESTS.py
+++ b/src/test/pmem2_mover/TESTS.py
@@ -40,22 +40,56 @@ class PMEM2_MOVER_MT(PMEM2_MOVER):
 
 
 class TEST0(PMEM2_MOVER):
-    """verify pmem2 mover functionality"""
-    test_case = "test_mover_basic"
+    """verify pmem2 mover memcpy functionality"""
+    test_case = "test_mover_memcpy_basic"
+
+
+class TEST1(PMEM2_MOVER):
+    """verify pmem2 mover memmove functionality"""
+    test_case = "test_mover_memmove_basic"
+
+
+class TEST2(PMEM2_MOVER):
+    """verify pmem2 mover memset functionality"""
+    test_case = "test_mover_memset_basic"
+
+
+class TEST3(PMEM2_MOVER_MT):
+    """verify pmem2 mover multi-threaded memcpy functionality"""
+    test_case = "test_mover_memcpy_multithreaded"
+
+
+class TEST4(PMEM2_MOVER_MT):
+    """verify pmem2 mover multi-threaded memmove functionality"""
+    test_case = "test_mover_memmove_multithreaded"
 
 
-class TEST1(PMEM2_MOVER_MT):
-    """verify pmem2 mover multi-threaded functionality"""
-    test_case = "test_mover_multithreaded"
+class TEST5(PMEM2_MOVER_MT):
+    """verify pmem2 mover multi-threaded memset functionality"""
+    test_case = "test_mover_memset_multithreaded"
+
+
+class TEST6(PMEM2_MOVER_MT):
+    test_type = t.Long
+    thread_num = 16
+    """verify pmem2 mover multi-threaded memcpy functionality (Long)"""
+    test_case = "test_mover_memcpy_multithreaded"
+
+
+class TEST7(PMEM2_MOVER_MT):
+    test_type = t.Long
+    thread_num = 16
+    """verify pmem2 mover multi-threaded memmove functionality (Long)"""
+    test_case = "test_mover_memmove_multithreaded"
 
 
-class TEST2(PMEM2_MOVER_MT):
+class TEST8(PMEM2_MOVER_MT):
     test_type = t.Long
     thread_num = 16
-    """verify pmem2 mover multi-threaded functionality (Long)"""
-    test_case = "test_mover_multithreaded"
+    """verify pmem2 mover multi-threaded memset functionality (Long)"""
+    test_case = "test_mover_memset_multithreaded"
 
 
-class TEST3(PMEM2_MOVER):
+class TEST9(PMEM2_MOVER):
     """verify pmem2 mover functionality"""
     test_case = "test_miniasync_mover"
diff --git a/src/test/pmem2_mover/pmem2_mover.c b/src/test/pmem2_mover/pmem2_mover.c
index 99db7807b692bee29100acd8fd5240565e52f7d5..7602ab2c7db58c08aa6c34693ddbd8e88e53f35d 100644
--- a/src/test/pmem2_mover/pmem2_mover.c
+++ b/src/test/pmem2_mover/pmem2_mover.c
@@ -6,12 +6,14 @@
  */
 
 #define PMEM2_USE_MINIASYNC 1
+
 #include "libpmem2.h"
 #include "unittest.h"
 #include "ut_pmem2.h"
 #include "ut_pmem2_setup_integration.h"
 
 #include <libminiasync.h>
+
 /*
  * map_valid -- return valid mapped pmem2_map
  */
@@ -27,13 +29,13 @@ map_valid(struct pmem2_config *cfg, struct pmem2_source *src)
 }
 
 /*
- * test_mover_basic -- test basic functionality of pmem2 default mover
+ * test_mover_memcpy_basic -- test basic functionality of pmem2 default mover
  */
 static int
-test_mover_basic(const struct test_case *tc, int argc, char *argv[])
+test_mover_memcpy_basic(const struct test_case *tc, int argc, char *argv[])
 {
 	if (argc < 1)
-		UT_FATAL("usage: test_mover_basic <file>");
+		UT_FATAL("usage: test_mover_memcpy_basic <file>");
 
 	char *file = argv[0];
 	int fd = OPEN(file, O_RDWR);
@@ -63,20 +65,124 @@ test_mover_basic(const struct test_case *tc, int argc, char *argv[])
 	return 1;
 }
 
+/*
+ * test_mover_memmove_basic -- test memmove functionality of the default mover
+ * using two overlapping buffers: [1,2,3,4,0,0] -> [1,2,1,2,3,4]
+ *                                 A   B            A   B
+ */
+static int
+test_mover_memmove_basic(const struct test_case *tc, int argc, char *argv[])
+{
+	if (argc < 1)
+		UT_FATAL("usage: test_mover_memmove_basic <file>");
+
+	char *file = argv[0];
+	int fd = OPEN(file, O_RDWR);
+	unsigned string_size = 255;
+
+	struct pmem2_source *src;
+	struct pmem2_config *cfg;
+	PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd,
+		PMEM2_GRANULARITY_PAGE);
+
+	struct pmem2_map *map = map_valid(cfg, src);
+	char *data = pmem2_map_get_address(map);
+	pmem2_memcpy_fn pmem2_memcpy = pmem2_get_memcpy_fn(map);
+
+	/*
+	 * Create data for first buffer
+	 */
+	char *buffer_data = malloc(string_size);
+	for (unsigned i = 0; i < string_size; i++) {
+		buffer_data[i] = (char)i;
+	}
+	/*
+	 * Fill first buffer with numbers from 0 to 255
+	 */
+	pmem2_memcpy(data, buffer_data, string_size, 0);
+
+	/*
+	 * Create future to copy contents of first buffer into second buffer
+	 * which starts in the half of first buffer.
+	 */
+	struct vdm_operation_future move = pmem2_memmove_async(
+		map, data + string_size / 2, data, string_size, 0);
+
+	FUTURE_BUSY_POLL(&move);
+
+	if (memcmp(data + string_size / 2, buffer_data, string_size))
+		UT_FATAL("data should be equal");
+
+	pmem2_map_delete(&map);
+	pmem2_config_delete(&cfg);
+	pmem2_source_delete(&src);
+	CLOSE(fd);
+	return 1;
+}
+
+/*
+ * test_mover_memmove_basic -- test memmove functionality of the default mover
+ * by filling a buffer with some data and then using memset to overwrite it
+ */
+static int
+test_mover_memset_basic(const struct test_case *tc, int argc, char *argv[])
+{
+	if (argc < 1)
+		UT_FATAL("usage: test_mover_memset_basic <file>");
+
+	char *file = argv[0];
+	int fd = OPEN(file, O_RDWR);
+	unsigned array_size = 4096;
+
+	struct pmem2_source *src;
+	struct pmem2_config *cfg;
+	PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd,
+		PMEM2_GRANULARITY_PAGE);
+
+	struct pmem2_map *map = map_valid(cfg, src);
+	char *data = pmem2_map_get_address(map);
+	char *memset_result = malloc(array_size);
+	memset(memset_result, 5, array_size);
+
+	/*
+	 * Fill buffer with some data different from a result of memset
+	 */
+	for (unsigned i = 0; i < array_size; i++) {
+		data[i] = (char)i;
+	}
+
+	/*
+	 * Create future to set every byte of the buffer to 5
+	 */
+	struct vdm_operation_future move =
+		pmem2_memset_async(map, data, 5, array_size, 0);
+
+	FUTURE_BUSY_POLL(&move);
+
+	if (memcmp(data, memset_result, array_size))
+		UT_FATAL("data should be equal");
+
+	pmem2_map_delete(&map);
+	pmem2_config_delete(&cfg);
+	pmem2_source_delete(&src);
+	CLOSE(fd);
+	return 1;
+}
+
 #define WORKER_RUNS 20000
 #define TEST_SIZE 4096
 struct thread_arg {
-	struct pmem2_map *map;
-	void *addr;
-	unsigned threads;
-	unsigned thread_id;
+    struct pmem2_map *map;
+    void *addr;
+    unsigned threads;
+    unsigned thread_id;
 };
 
 /*
- * thread_worker -- thread worker for test_mover_multithread
+ * thread_memcpy_worker -- thread worker for test_mover_memcpy_multithread
  */
 static void *
-thread_worker(void *arg)
+thread_memcpy_worker(void *arg)
 {
 	struct thread_arg *targ = arg;
 	unsigned *pattern1, *pattern2;
@@ -94,9 +200,8 @@ thread_worker(void *arg)
 
 	for (int i = 0; i < WORKER_RUNS; i++) {
 		unsigned *pattern = i % 2 ? pattern1 : pattern2;
-		struct vdm_operation_future cpy =
-			pmem2_memcpy_async(targ->map, targ->addr, pattern,
-				TEST_SIZE, 0);
+		struct vdm_operation_future cpy = pmem2_memcpy_async(
+			targ->map, targ->addr, pattern, TEST_SIZE, 0);
 
 		FUTURE_BUSY_POLL(&cpy);
 
@@ -109,13 +214,103 @@ thread_worker(void *arg)
 }
 
 /*
- * test_mover_multithreaded -- multi-threaded test for the memcpy
+ * test_mover_memcpy_multithreaded -- multi-threaded test for the mover's memcpy
+ */
+static int
+test_mover_memcpy_multithreaded(const struct test_case *tc, int argc,
+	char *argv[])
+{
+	if (argc < 2)
+		UT_FATAL(
+		"usage: test_mover_memcpy_multithreaded <file> <threads>");
+
+	char *file = argv[0];
+	int fd = OPEN(file, O_RDWR);
+	unsigned long num_threads = STRTOUL(argv[1], NULL, 10);
+
+	struct pmem2_source *src;
+	struct pmem2_config *cfg;
+	PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd,
+		PMEM2_GRANULARITY_PAGE);
+
+	struct pmem2_map *map = map_valid(cfg, src);
+
+	UT_ASSERT(pmem2_map_get_size(map) >= TEST_SIZE * num_threads);
+
+	os_thread_t *threads = MALLOC(num_threads * sizeof(*threads));
+	struct thread_arg *args = MALLOC(num_threads * sizeof(*args));
+
+	char *data = pmem2_map_get_address(map);
+	for (unsigned i = 0; i < num_threads; i++) {
+		args[i].map = map;
+		args[i].addr = data + i * TEST_SIZE;
+		args[i].threads = num_threads;
+		args[i].thread_id = i;
+
+		THREAD_CREATE(&threads[i], NULL, thread_memcpy_worker,
+			&args[i]);
+	}
+
+	for (unsigned i = 0; i < num_threads; i++) {
+		THREAD_JOIN(&threads[i], NULL);
+	}
+
+	FREE(threads);
+	FREE(args);
+
+	pmem2_map_delete(&map);
+	pmem2_config_delete(&cfg);
+	pmem2_source_delete(&src);
+	CLOSE(fd);
+	return 2;
+}
+
+/*
+ * thread_memmove_worker -- thread worker for test_mover_memmove_multithread
+ */
+static void *
+thread_memove_worker(void *arg)
+{
+	struct thread_arg *targ = arg;
+	unsigned *pattern1, *pattern2;
+
+	UT_COMPILE_ERROR_ON(TEST_SIZE % sizeof(*pattern1) != 0);
+	unsigned array_size = TEST_SIZE / sizeof(*pattern1);
+
+	pattern1 = MALLOC(array_size * sizeof(*pattern1));
+	pattern2 = MALLOC(array_size * sizeof(*pattern2));
+
+	for (unsigned j = 0; j < array_size; j++) {
+		pattern1[j] = targ->thread_id + 1 * targ->threads;
+		pattern2[j] = targ->thread_id + 2 * targ->threads;
+	}
+
+	for (int i = 0; i < WORKER_RUNS; i++) {
+		unsigned *pattern = i % 2 ? pattern1 : pattern2;
+		struct vdm_operation_future move = pmem2_memmove_async(
+			targ->map, targ->addr, pattern, TEST_SIZE, 0);
+
+		FUTURE_BUSY_POLL(&move);
+
+		if (memcmp(pattern, targ->addr, TEST_SIZE))
+			UT_FATAL("data should be equal");
+	}
+	FREE(pattern1);
+	FREE(pattern2);
+	return NULL;
+}
+
+/*
+ * test_mover_memmove_multithreaded -- multi-threaded test for the mover's
+ * memmove
  */
 static int
-test_mover_multithreaded(const struct test_case *tc, int argc, char *argv[])
+test_mover_memmove_multithreaded(const struct test_case *tc, int argc,
+	char *argv[])
 {
 	if (argc < 2)
-		UT_FATAL("usage: test_mover_basic <file> <threads>");
+		UT_FATAL(
+		"usage: test_mover_memmove_multithreaded <file> <threads>");
 
 	char *file = argv[0];
 	int fd = OPEN(file, O_RDWR);
@@ -130,8 +325,7 @@ test_mover_multithreaded(const struct test_case *tc, int argc, char *argv[])
 
 	UT_ASSERT(pmem2_map_get_size(map) >= TEST_SIZE * num_threads);
 
-	os_thread_t *threads
-		= MALLOC(num_threads * sizeof(*threads));
+	os_thread_t *threads = MALLOC(num_threads * sizeof(*threads));
 	struct thread_arg *args = MALLOC(num_threads * sizeof(*args));
 
 	char *data = pmem2_map_get_address(map);
@@ -141,7 +335,96 @@ test_mover_multithreaded(const struct test_case *tc, int argc, char *argv[])
 		args[i].threads = num_threads;
 		args[i].thread_id = i;
 
-		THREAD_CREATE(&threads[i], NULL, thread_worker,
+		THREAD_CREATE(&threads[i], NULL, thread_memove_worker,
+			&args[i]);
+	}
+
+	for (unsigned i = 0; i < num_threads; i++) {
+		THREAD_JOIN(&threads[i], NULL);
+	}
+
+	FREE(threads);
+	FREE(args);
+
+	pmem2_map_delete(&map);
+	pmem2_config_delete(&cfg);
+	pmem2_source_delete(&src);
+	CLOSE(fd);
+	return 2;
+}
+
+/*
+ * thread_memset_worker -- thread worker for test_mover_memset_multithread
+ */
+static void *
+thread_memset_worker(void *arg)
+{
+	struct thread_arg *targ = arg;
+	char *expected_result1, *expected_result2;
+
+	UT_COMPILE_ERROR_ON(TEST_SIZE % sizeof(*expected_result1) != 0);
+	unsigned array_size = TEST_SIZE / sizeof(*expected_result1);
+
+	expected_result1 = MALLOC(array_size * sizeof(*expected_result1));
+	expected_result2 = MALLOC(array_size * sizeof(*expected_result2));
+
+	memset(expected_result1, (int)targ->thread_id, TEST_SIZE);
+	memset(expected_result2, (int)(targ->thread_id + targ->threads),
+		TEST_SIZE);
+
+	for (int i = 0; i < WORKER_RUNS; i++) {
+		int number = i % 2 ? (int)targ->thread_id
+				: (int)(targ->thread_id + targ->threads);
+		char *expected_result =
+			i % 2 ? expected_result1 : expected_result2;
+		struct vdm_operation_future set = pmem2_memset_async(
+			targ->map, targ->addr, number, array_size, 0);
+
+		FUTURE_BUSY_POLL(&set);
+
+		if (memcmp(expected_result, targ->addr, TEST_SIZE))
+			UT_FATAL("data should be equal");
+	}
+	FREE(expected_result1);
+	FREE(expected_result2);
+	return NULL;
+}
+
+/*
+ * test_mover_memset_multithreaded -- multi-threaded test for the mover's memset
+ */
+static int
+test_mover_memset_multithreaded(const struct test_case *tc, int argc,
+	char *argv[])
+{
+	if (argc < 2)
+		UT_FATAL(
+		"usage: test_mover_memset_multithreaded <file> <threads>");
+
+	char *file = argv[0];
+	int fd = OPEN(file, O_RDWR);
+	unsigned long num_threads = STRTOUL(argv[1], NULL, 10);
+
+	struct pmem2_source *src;
+	struct pmem2_config *cfg;
+	PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd,
+		PMEM2_GRANULARITY_PAGE);
+
+	struct pmem2_map *map = map_valid(cfg, src);
+
+	UT_ASSERT(pmem2_map_get_size(map) >= TEST_SIZE * num_threads);
+
+	os_thread_t *threads = MALLOC(num_threads * sizeof(*threads));
+	struct thread_arg *args = MALLOC(num_threads * sizeof(*args));
+
+	char *data = pmem2_map_get_address(map);
+	for (unsigned i = 0; i < num_threads; i++) {
+		args[i].map = map;
+		args[i].addr = data + i * TEST_SIZE;
+		args[i].threads = num_threads;
+		args[i].thread_id = i;
+
+		THREAD_CREATE(&threads[i], NULL, thread_memset_worker,
 			&args[i]);
 	}
 
@@ -206,10 +489,13 @@ test_miniasync_mover(const struct test_case *tc, int argc, char *argv[])
  * test_cases -- available test cases
  */
 static struct test_case test_cases[] = {
-	TEST_CASE(test_mover_basic),
-	TEST_CASE(test_mover_multithreaded),
-	TEST_CASE(test_miniasync_mover)
-};
+	TEST_CASE(test_mover_memcpy_basic),
+	TEST_CASE(test_mover_memmove_basic),
+	TEST_CASE(test_mover_memset_basic),
+	TEST_CASE(test_mover_memcpy_multithreaded),
+	TEST_CASE(test_mover_memmove_multithreaded),
+	TEST_CASE(test_mover_memset_multithreaded),
+	TEST_CASE(test_miniasync_mover)};
 
 #define NTESTS (sizeof(test_cases) / sizeof(test_cases[0]))
 
diff --git a/src/test/scope/out13.log.match b/src/test/scope/out13.log.match
index 0cd04d146f37ec950b02696c3bbb98ba2135fd1c..bf6639cb2ef2baaada9f8fb10e0b380631a5531a 100644
--- a/src/test/scope/out13.log.match
+++ b/src/test/scope/out13.log.match
@@ -26,6 +26,8 @@ pmem2_map_get_size$(nW)
 pmem2_map_get_store_granularity$(nW)
 pmem2_map_new$(nW)
 pmem2_memcpy_async$(nW)
+pmem2_memmove_async$(nW)
+pmem2_memset_async$(nW)
 pmem2_perror$(nW)
 pmem2_source_alignment$(nW)
 pmem2_source_delete$(nW)
diff --git a/src/test/scope/out14.log.match b/src/test/scope/out14.log.match
index e64fd58b04d723535c18e607bbd1f613e6878adb..63f642cd626bc759104c59accd4a8dca86544b41 100644
--- a/src/test/scope/out14.log.match
+++ b/src/test/scope/out14.log.match
@@ -28,6 +28,8 @@ pmem2_map_get_size
 pmem2_map_get_store_granularity
 pmem2_map_new
 pmem2_memcpy_async
+pmem2_memmove_async
+pmem2_memset_async
 pmem2_perrorU
 pmem2_perrorW
 pmem2_source_alignment
diff --git a/utils/docker/images/Dockerfile.fedora-31 b/utils/docker/images/Dockerfile.fedora-31
index ff95935999d0cedf3e7dddca9f156cd683febf16..95389b9ecea4fc09f6a7bc833434b06e43d713e7 100644
--- a/utils/docker/images/Dockerfile.fedora-31
+++ b/utils/docker/images/Dockerfile.fedora-31
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: BSD-3-Clause
-# Copyright 2016-2020, Intel Corporation
+# Copyright 2016-2022, Intel Corporation
 
 #
 # Dockerfile - a 'recipe' for Docker to build an image of fedora-based
diff --git a/utils/docker/images/Dockerfile.fedora-35 b/utils/docker/images/Dockerfile.fedora-35
index 4a89989ecc1dcda45f56521c42de5a16804b7c76..5d07c11f26b55dd9c79f1501946349c22ce49b33 100644
--- a/utils/docker/images/Dockerfile.fedora-35
+++ b/utils/docker/images/Dockerfile.fedora-35
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: BSD-3-Clause
-# Copyright 2016-2020, Intel Corporation
+# Copyright 2016-2022, Intel Corporation
 
 #
 # Dockerfile - a 'recipe' for Docker to build an image of fedora-based
diff --git a/utils/docker/images/Dockerfile.ubuntu-20.04 b/utils/docker/images/Dockerfile.ubuntu-20.04
index 8b201a85a0de1a626671363996ac7b20b8ab6212..7d0d4acc1dfc754d0fe1451a99427255e83d8909 100644
--- a/utils/docker/images/Dockerfile.ubuntu-20.04
+++ b/utils/docker/images/Dockerfile.ubuntu-20.04
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: BSD-3-Clause
-# Copyright 2016-2020, Intel Corporation
+# Copyright 2016-2022, Intel Corporation
 
 #
 # Dockerfile - a 'recipe' for Docker to build an image of ubuntu-based