diff --git a/doc/Makefile b/doc/Makefile
index bd6ef6688d528d22ae2ded9f19488957ba5efae9..257bc0bf9631882b2bd52ffe56f1f08dd4ef038b 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -92,7 +92,7 @@ MANPAGES_3_DUMMY_EXP =
 MANPAGES_1_DUMMY_EXP =
 
 # libpmem2
-MANPAGES_7_MD_PMEM2 = libpmem2/libpmem2.7.md
+MANPAGES_7_MD_PMEM2 = libpmem2/libpmem2.7.md libpmem2/libpmem2_unsafe_shutdown.7.md
 MANPAGES_5_MD_PMEM2 =
 MANPAGES_3_MD_PMEM2 = libpmem2/pmem2_errormsg.3.md libpmem2/pmem2_config_new.3.md libpmem2/pmem2_map.3.md \
 		libpmem2/pmem2_unmap.3.md libpmem2/pmem2_map_get_address.3.md libpmem2/pmem2_map_get_size.3.md \
@@ -106,7 +106,8 @@ MANPAGES_3_MD_PMEM2 = libpmem2/pmem2_errormsg.3.md libpmem2/pmem2_config_new.3.m
 		libpmem2/pmem2_config_set_vm_reservation.3.md libpmem2/pmem2_vm_reservation_new.3.md \
 		libpmem2/pmem2_badblock_context_new.3.md libpmem2/pmem2_badblock_next.3.md \
 		libpmem2/pmem2_badblock_clear.3.md libpmem2/pmem2_config_set_protection.3.md \
-		libpmem2/pmem2_deep_flush.3.md libpmem2/pmem2_source_from_anon.3.md
+		libpmem2/pmem2_deep_flush.3.md libpmem2/pmem2_source_from_anon.3.md \
+		libpmem2/pmem2_source_device_id.3.md libpmem2/pmem2_source_device_usc.3.md
 MANPAGES_1_MD_PMEM2 =
 ifeq ($(PMEM2_INSTALL),y)
 MANPAGES_3_DUMMY += libpmem2/pmem2_config_delete.3 libpmem2/pmem2_source_from_handle.3 libpmem2/pmem2_source_delete.3 \
diff --git a/doc/libpmem2/.gitignore b/doc/libpmem2/.gitignore
index 710e48a6d6be83dc1a185d2dc402bffe1cb36593..1474ccdf6567edd1f69005e6a71088c1f8970f05 100644
--- a/doc/libpmem2/.gitignore
+++ b/doc/libpmem2/.gitignore
@@ -1,4 +1,5 @@
 libpmem2.7
+libpmem2_unsafe_shutdown.7
 pmem2_badblock_context_new.3
 pmem2_badblock_next.3
 pmem2_badblock_clear.3
@@ -25,6 +26,8 @@ pmem2_source_alignment.3
 pmem2_source_from_fd.3
 pmem2_source_from_anon.3
 pmem2_source_size.3
+pmem2_source_device_id.3
+pmem2_source_device_usc.3
 pmem2_unmap.3
 pmem2_perror.3
 pmem2_vm_reservation_new.3
diff --git a/doc/libpmem2/libpmem2_unsafe_shutdown.7.md b/doc/libpmem2/libpmem2_unsafe_shutdown.7.md
new file mode 100644
index 0000000000000000000000000000000000000000..83c8940c6e72a0c3ea62ac58bfb3711037a2205e
--- /dev/null
+++ b/doc/libpmem2/libpmem2_unsafe_shutdown.7.md
@@ -0,0 +1,84 @@
+---
+layout: manual
+Content-Style: 'text/css'
+title: _MP(LIBPMEM2_UNSAFE_SHUTDOWN, 7)
+collection: libpmem2
+header: PMDK
+date: pmem2 API version 1.0
+...
+
+[comment]: <> (SPDX-License-Identifier: BSD-3-Clause
+[comment]: <> (Copyright 2020, Intel Corporation)
+
+[comment]: <> (libpmem2_unsafe_shutdown.7 -- man page for libpmem2 unsafe shutdown)
+
+[NAME](#name)<br />
+[DESCRIPTION](#description)<br />
+[UNSAFE SHUTDOWN DETECTION](#unsafe-shutdown-detection)<br />
+[SEE ALSO](#see-also)
+
+# NAME #
+
+**libpmem2_unsafe_shutdown** - libpmem2 unsafe shutdown
+
+# DESCRIPTION #
+
+In systems with the persistent memory support, *a power-fail protected domain*
+covers a set of resources from which the platform will flush data to the
+*a persistent medium* in case of *a power-failure*. Data stored on
+*the persistent medium* is preserved across power cycles.
+
+The hardware guarantees the feature to flush all data stored in
+*the power-fail protected domain* to *the persistent medium*. However, nothing
+is infallible, and Persistent Memory hardware can expose a monotonically
+increasing *unsafe shutdown counter* (**USC**) that is incremented every time
+a failure of the mechanism above is detected. This allows software to discover
+situations where a running application was interrupted by a power failure that
+led to an unsafe shutdown. Undiscovered unsafe shutdowns might cause silent data
+corruption.
+
+>Note: *The unsafe shutdown* may corrupt data stored on a device, in a file,
+in a set of files, and a mapping spanning only a part of a file.
+For the sake of simplicity, all of the above cases will be called *file* below.
+
+# UNSAFE SHUTDOWN DETECTION #
+
+Software can detect an unsafe shutdown by watching for the change between
+unsafe shutdown count value across application startups. Any changes can be
+indicative of unsafe shutdown occurrence.
+
+Applications can implement a detection mechanism by storing the **USC** retrieved
+from **pmem2_source_device_usc**(3) in Persistent Memory. Then, on subsequent
+startups, the stored value must be compared with a newly retrieved one.
+
+However, this detection method can result in false-positives. Moving the file to
+different Persistent Memory devices with possibly different **USC** values would
+lead to false unsafe shutdown detection.
+
+Additionally, relying on **USC** value alone could result in the detection of
+unsafe shutdown events that occur when such a shutdown has no chance of impacting
+the data used by the application, e.g., when nothing is actively using the file.
+
+Applications can avoid false-positives associated with moving the file by storing
+device identification, obtained through **pmem2_source_device_id**(3), alongside
+the **USC**. This enables the software to check if the underlying device has
+changed, and reinitialize the stored **USC** in such cases.
+
+The second behavior, detection of possibly irrelevant unsafe shutdown events,
+if undesirable, can be prevented by storing a flag indicating whether the file
+is in use, alongside all the rest of the relevant information.
+
+The application should use **pmem2_deep_flush**(3) when storing any data related
+to unsafe shutdown detection for higher reliability. This helps ensure that the
+detection mechanism is not reliant on the correct functioning of the same hardware
+features it is designed to safeguard.
+
+General-purpose software should not assume the presence of **USC** in the platform,
+and should instead appropriately handle any *PMEM2_E_NOSUPP* it encounters.
+Doing otherwise might cause the software to be unnecessarily restrictive about
+the hardware it supports and would prevent, e.g., testing on emulated PMEM.
+
+# SEE ALSO #
+
+**pmem2_deep_flush**(3), **pmem2_persist_fn**(3), **pmem2_source_device_id**(3),
+**pmem2_source_device_usc**(3) and **<https://pmem.io>**
diff --git a/doc/libpmem2/pmem2_source_device_id.3.md b/doc/libpmem2/pmem2_source_device_id.3.md
new file mode 100644
index 0000000000000000000000000000000000000000..eeff69b7c32ebf1bf742848c1f22810138f7ac92
--- /dev/null
+++ b/doc/libpmem2/pmem2_source_device_id.3.md
@@ -0,0 +1,90 @@
+---
+layout: manual
+Content-Style: 'text/css'
+title: _MP(PMEM2_SOURCE_DEVICE_ID, 3)
+collection: libpmem2
+header: PMDK
+date: pmem2 API version 1.0
+...
+
+[comment]: <> (SPDX-License-Identifier: BSD-3-Clause)
+[comment]: <> (Copyright 2020, Intel Corporation)
+
+[comment]: <> (pmem2_source_device_id.3 -- man page for pmem2_source_device_id)
+
+[NAME](#name)<br />
+[SYNOPSIS](#synopsis)<br />
+[DESCRIPTION](#description)<br />
+[RETURN VALUE](#return-value)<br />
+[SEE ALSO](#see-also)<br />
+
+# NAME #
+
+**pmem2_source_device_id**() - returns the unique identifier of a device
+
+# SYNOPSIS #
+
+```c
+#include <libpmem2.h>
+
+struct pmem2_source;
+int pmem2_source_device_id(const struct pmem2_source *source, char *id, size_t *len);
+```
+
+# DESCRIPTION #
+
+The **pmem2_source_device_id**() function retrieves a unique identifier
+of all NVDIMMs backing the data source. This function has two operating modes:
+
+* if *\*id* is NULL the function calculates a buffer length required for
+storing the identifier of the *\*source* device and puts this length in *\*len*
+The more hardware devices back the data source, the longer the length is.
+
+* if *\*id* is not NULL it must point to a buffer of length *\*len* provided by
+the previous call to this function.
+On success, **pmem2_source_device_id**() will store a unique identifier
+of all hardware devices backing the data source.
+
+For details on how to use the unique identifier for detecting *the unsafe shutdown*
+please refer to **libpmem2_unsafe_shutdown**(7) manual page.
+
+# RETURN VALUE #
+
+The **pmem2_source_device_id**() function returns 0 on success.
+If the function fails, the *\*id* and *\*len* variables contents are left unmodified,
+and one of the following errors is returned:
+
+On all systems:
+
+* **PMEM2_E_BUFFER_TOO_SMALL** - the provided buffer of length *\*len* is too
+small to store the full identifier of the backing devices.
+* **PMEM2_E_NOSUPP** - the underlying platform does not expose hardware
+identification.
+
+On Windows:
+
+* -**errno** equivalent of return code set by failing
+**GetFinalPathNameByHandleW**(), while trying to resolve the volume path from the
+file handle.
+
+* -**errno** set by failing **malloc**(3), while trying to allocate a buffer
+for storing volume path.
+
+* -**errno** equivalent of return code set by failing
+**CreateFileW**(), while trying to obtain a handle to the volume.
+
+* -**errno** equivalent of return code set by failing
+**DeviceIoControl **(), while trying to obtain volume **USC** value.
+
+On Linux:
+
+* -**errno** set by failing **fstat**(2), while trying to validate the file
+descriptor.
+
+* -**errno** set by failing **ndctl_new**(), while trying to initiate a new
+NDCTL library context.
+
+# SEE ALSO #
+
+**fstat**(2), **errno**(3), **malloc**(3), **libpmem2_unsafe_shutdown**(7),
+ and **<http://pmem.io>**
diff --git a/doc/libpmem2/pmem2_source_device_usc.3.md b/doc/libpmem2/pmem2_source_device_usc.3.md
new file mode 100644
index 0000000000000000000000000000000000000000..20cf67a9d3922703885f9ad832bec281cf01e9cc
--- /dev/null
+++ b/doc/libpmem2/pmem2_source_device_usc.3.md
@@ -0,0 +1,84 @@
+---
+layout: manual
+Content-Style: 'text/css'
+title: _MP(PMEM2_SOURCE_DEVICE_USC, 3)
+collection: libpmem2
+header: PMDK
+date: pmem2 API version 1.0
+...
+
+[comment]: <> (SPDX-License-Identifier: BSD-3-Clause)
+[comment]: <> (Copyright 2020, Intel Corporation)
+
+[comment]: <> (pmem2_source_device_usc.3 -- man page for pmem2_source_device_usc)
+
+[NAME](#name)<br />
+[SYNOPSIS](#synopsis)<br />
+[DESCRIPTION](#description)<br />
+[RETURN VALUE](#return-value)<br />
+[SEE ALSO](#see-also)<br />
+
+# NAME #
+
+**pmem2_source_device_usc**() - returns the *unsafe shutdown counter* value of a
+device
+
+# SYNOPSIS #
+
+```c
+#include <libpmem2.h>
+
+struct pmem2_source;
+int pmem2_source_device_usc(const struct pmem2_source *source, uint64_t *usc);
+```
+
+# DESCRIPTION #
+
+The **pmem2_source_device_usc**() function retrieves the sum of the
+*unsafe shutdown count*(**USC**) values of all hardware devices backing
+the data source and stores it in *\*usc*.
+
+Please refer to **libpmem2_unsafe_shutdown**(7) for detailed description on how
+to properly consume this information.
+
+# RETURN VALUE #
+
+The **pmem2_source_device_usc**() function returns 0 on success.
+If the function fails, the *\*usc* variable content is left unmodified, and one of
+the following errors is returned:
+
+On all systems:
+
+* **PMEM2_E_NOSUPP** - the underlying platform does not expose unsafe shutdown
+count information.
+
+On Windows:
+
+* -**errno** equivalent of return code set by failing
+**GetFinalPathNameByHandleW**(), while trying to resolve volume path from the
+file handle.
+
+* -**errno** set by failing **malloc**(3), while trying to allocate a buffer
+for storing volume path.
+
+* -**errno** equivalent of return code set by failing
+**CreateFileW**(), while trying to obtain a handle to the volume.
+
+* -**errno** equivalent of return code set by failing
+**DeviceIoControl**(), while trying to obtain  volume **USC** value.
+
+On Linux:
+
+* -**errno** set by failing **fstat**(2), while trying to validate the file
+descriptor.
+
+* -**errno** set by failing **ndctl_new**(), while trying to initiate a new
+NDCTL library context.
+
+* -**errno** set by failing **ndctl_dimm_get_dirty_shutdown**(),
+while trying to obtain DIMM **USC** value.
+
+# SEE ALSO #
+
+**fstat**(2), **errno**(3), **malloc**(3), **libpmem2_unsafe_shutdown**(7),
+ and **<http://pmem.io>**