diff --git a/docs/vmcs.md b/docs/vmcs.md
new file mode 100644
index 0000000000000000000000000000000000000000..cfa08130f9c1a52d1b68395c2e1928cf3e0d8767
--- /dev/null
+++ b/docs/vmcs.md
@@ -0,0 +1,32 @@
+# VMCS -- Virtual Machine Control Structure
+
+## Purpose
+
+- **VMCSs help to manage transitions into and out of VMX non-root operation (i.e
+VM entries and exits)**
+- Manage processor behaviour in VMX non-root operation
+- VMCSs are manipulated using `vmclear`, `vmptrld`, `vmread`, `vmwrite` instructions
+
+> **For a multi-vCPU VM, the VMM can use a different VMCS for each vCPU**
+
+## Requirements
+
+- **VMCS pointer** $\rightarrow$ 64-bit **physical address** (will be $\sim$ 39
+in reality)
+    - Aligned to a 4-KByte boundary (bits 11:0 must be zero)
+
+### Structure
+
+The size of the structure below should be precisely equal to a page (i.e. 4KiB).[^1]
+
+```c
+struct vmcs_t {
+    unsigned long vmcs_rev_id : 31;
+    unsigned long shadow_vmcs : 1;
+    unsigned long vmx_abort;
+    char data[0x1000 - (sizeof(unsigned long) << 1)];
+};
+```
+
+[^1]: it seems that the `gcc` extension `__attribute__((packed))` doesn't help
+in this case because it ruins the 8-byte alignment (according to `clangd`)