# From /hotpatch to $1.50 a Core: The Live-Patch Pipeline Microsoft Built and Then Made Public

> How Windows hot patching evolved from a 1990s compiler flag to a Secure-Kernel-mediated, three-layer pipeline shipping in three product waves between 2022 and 2025.

*Published: 2026-05-12*
*Canonical: https://paragmali.com/blog/from-hotpatch-to-150-a-core-the-live-patch-pipeline-microsof*
*License: CC BY 4.0 - https://creativecommons.org/licenses/by/4.0/*

---
<TLDR>
**Windows hot patching is a three-layer pipeline, not a feature.** A kernel mechanism rewrites a process's `.text` in place, directed by HPAT metadata baked into every patchable PE and brokered by the Secure Kernel. A servicing model ships one Cumulative Update per quarter and two hot-patch-only months between baselines. A management plane (Azure Update Manager, Intune Autopatch, or Azure Arc) selects eligible fleets and falls back to the regular reboot path for everything else.

The mechanism has been running on the Azure host fleet [for years](https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541) before Microsoft turned it into a product. The public products arrived in three waves: [Windows Server 2022 Datacenter: Azure Edition](https://techcommunity.microsoft.com/blog/itopstalkblog/announcing-general-availability-of-hotpatch-for-windows-server-2022-azure-editio/3168095) (February 16, 2022, free on Azure), [Windows 11 Enterprise 24H2](https://techcommunity.microsoft.com/blog/windows-itpro-blog/hotpatch-for-windows-client-now-available/4399808) (April 2, 2025, license-gated via Intune Autopatch), and [Windows Server 2025 outside Azure](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/) (July 1, 2025, $1.50 USD per CPU core per month over Azure Arc). The architectural innovation -- the part that separates the modern design from Microsoft's failed 2003 attempt and from Linux's ftrace-based `livepatch` -- is the trust anchor. The Secure Kernel verifies signed patch payloads and performs the rewrite under HVCI. Static-data-layout changes still force a reboot, and they always will. That is not an engineering shortcoming. It is a corollary of Rice's theorem.
</TLDR>

## 1. The hook: a $1.50-per-core-per-month reboot bill

Microsoft's Visual C++ compiler ships a `/hotpatch` switch. The flag is small, almost forgettable: when set, the compiler guarantees that [the first instruction of every function is at least two bytes long and that no jump within the function targets the prologue](https://learn.microsoft.com/en-us/cpp/build/reference/hotpatch-create-hotpatchable-image). Those two bytes are the enabling primitive for everything that follows in this article. They are the place where a running operating system can be quietly amended without being stopped.

On July 1, 2025, Microsoft began charging $1.50 USD per CPU core per month for the right to use that primitive on [Windows Server 2025 outside Azure](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/). The 26 years in between are the subject of this article.

<Definition term="Hot patching">
The replacement of executable code inside a running process or kernel without first stopping the program. Microsoft uses the term as an umbrella for the *mechanism* (in-memory binary rewriting), the *delivery pipeline* (signed payloads, servicing cadence), and the *operational plane* (which fleets are eligible and how rollout is staged). Linux uses *livepatch* (in-tree) and *kpatch* / *kGraft* / *Ksplice* (out-of-tree or vendor) for closely related but mechanically distinct primitives. The shared goal is to apply security fixes without paying the downtime cost of a reboot.
</Definition>

The shock of a metered subscription on a 30-year-old compiler feature is the question this article exists to answer. Three current Windows hot-patch products run on top of a single internal engineering pipeline:

- **Windows Server 2022 Datacenter: Azure Edition**, [GA on February 16, 2022, free for Azure VMs](https://techcommunity.microsoft.com/blog/itopstalkblog/announcing-general-availability-of-hotpatch-for-windows-server-2022-azure-editio/3168095). The first public surface of the modern pipeline.
- **Windows 11 Enterprise 24H2 client**, [GA on April 2, 2025](https://techcommunity.microsoft.com/blog/windows-itpro-blog/hotpatch-for-windows-client-now-available/4399808), license-gated through Intune Autopatch.
- **Windows Server 2025**, [GA on July 1, 2025 over Azure Arc at $1.50 USD per CPU core per month](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/) for on-premises and multi-cloud machines, with the [reboot frequency reduced from 12 times a year to 4](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/).

<PullQuote>
"Hotpatching is an impact-less update technology which has been keeping the Azure fleet up-to-date for years with zero impact on customer workloads." -- [Microsoft's Windows OS Platform team, November 2021](https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541)
</PullQuote>

That single sentence is the load-bearing claim. The customer-facing product launched in February 2022 was not a research result. It was the externalization of an internal pipeline that had been quietly servicing Azure for years. The 2022, 2025, and 2025 GA dates are the points at which Microsoft turned the same engineering machine outward, one customer surface at a time.

<Aside label="Three Azure availability primitives, often conflated">
At Build 2025, Mark Russinovich [presented hot patching alongside two other Azure availability primitives](https://www.microsoft.com/en-us/research/video/inside-azure-innovations-with-mark-russinovich/): VMPHU (Virtual Machine Preserving Host Update), which patches the host while preserving running guests through the host reboot, and Kernel Soft Reboot, which is a fast in-place kernel transition that skips firmware. These are not the same thing. VMPHU is host-side. Kernel Soft Reboot still costs a kernel transition. Hot patching is the only one that rewrites code in flight on the running guest. Conflating the three is the second-most-common mistake in this space.
</Aside>

So the question. Microsoft did not invent in-memory function replacement on Windows in 2022. Microsoft *shipped* it in 2003. Why did it take 17 years to come back? The answer threads through a failed first attempt, a state-aligned APT, the entire Linux live-patching family tree, and an architectural change that did not exist when the original mechanism was designed. The compiler flag does not change. Everything around it does.

## 2. The 2003 original: Server 2003 SP1 hotpatching and why it mattered

In May 2011, a German systems engineer named Johannes Passing sat down with a Server 2003 kernel and a debugger and reverse-engineered, function by function, how an MS06-030 hot patch landed in memory. His [walkthrough](https://jpassing.com/2011/05/03/windows-hotpatching-a-walkthrough/) is one of the cleanest contemporaneous records of a Microsoft feature that nearly nobody used. The trace looks like this, copied verbatim from his debugger session:

```
nt!MmLoadSystemImage
nt!MmHotPatchRoutine+0x59
nt!ExApplyCodePatch+0x191
nt!NtSetSystemInformation+0xa1e
```

`NtSetSystemInformation`, with the magic class `SystemHotpatchInformation`, dispatched into `ExApplyCodePatch`, which called `MmHotPatchRoutine`, which finally called `MiPerformHotPatch` to walk the patch image's metadata and rewrite the target driver's instructions. The example Passing followed targeted `mrxsmb.sys` and `rdbss.sys` for the SMB bug that MS06-030 fixed. The patch worked. It worked in production. And almost nobody ever shipped one.

The enabling primitive is the compiler flag from §1. The MSVC documentation states the contract: [when `/hotpatch` is used at compile time, every function begins with an at-least-two-byte first instruction with no internal jumps to it](https://learn.microsoft.com/en-us/cpp/build/reference/hotpatch-create-hotpatchable-image). The x86 convention that fell out of this was the famous [`mov edi, edi` instruction at the start of every Windows function](https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=9583) -- a 2-byte NOP-equivalent that, per Raymond Chen's verbatim Microsoft DevBlogs description, [can be replaced with a two-byte `JMP $-5` instruction to redirect control to five bytes of patch space that comes immediately before the start of the function](https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=9583) without ever being read in a half-modified state.

<Sidenote>The `mov edi, edi` instruction is itself an artifact. On x86 it is the compiler's chosen 2-byte placeholder; on x64 and Arm64 the compiler [guarantees the hotpatchable prologue without an explicit placeholder instruction](https://learn.microsoft.com/en-us/cpp/build/reference/hotpatch-create-hotpatchable-image), because those architectures' calling conventions and alignment requirements give the linker more freedom. The fossil-like sequence survives in x86 code today as a quiet reminder that every Windows function used to be hotpatchable by construction.</Sidenote>

The 2003 design paired this prologue convention with a payload format and a delivery syscall. The OpenRCE community published [the format details in 2006](https://www.openrce.org/articles/full_view/22): the hot-patch image was a normal PE module with a section called `.hotp1`, at least 80 bytes long, beginning with a `HOTPATCH_HEADER` followed by a relocation-and-replacement table. On kernel-mode targets, `MmHotPatchRoutine` walked the headers and rewrote the live `.text`. On user-mode targets, an updating agent enumerated the running processes and [injected a remote thread into each one](https://www.openrce.org/articles/full_view/22) to perform the equivalent rewrite. The mechanism shipped in Server 2003 SP1 and was available on XP SP2 across x86, IA-64, and x64.<Sidenote>Primary sources disagree on the service-pack attribution: the [OpenRCE 2006 writeup](https://www.openrce.org/articles/full_view/22) labels availability as "Server 2003 SP0, XP SP2 x86, ia64, x64," while [Johannes Passing's 2011 walkthrough](https://jpassing.com/2011/05/03/windows-hotpatching-a-walkthrough/) and Microsoft's 2016 MMPC blog both say "Server 2003 SP1." The article picks the Microsoft-leaning side; the OpenRCE attribution remains in tension.</Sidenote>

It also never really shipped. The Server 2003 hotpatch engine was a credible developer feature that did not become an operational habit. A handful of advisories ever produced a `.hotp1` payload; the feature was quietly retired by Windows 8. Why? Three structural reasons -- and a fourth that did not become visible until 2016.

<Definition term="GDR vs QFE branches">
Microsoft's pre-cumulative-update servicing model split each Windows binary into two parallel build streams: GDR (General Distribution Release), which carried only the security fixes shipped publicly, and QFE (Quick Fix Engineering), which carried the union of every per-customer hotfix Microsoft had issued. A 2003-era hot patch had to apply cleanly to *both* branches because customers were on different branches. Producing the patch was double the work, and the work duplicated everything that was already going into GDR. The cumulative-update model that replaced GDR/QFE in 2016 is one of the precise preconditions that made the modern hot-patch pipeline economical.
</Definition>

So the four failures of the 2003 design:

1. **No consistency model.** The prologue overwrite was atomic at the instruction level, but the design said nothing about a thread that was already executing the function body. If an in-flight call could finish in the old code while a new call into the same function landed in the new code, certain bug fixes that changed semantics across the call were unsound. The 2003 engine handled the easy cases and trusted the patch author for the rest.
2. **No architectural trust anchor.** Any kernel-mode code with permission to call `NtSetSystemInformation(SystemHotpatchInformation)` could install a "hot patch." [Driver signing](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format) and [Authenticode](/blog/authenticode-and-catalog-files-the-crypto-foundation-under-w/) were the only line of defense, and Microsoft would discover ten years later that they were not enough.
3. **No servicing-model integration.** Hot patches were ad-hoc per-advisory artifacts. There was no quarterly baseline, no hotpatch-month cadence, no servicing-stack-level expectation that a customer would receive a hot patch instead of a reboot. Operations teams had to opt into each one.
4. **Limited content coverage.** Function-body replacement only. No struct-layout migration, no driver-version transitions in the boot path, no ELAM. The pool of advisories that *could* ship as a `.hotp1` was small.

The fourth failure -- the one Microsoft discovered the hard way -- is the subject of the next section.

## 3. Why the 2003 pipeline failed: politics, operations, and PLATINUM

In April 2016, Microsoft Threat Intelligence published a report on a state-aligned APT group it tracked as PLATINUM. [The mainstream coverage of that report](https://thehackernews.com/2016/04/windows-hotpatching-malware.html) named the group's activity as dating to 2009 and described its tradecraft: PLATINUM was abusing the same `NtSetSystemInformation(SystemHotpatchInformation)` interface Microsoft itself had shipped, to inject backdoors named Dipsing, Adbupd, and JPIN into `winlogon.exe`, `lsass.exe`, and `svchost.exe`. Microsoft's own MMPC blog said of the hot-patch tradecraft itself, [preserved verbatim on the Wayback Machine](https://web.archive.org/web/2020/https://blogs.technet.microsoft.com/mmpc/2016/04/26/digging-deep-for-platinum/): "Using hotpatching in the malicious context has been theorized, but has not been observed in the wild before." The April 2016 disclosure was the *first* in-the-wild observation. The exact start date for PLATINUM's use of the technique is not in the public record; what is in the record is that the mechanism Microsoft had introduced as a customer feature had quietly become a detection-evasion technique by the time Microsoft caught it.

> **Note:** PLATINUM's tradecraft was structurally identical to the 2003 hot-patch engine's design. The group obtained the `SeDebugPrivilege`-equivalent privileges that the documented `NtSetSystemInformation(SystemHotpatchInformation)` call required, then [used the same syscall path Microsoft had documented for legitimate hot patching](https://thehackernews.com/2016/04/windows-hotpatching-malware.html) to inject code into long-running system processes. Microsoft's MMPC blog framed this as the first in-the-wild observation of the technique, not as evidence of a long-running campaign with a known start date. The point is not that the syscall was a backdoor. The point is that hot patching, as designed in 2003, had no trust anchor architecturally distinct from the kernel that performed the patch. [Authenticode](/blog/authenticode-and-catalog-files-the-crypto-foundation-under-w/) validated the binary on disk; nothing validated the in-memory operation. Once an attacker reached kernel mode, the patch path was just another tool.

<Sidenote>Microsoft's original PLATINUM writeup lived at `blogs.technet.microsoft.com/mmpc/2016/04/26/digging-deep-for-platinum/`. That URL has not survived the multiple Microsoft CMS migrations between 2016 and 2026. [The Hacker News's contemporaneous coverage](https://thehackernews.com/2016/04/windows-hotpatching-malware.html) preserves the load-bearing details: target processes, backdoor names, the 2009 first-observation date, and the `NtSetSystemInformation` abuse pattern.</Sidenote>

In retrospect Microsoft drew a two-part lesson, visible in the structure of the modern design. First: in-memory code mutation is necessary if you want to live-patch a fleet at any reasonable scale, because reboots are too expensive and operationally too political to schedule monthly. Second: in-memory code mutation cannot ship safely without an architectural trust anchor distinct from the kernel code being mutated, and it cannot ship operationally without a delivery system that constrains *what* mutations are allowed. The Server 2003 engine had the first half. It had nothing resembling the second half.

Both halves of that lesson took 17 years to be ready. Hardware-mediated isolation under Virtualization-Based Security (VBS) shipped in Windows 10 in 2015; [HVCI](/blog/wdac--hvci-code-integrity-at-every-layer-in-windows/) (the Hypervisor-protected Code Integrity component) and [the Secure Kernel](/blog/when-system-isnt-enough-the-windows-secure-kernel-and-the-en/) matured through subsequent releases; and the [cumulative-update servicing model](https://en.wikipedia.org/wiki/Windows_Update) that replaced the GDR/QFE branch split arrived [with Windows 10 and was back-ported to Windows 7 and 8.1 in October 2016](https://en.wikipedia.org/wiki/Windows_Update). Each of those preconditions had to be standard before a successor hot-patch design could exist.

> **Key idea:** The mechanism of hot patching is older than the product. Microsoft did not invent in-memory function replacement on Windows in 2022. It *shipped* it in 2003, watched it fail operationally, and then discovered in April 2016 that PLATINUM, a group active since 2009, had been weaponizing the same primitive. The work that took 17 years was not the binary rewriting. It was the trust anchor, the servicing discipline, and the management plane that would make rewriting a fleet's `.text` safe to operate.

While Microsoft's 2003 attempt was atrophying in the field, an MIT graduate student named Jeff Arnold was about to publish what would become the canonical academic treatment of the same problem -- and the Linux community was about to spend a decade and a half working through every consistency-model variant a function-replacement system can have. The Linux side of the story is the next four sections in compressed form.

## 4. Linux takes the wheel: Ksplice, kpatch and kGraft, mainline livepatch

In June 2008, Jeff Arnold submitted his MIT Master of Engineering thesis. [The cover page names him and his supervisor, M. Frans Kaashoek, only](https://dspace.mit.edu/handle/1721.1/45813). The thesis's claim, presented as a measurement rather than a hope: 42 of 50 (84%) of all significant x86-32 Linux security patches from May 2005 to December 2007 could be applied to a running kernel by Ksplice without a human writing new code. The patches were applied by treating the source diff as a binary diff and lifting the object-level differences onto the running kernel under `stop_machine()` quiescence.

<Sidenote>The Ksplice EuroSys 2009 paper has *exactly two* authors: Jeff Arnold and M. Frans Kaashoek, both at MIT. The DSpace record at MIT names them verbatim; [the PDF title page does the same](https://pdos.csail.mit.edu/papers/ksplice:eurosys.pdf). Web search engines have occasionally produced five- and six-author lists for this paper. Those are hallucinations. The thesis-to-paper extension at EuroSys is two authors. The Ksplice startup later employed more engineers; the academic record does not.</Sidenote>

Ten months after the thesis, in April 2009, Arnold and Kaashoek's EuroSys paper [tightened the headline number](https://dspace.mit.edu/handle/1721.1/51698): 56 of 64 patches from May 2005 to May 2008, or 88% of significant x86-32 Linux kernel security patches, applied with no new code. That number became the founding empirical claim of the entire field. Every live-patcher built since has been measured against it.

Then the field stalled. Oracle [acquired Ksplice on July 21, 2011](https://en.wikipedia.org/wiki/Ksplice), pulled Red Hat support, and made the technology [Oracle Linux Premier Support customers only](https://web.mit.edu/ksplice/). For three years, Linux had no community-shipped live patcher.

<Mermaid caption="26 years of approaches to live-patching">
timeline
    title Live-patching, 1996 to 2026
    1996-1999 : MSVC /hotpatch ships
    2005      : Server 2003 SP1 hotpatch engine
    2008-2009 : Ksplice (Arnold and Kaashoek)
    2011      : Oracle acquires Ksplice
    2014      : kGraft (SUSE) and kpatch (Red Hat)
    2015      : Linux 4.0 merges in-tree livepatch
    2016+     : Hybrid consistency model lands
    2016+     : VBS and HVCI mature in Windows 10
    2018-2021 : Microsoft Azure host fleet on internal hot patch
    Feb 2022  : Server 2022 Azure Edition public GA
    Apr 2025  : Win11 Enterprise 24H2 client GA
    Jul 2025  : Server 2025 over Arc at $1.50/core/month
</Mermaid>

<Sidenote>Two timeline brackets are editorial inferences worth flagging explicitly. The **1996-1999 MSVC `/hotpatch`** row uses the MSVC 6.0 / 7.x toolchain window as the introduction range; [the MSVC compiler reference](https://learn.microsoft.com/en-us/cpp/build/reference/hotpatch-create-hotpatchable-image) documents current behavior but does not state the original ship year. The **2018-2021 Microsoft Azure host fleet on internal hot patch** row brackets the "for years" framing in [the November 2021 Windows OS Platform team blog](https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541), which is the load-bearing primary attestation that the engine was internal-Azure for years before the February 2022 GA. Both brackets are editorial; the surrounding text and citations carry the unambiguous dates (1996+ for MSVC, 2022 GA for the public product).</Sidenote>

The stall ended in early 2014 with two near-simultaneous re-attempts at the same problem. SUSE's Jiri Kosina and Jiri Slaby published [kGraft on February 3, 2014](https://lwn.net/Articles/584016/), as a 600-line patch that built on the kernel's existing ftrace infrastructure plus a per-task "two universe" model, with switchover at kernel-exit. SUSE [presented kGraft at the Linux Foundation Collaboration Summit on March 27, 2014](https://collaborationsummit2014.sched.com/event/0d798ed17bfaa0361d0aec63f2331c8d), and [issued a press release crediting SUSE Labs as the origin](https://www.suse.com/news/suse-releases-kgraft-for-live-patching-of-linux-kernel/). Red Hat's kpatch project [had announced publicly on February 26, 2014](https://en.wikipedia.org/wiki/Kpatch); on May 1, 2014, Josh Poimboeuf [sent the kpatch RFC to LKML](https://lwn.net/Articles/597123/), with Seth Jennings co-named on the development team. Red Hat published [Poimboeuf's introductory blog](https://www.redhat.com/en/blog/introducing-kpatch-dynamic-kernel-patching) describing kpatch's four components: a build tool, a per-fix hot-patch module, the kpatch core module that hooked ftrace, and a userspace utility.

<Definition term="ftrace">
Linux's in-kernel function tracer. ftrace works by reserving a small region of NOP space at the start of every traceable kernel function (the `mcount` reservation, similar in spirit to MSVC's `/hotpatch` prologue but separately implemented), then rewriting that NOP region at runtime to call a tracer or, in the live-patch case, to call a replacement function. Both kpatch and kGraft layered live patching on top of ftrace because ftrace had already solved the safe-rewriting problem in the kernel; the live-patcher's job was reduced to "redirect this function" rather than "rewrite this code." The choice of ftrace is the single biggest mechanical difference between Linux live patching and Windows hot patching.
</Definition>

The two designs differed at exactly one place: the consistency model. Kpatch chose [stop_machine plus a backtrace check](https://lwn.net/Articles/597407/) -- "a sledgehammer," in LWN's contemporaneous phrase, that halted every CPU and walked every task's stack to verify the old code was not in flight before swapping it for the new. kGraft chose [a per-task flag and a lazy migration at kernel-exit](https://lwn.net/Articles/596854/) -- elegant in concept, but with an unbounded transition tail for tasks that never crossed back into user mode. Kpatch could not patch always-on-stack functions like `schedule()`, `do_wait()`, or `irq_thread()`; LWN estimated [a few dozen such functions in a typical kernel](https://lwn.net/Articles/597407/). kGraft could in principle patch anything but might never finish converging.

| Generation | Year | System | Primitive | Consistency model | Trust anchor |
|---|---|---|---|---|---|
| Gen 0 | 2005 | Server 2003 SP1 hotpatch | `/hotpatch` prologue + `.hotp1` PE section | Atomic prologue swap, no in-flight story | Authenticode + driver signing |
| Gen 1 | 2008 to 2011 | Ksplice (MIT, then Oracle) | Object-code diff, `stop_machine` quiescence | Global pause, stack check | Out-of-tree kernel module, GPLv2 |
| Gen 2a | 2014 | kpatch (Red Hat) | ftrace-based fentry trampoline | `stop_machine` plus per-task backtrace check | Module signing |
| Gen 2b | 2014 | kGraft (SUSE) | ftrace plus INT3/IPI-NMI rewriting | Per-task flag, kernel-exit migration | Module signing |
| Gen 3 | Apr 2015 | Mainline `livepatch` v1 | ftrace-based common substrate | Deferred -- both front-ends survive | In-tree module signing |
| Gen 4 | 2016+ | Mainline `livepatch` hybrid | Same | kGraft per-task plus kpatch stack-check plus kernel-exit plus idle-loop | In-tree module signing |
| Gen 5 | 2018 to 2021 | Microsoft Azure internal hot patch | HPAT plus IMAGE_HOT_PATCH_BASE plus VSM | Per-process callback, no global pause | Secure Kernel under HVCI |
| Gen 6 | 2022, 2025 | Windows Modern Hotpatch (three product waves) | Same as Gen 5 | Same | Same |

Two near-equivalent re-attempts, one tree-shaped politics problem: only one design could be merged. [LWN's coverage of the contest](https://lwn.net/Articles/597407/) is now the canonical retrospective. The compromise came in [Linux 4.0, released April 12, 2015](https://kernelnewbies.org/Linux_4.0): merge the ftrace-based common core, defer the consistency-model question. Both kpatch and kGraft survived as out-of-tree front-ends on top of the in-tree core.

A year later, Josh Poimboeuf landed [the hybrid consistency model](https://lwn.net/Articles/634649/) that the in-tree v1 had postponed. The result is what the [kernel.org documentation today calls](https://www.kernel.org/doc/html/latest/livepatch/livepatch.html), in three converged paragraphs of formerly contested design:

<PullQuote>
"Livepatch has a consistency model which is a hybrid of kGraft and kpatch: it uses kGraft's per-task consistency and syscall barrier switching combined with kpatch's stack trace switching." -- [`Documentation/livepatch/livepatch.rst`, kernel.org](https://www.kernel.org/doc/html/latest/livepatch/livepatch.html)
</PullQuote>

The hybrid uses three convergence approaches in sequence: walk every task's stack at a quiescent point (kpatch's stack-check), transition any remaining tasks lazily at kernel-exit (kGraft's per-task), and finally handle idle "swapper" tasks and forked tasks with separate convergence rules. The architecture is gated on [`HAVE_RELIABLE_STACKTRACE`](https://www.kernel.org/doc/html/latest/livepatch/livepatch.html), which is itself a non-trivial per-architecture invariant.

<RunnableCode lang="js" title="Convergence of a hybrid live-patch transition">{`
// Toy simulator of the hybrid livepatch consistency model.
// Each task is in one universe (0 = old, 1 = new). The transition
// finishes when every task has migrated.

function simulate({ nTasks = 100, perTickKernelExit = 0.20, stackCheckPass = 0.60 }) {
  const tasks = Array.from({ length: nTasks }, () => ({ universe: 0, blocked: false }));
  let tick = 0;
  let converged = 0;

  // Phase 1: stack check (kpatch). Migrate every task whose stack does NOT contain
  // a patched function. We model this as a per-task pass probability.
  for (const t of tasks) {
    if (Math.random() < stackCheckPass) {
      t.universe = 1;
      converged++;
    }
  }

  // Phase 2: per-task kernel-exit (kGraft). Each tick, a fraction of remaining
  // tasks transition the next time they cross from kernel to user mode.
  while (converged < nTasks && tick < 1000) {
    tick++;
    for (const t of tasks) {
      if (t.universe === 0 && Math.random() < perTickKernelExit) {
        t.universe = 1;
        converged++;
      }
    }
  }

  return { tick, converged, total: nTasks };
}

const r = simulate({ nTasks: 100, perTickKernelExit: 0.20, stackCheckPass: 0.60 });
console.log('Converged ' + r.converged + '/' + r.total + ' tasks in ' + r.tick + ' ticks');
console.log('Phase 1 (stack check) caught ~60 percent; phase 2 (kernel-exit) caught the rest.');
`}</RunnableCode>

The key insight from this decade and a half of Linux engineering, stated as an empirical observation that has not been overturned: function-level live patching is tractable if and only if you accept that struct-layout changes still require a reboot. Every Linux generation between 2008 and 2026 confirms this rule. Ksplice's [88%](https://dspace.mit.edu/handle/1721.1/51698) is precisely the fraction of patches that happen to leave data structures alone.

While the Linux community was building the hybrid, Microsoft was watching from inside Azure -- and was rebuilding hot patching from scratch on a different foundation.

## 5. The modern mechanism: HPAT, IMAGE_HOT_PATCH_BASE, NtManageHotPatch, and the Secure Kernel

On November 19, 2021, the Windows OS Platform blog published [a piece called "Hotpatching on Windows"](https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541). Buried in the second paragraph is the load-bearing sentence: *"The hotpatch engine requires the Secure Kernel to be running."* That single requirement is the architectural pivot. It is what separates the modern pipeline from the 2003 original, from Ksplice, and from every Linux livepatch design built before or since. It is also the answer to the trust-anchor failure that PLATINUM exploited.

Walk the chain of structures, in the order the kernel walks them. There are six steps.

### 5.1. Compile time: hot-patch metadata into every patchable PE

The target binary is built with hot-patch metadata. The eligible scope, according to the [November 2021 blog](https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541), covers user-mode DLLs and EXEs, kernel-mode drivers, [the hypervisor](/blog/above-ring-zero-how-the-windows-hypervisor-became-a-security/), and the Secure Kernel itself. Modern Microsoft compiler toolchains lay the metadata into a structured table inside the binary; the published reference is the PE optional header's load-config directory.

<Definition term="PE32+ load config directory">
A structure pointed to by the optional header of every modern PE32+ image (`IMAGE_LOAD_CONFIG_DIRECTORY64`). The directory carries security-and-loading configuration that the kernel needs before user-mode code starts running: cookie offsets, CFG and CET metadata, SafeSEH tables, and so on. [Microsoft's reference](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_load_config_directory64) lists `DWORD HotPatchTableOffset;` as a member of this directory in modern Windows SDKs. That single 32-bit RVA is the entry point to every other hot-patch structure described in this section.
</Definition>

### 5.2. Image metadata: the IMAGE_HOT_PATCH_INFO and IMAGE_HOT_PATCH_BASE chain

`HotPatchTableOffset` points at an `IMAGE_HOT_PATCH_INFO` structure. [The Microsoft Rust bindings](https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/SystemServices/struct.IMAGE_HOT_PATCH_INFO.html) document its fields verbatim: `Version`, `Size`, `SequenceNumber`, `BaseImageList`, `BaseImageCount`, `BufferOffset`, `ExtraPatchSize`. The `BaseImageList` is itself an RVA into one or more `IMAGE_HOT_PATCH_BASE` records, with [fields](https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/SystemServices/struct.IMAGE_HOT_PATCH_BASE.html) `SequenceNumber`, `Flags`, `OriginalTimeDateStamp`, `OriginalCheckSum`, `CodeIntegrityInfo`, `CodeIntegritySize`, `PatchTable`, and `BufferOffset`.

The two fields that are doing the real work, semantically, are `OriginalTimeDateStamp` and `OriginalCheckSum`. They name the exact base image to which the patch binds. The HPAT proper -- the Hot Patch Address Table reachable from the `PatchTable` field -- enumerates each patchable site inside the base image: where the prologue lives, what bytes go there, and how to redirect to the replacement function body.

<Definition term="HPAT (Hot Patch Address Table)">
The patch-site table reachable from `IMAGE_HOT_PATCH_BASE.PatchTable`. The HPAT enumerates every individual function-level patch site that a hot patch wants to install in the base image: source RVA, target RVA, byte counts, and any per-site flags the patch engine needs. The Signal Labs reverse-engineering [writeup](https://signal-labs.com/windows-hotpatching-amp-process-injection/) documents the table's structure and the kernel's expectations for it as observed in Windows 11 builds.
</Definition>

<Mermaid caption="The PE32+ metadata chain that locates a hot patch">
flowchart TD
    A[PE optional header] --> B["IMAGE_LOAD_CONFIG_DIRECTORY64"]
    B --> C["HotPatchTableOffset (RVA)"]
    C --> D["IMAGE_HOT_PATCH_INFO\nVersion / Size / SequenceNumber\nBaseImageList / BaseImageCount"]
    D --> E["IMAGE_HOT_PATCH_BASE\nOriginalTimeDateStamp\nOriginalCheckSum\nCodeIntegrityInfo / Size\nPatchTable"]
    E --> F["HPAT entries\nper-function patch sites"]
    F --> G["Replacement function bodies\n(in the patch PE)"]
</Mermaid>

### 5.3. Patch payload: a separate signed PE32+

Each hot patch ships as a [separate signed PE32+ image](https://signal-labs.com/windows-hotpatching-amp-process-injection/). The patch image's own `IMAGE_HOT_PATCH_BASE.OriginalTimeDateStamp` and `OriginalCheckSum` must match the base image's load-time fields exactly. The kernel refuses to apply a hot patch whose binding metadata does not match the running base. This is the binding rule that prevents a hot patch produced for `kernel32.dll` build N from accidentally landing on build N+1.

The patch PE may export a special function `__PatchMainCallout__`. [If present, it is invoked automatically after the patch is loaded in each process](https://signal-labs.com/windows-hotpatching-amp-process-injection/) as a per-process initialization hook -- a hot-patch equivalent of a DLL's `DllMain`.

### 5.4. NtManageHotPatch: the dedicated syscall

The 2003 design overloaded `NtSetSystemInformation(SystemHotpatchInformation)`. The modern design has its own syscall. [The ntdoc reference](https://ntdoc.m417z.com/ntmanagehotpatch) records the signature verbatim:

```c
NTSTATUS NtManageHotPatch(
    _In_      HOT_PATCH_INFORMATION_CLASS HotPatchInformationClass,
    _Out_writes_bytes_opt_(HotPatchInformationLength) PVOID HotPatchInformation,
    _In_      ULONG HotPatchInformationLength,
    _Out_opt_ PULONG ReturnLength
);
```

The same reference notes the syscall's [`PHNT_VERSION >= PHNT_WINDOWS_11`](https://ntdoc.m417z.com/ntmanagehotpatch) availability gate, which corresponds operationally to Windows 11 and Windows Server 2022 and later. The call dispatches on `HotPatchInformationClass` in the style of `NtQuerySystemInformation`, with separate operations to create, activate, map, and list patches.

<Definition term="NtManageHotPatch syscall">
The dedicated NT syscall through which hot patches are managed. Class-dispatched on `HOT_PATCH_INFORMATION_CLASS`, with operations including patch creation, activation, mapping into target processes, and enumeration of currently active patches. [Introduced in the Windows 11 / Server 2022 family](https://ntdoc.m417z.com/ntmanagehotpatch). Unlike the 2003 design, this syscall is the *only* documented entry point to hot patching, which means EDR vendors can instrument it as a discrete operation rather than guessing from `NtSetSystemInformation` parameter blocks.
</Definition>

### 5.5. Trust anchor: the Secure Kernel under HVCI

The pivotal architectural difference. Per [the Windows OS Platform team's November 2021 blog](https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541): the Secure Kernel mediates patch validation and the actual `.text` rewrite. The Secure Kernel is the kernel-side counterpart to [the Isolated User Mode (IUM) trustlet world](/blog/vbs-trustlets-what-actually-runs-in-the-secure-kernel/), running in Virtual Trust Level 1 (VTL1) under VBS, with HVCI enforcing the invariant that executable code pages must be signed by an entity the normal kernel trusts.

> **Note:** HVCI's bedrock invariant is that no code page becomes executable unless it was signed by Microsoft (or a trust chain Microsoft endorses) at attestation time. A hot patch rewrites `.text`. Naively, that breaks the invariant. The architectural escape is that the *new* `.text` came from a signed PE whose signature chains to Microsoft -- and that signature is verified by the Secure Kernel, in VTL1, before the rewrite happens. The normal kernel cannot bypass that verification, because the normal kernel does not perform the rewrite. The Secure Kernel does. This is the structural advance over both Microsoft's 2003 self and over Linux livepatch -- where the same kernel both verifies module signatures and applies the patch. Trust comes from the verifier being architecturally distinct from the verified.

### 5.6. Per-process rollout: ntdll callback and PatchMainCallout

No global stop-the-world. The kernel enumerates running processes and [calls a notification callback inside `ntdll.dll`](https://signal-labs.com/windows-hotpatching-amp-process-injection/) in each process, which re-maps the patched code from a kernel-curated view into the process's address space. If the patch PE exports `__PatchMainCallout__`, that function runs in each process immediately after the patch lands. The per-process model means the patch transition is asynchronous and decentralized; there is no equivalent of Linux's `stop_machine()` quiescence, and no equivalent of kGraft's per-task universe flag. The cost is a more complex security boundary -- the Signal Labs analysis observes that a process can [attempt to load a hot patch repeatedly with a payload that fails validation](https://signal-labs.com/windows-hotpatching-amp-process-injection/), producing a denial-of-service vector against specific target processes if administrative privileges have been compromised.

<Mermaid caption="NtManageHotPatch application sequence">
sequenceDiagram
    actor Admin as Administrator
    participant UM as User-mode caller
    participant NK as Normal kernel
    participant SK as Secure Kernel (VTL1)
    participant Proc as Each running process
    participant NTDLL as ntdll.dll per process

    Admin->>UM: Initiate patch install
    UM->>NK: NtManageHotPatch(class=Activate)
    NK->>SK: Forward patch PE for validation
    SK->>SK: Verify signature, OriginalTimeDateStamp,\nOriginalCheckSum, code-integrity hash
    SK->>SK: Walk HPAT, rewrite .text under HVCI
    SK-->>NK: SUCCESS
    NK->>Proc: Walk processes that mapped the base image
    NK->>NTDLL: Invoke per-process notification callback
    NTDLL->>NTDLL: Re-map patched code into address space
    alt Patch exports __PatchMainCallout__
        NTDLL->>Proc: Invoke __PatchMainCallout__()
    end
    NTDLL-->>NK: Per-process completion
</Mermaid>

### Walking the HPAT chain in code

The chain from optional header to per-function patch site is small enough to walk by hand. The block below is a teaching skeleton: it does not execute against a real PE binary; it shows the field-by-field traversal that a kernel-side validator performs every time `NtManageHotPatch(Activate)` is called.

<RunnableCode lang="js" title="Walking the HPAT chain from IMAGE_LOAD_CONFIG_DIRECTORY64">{`
// Teaching skeleton. The shapes match the public Microsoft documentation
// (ms-image-load-config64, ms-rs-image-hot-patch-info, ms-rs-image-hot-patch-base).
// The structures are populated with placeholder values; a real kernel-side
// validator reads bytes from the on-disk PE and the in-memory image.

function walkPatchChain(peImage) {
  const optionalHeader = peImage.optionalHeader;
  const loadConfig     = peImage.read(optionalHeader.loadConfigRVA, 'IMAGE_LOAD_CONFIG_DIRECTORY64');
  const hpatTableRVA   = loadConfig.HotPatchTableOffset;
  if (!hpatTableRVA) {
    return { eligible: false, reason: 'no HotPatchTableOffset; binary not compiled hotpatchable' };
  }

  const info = peImage.read(hpatTableRVA, 'IMAGE_HOT_PATCH_INFO');
  const bases = [];
  for (let i = 0; i < info.BaseImageCount; i++) {
    const baseOffset = info.BaseImageList + i * peImage.sizeOf('IMAGE_HOT_PATCH_BASE');
    const base = peImage.read(baseOffset, 'IMAGE_HOT_PATCH_BASE');
    bases.push(base);
  }

  // The kernel verifies a patch by matching THIS image's OriginalTimeDateStamp
  // and OriginalCheckSum against the patch PE's corresponding fields. If they
  // mismatch, the kernel refuses the patch with STATUS_HOT_PATCH_FAILED.
  return {
    eligible: true,
    info,
    bases,
    bindingFields: bases.map(b => ({
      stamp: b.OriginalTimeDateStamp,
      checksum: b.OriginalCheckSum,
      patchTableRVA: b.PatchTable
    }))
  };
}
`}</RunnableCode>

### The three architectural differentiators

Three differences from the 2003 design, stated bluntly because they are the load-bearing distinctions:

1. **Dedicated `NtManageHotPatch` syscall instead of overloaded `NtSetSystemInformation`.** Distinct attack surface, instrumentable separately, with its own access-control rules.
2. **Signed PE32+ patch images verified by the Secure Kernel, not bare driver-signing on a `.hotp1` payload.** The verifier sits in VTL1, architecturally distinct from the kernel that holds the `.text` mapping.
3. **HPAT metadata baked into every patchable binary at compile time, not a single-flag prologue plus `.hotp1` section pair.** The metadata names the patchable sites individually, with a per-site flag vocabulary that admits future operations the 2003 engine could not represent.

> **Key idea:** The Secure Kernel is the load-bearing innovation, not HPAT. HPAT is mechanism -- a structurally cleaner version of the 2003 metadata, with per-site flags and binding fields the older format did not have. The architectural advance is that HVCI's "executable pages were signed" invariant is preserved across a hot patch *because* the new pages came from a signed PE whose signature chains to Microsoft *and* the normal kernel cannot bypass that verification. Linux livepatch trusts the standard module-signing policy enforced by the kernel it is patching. Microsoft's modern design moves the verifier into a different, architecturally isolated kernel.

The mechanism is now complete. What remains is the pipeline around it.

## 6. The three-stack decomposition: mechanism, delivery, management

There is no single thing called "Windows hot patching." There are three layers that look like one thing if you squint -- and explaining them as one thing is the most common pedagogical mistake in this space. Each layer has its own engineering team, its own failure modes, its own primary documentation. Treat them in order.

**Layer A -- the kernel mechanism.** Everything in §5: HPAT, `IMAGE_HOT_PATCH_BASE`, `NtManageHotPatch`, and the Secure Kernel. Microsoft documents Layer A unevenly. The structure definitions are public via the Rust windows-docs bindings ([`IMAGE_HOT_PATCH_INFO`](https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/SystemServices/struct.IMAGE_HOT_PATCH_INFO.html), [`IMAGE_HOT_PATCH_BASE`](https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/SystemServices/struct.IMAGE_HOT_PATCH_BASE.html)) and the [`IMAGE_LOAD_CONFIG_DIRECTORY64` reference](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_load_config_directory64). The syscall signature is in the [community-maintained `ntdoc` reference](https://ntdoc.m417z.com/ntmanagehotpatch). The most thorough public field-level documentation of the runtime behavior is [Signal Labs' reverse-engineering writeup](https://signal-labs.com/windows-hotpatching-amp-process-injection/) and an independent [PoC repository](https://github.com/chc/NtManageHotpatchTests) that exercises the syscall. There is no equivalent of the kernel.org `Documentation/livepatch/livepatch.rst` file inside Microsoft's official docs.

**Layer B -- the servicing model.** This is where the operational pipeline lives. The Microsoft Learn reference for [Hotpatch on Windows Server](https://learn.microsoft.com/en-us/windows-server/get-started/hotpatch) describes the cadence verbatim: hot patching first establishes a baseline with the current Cumulative Update for Windows Server, and every three months that baseline refreshes with the latest Cumulative Update. Between baselines, two hotpatch-only releases ship: months in which the only payload is the security-update delta as a signed hot-patch PE.

<Definition term="LCU and SSU">
**LCU**: Latest Cumulative Update. The single, full security-and-quality update bundle that Microsoft has issued monthly for Windows since the 2016 cumulative-update model. An LCU contains the union of all security fixes since the previous baseline, and applying it always requires a reboot because it lays down replacement binaries on disk and rebinds the running kernel.

**SSU**: Servicing Stack Update. A specialized monthly update to the component that *applies* updates (`wusa.exe`, `usoclient.exe`, the Windows Update agent state machine). SSUs cannot ship as hot patches because they update the patcher itself. They are part of the reason "unplanned baselines" exist: a month in which security content cannot ship as a hot patch falls back to a regular LCU.
</Definition>

There are two types of baselines, again per [Microsoft Learn](https://learn.microsoft.com/en-us/windows-server/get-started/hotpatch). *Planned baselines* are the quarterly LCU drops that follow the cumulative-update cadence -- one each January, April, July, October. *Unplanned baselines* preempt a hotpatch month when the month's security content cannot ship as a hot patch: a kernel struct-layout change, a driver update, an SSU, a language-pack update, or any security fix in a non-hotpatchable component. The promise is that the channel [maintains parity with the content of security updates issued to the regular non-Hotpatch Windows update channel](https://learn.microsoft.com/en-us/windows-server/get-started/hotpatch). Customers who run hot patching are not getting a curated subset of fixes. They are getting the same fix set, in a different delivery mode.

<Mermaid caption="Quarterly servicing cadence: 4 reboots per year instead of 12">
gantt
    title Windows Hotpatch servicing cadence
    dateFormat YYYY-MM-DD
    axisFormat %b
    section Servicing
    Planned baseline LCU (reboot)  :crit, b1, 2026-01-01, 30d
    Hotpatch only                  :h1, 2026-02-01, 30d
    Hotpatch only                  :h2, 2026-03-01, 30d
    Planned baseline LCU (reboot)  :crit, b2, 2026-04-01, 30d
    Hotpatch only                  :h3, 2026-05-01, 30d
    Hotpatch only                  :h4, 2026-06-01, 30d
    Planned baseline LCU (reboot)  :crit, b3, 2026-07-01, 30d
    Hotpatch only                  :h5, 2026-08-01, 30d
    Hotpatch only                  :h6, 2026-09-01, 30d
    Planned baseline LCU (reboot)  :crit, b4, 2026-10-01, 30d
    Hotpatch only                  :h7, 2026-11-01, 30d
    Hotpatch only                  :h8, 2026-12-01, 30d
</Mermaid>

The reboot frequency on a hot-patch-eligible fleet drops from 12 a year to 4 a year, [per Microsoft's April 24, 2025 Windows Server blog](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/). That 3:1 reduction is the operational claim. It is conditional on the fleet being eligible every month -- on no month's security content being non-hotpatchable -- so the realized reduction depends on which CVEs Microsoft has to fix in any given quarter.

**Layer C -- the management plane.** Layer C is where compliance, telemetry, ring-based rollout, eligibility detection, and fallback behavior live. There are three management surfaces for the three product variants:

- **Azure Update Manager** for Azure VMs running Server 2022 Datacenter: Azure Edition and Server 2025 Datacenter: Azure Edition. The control plane is built into the VM SKU; onboarding is a SKU selection and an update-management association.
- **Intune Autopatch** for Windows 11 Enterprise 24H2 clients. [The Microsoft Learn doc for Autopatch hot patching](https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates) lays out the license requirements (Windows 11 Enterprise E3/E5, Microsoft 365 F3, Education A3/A5, M365 Business Premium, or Windows 365 Enterprise), the prerequisite that VBS must be turned on, and the silent-fallback behavior for ineligible devices: a Hotpatch-policy-enrolled device that does not meet the prerequisites simply receives the regular LCU instead.
- **Azure Arc Hotpatch** for Server 2025 outside Azure. The connection to Azure Arc is the delivery channel; the meter that runs at $1.50 per CPU core per month [is operationalized through Arc](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/).

Telemetry is a property of Layer C. The kernel patch engine reports per-process completion to the normal kernel; the normal kernel reports per-machine completion to whichever Layer C surface is in charge of that machine. Conflating "the kernel reports patch success" with "Microsoft is telemetering my workload" is wrong in the same way conflating Layer A with Layer C is wrong.

<Mermaid caption="Three-layer decomposition of the Windows hot-patch pipeline">
flowchart LR
    subgraph LayerA["Layer A: Kernel mechanism"]
        A1["HPAT + IMAGE_HOT_PATCH_BASE"]
        A2["NtManageHotPatch syscall"]
        A3["Secure Kernel under HVCI"]
        A1 --> A2 --> A3
    end
    subgraph LayerB["Layer B: Servicing model"]
        B1["Quarterly baseline LCU"]
        B2["2 hotpatch-only months between baselines"]
        B3["Unplanned baselines for non-hotpatchable content"]
        B1 --> B2 --> B3
    end
    subgraph LayerC["Layer C: Management plane"]
        C1["Azure Update Manager (Server, Azure)"]
        C2["Intune Autopatch (Win11 24H2 clients)"]
        C3["Azure Arc Hotpatch (Server 2025, outside Azure)"]
    end
    LayerC --> LayerB --> LayerA
</Mermaid>

So: what is hot-patchable? Per [the Microsoft Learn Hotpatch Autopatch documentation](https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates), Hotpatch updates are [Monthly B-release security updates that install and take effect without requiring you to restart the device](https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates). And what is not?

| Hot-patchable | Not hot-patchable |
|---|---|
| Security updates to function bodies inside hotpatch-compiled PEs | Updates that change the layout, size, or invariants of static data structures |
| User-mode DLLs and EXEs compiled with hot-patch metadata | Drivers, including ELAM drivers |
| Kernel-mode drivers compiled with hot-patch metadata | Boot loader components |
| The hypervisor and the Secure Kernel itself | Secure-Launch / DRTM measurement-scoped binaries |
| Win11 24H2 Enterprise B-release security updates on eligible (VBS-on, non-CHPE) devices | Servicing Stack Updates (the patcher patches itself) |
| | Language pack updates |
| | Defender platform updates outside the OS channel |
| | .NET updates outside the OS channel |
| | Any update issued outside the dedicated Hotpatch channel |

On Arm64 Win11 24H2 clients, [Hotpatch is additionally incompatible with servicing CHPE OS binaries](https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates) located in `%SystemRoot%\SyChpe32`. Operators who depend on CHPE for x86-on-Arm64 app compatibility cannot enable Hotpatch on those devices today.

<PullQuote>
"The experience is so seamless you don't even know what happened. There are no process restarts, no logging out, no performance impact. No glitch in the video playing or transaction dropping. Everything just works as if nothing has happened." -- [Nevine Geissa, Partner Group PM, Windows Servicing and Delivery, Microsoft Inside Track](https://www.microsoft.com/insidetrack/blog/transforming-security-and-compliance-at-microsoft-with-windows-hotpatch/)
</PullQuote>

Three layers, three failure modes. The Linux side of the story made different choices at each. The next section does the head-to-head along the axes that actually matter.

## 7. Windows hot patching vs Linux livepatching: different primitives, same problem

Two well-engineered systems. One shared goal. Four divergent answers. The comparison is not "Windows is better" or "Linux is better." The comparison is that each design made specific architectural choices that follow logically from preconditions the other system did not have.

| Axis | Windows Modern Hotpatch | Linux livepatch (in-tree, hybrid) |
|---|---|---|
| Redirection primitive | In-place `.text` rewrite of a signed PE image directed by HPAT | ftrace `mcount`/`fentry` trampoline redirecting callers to a replacement function loaded as a kernel module |
| Consistency model | Per-process notification callback in `ntdll`, no global pause | Hybrid: per-task (kGraft) + stack-trace (kpatch) + kernel-exit + idle "swapper" task + forced-signal fallback |
| Trust anchor | Secure Kernel signature validation under HVCI in VTL1 | Kernel module signing policy enforced by the same kernel being patched |
| Scope | User-mode DLLs/EXEs, kernel drivers, hypervisor, Secure Kernel itself | Kernel only (Oracle Ksplice adds glibc/OpenSSL user-mode on Oracle Linux Premier Support) |
| Cadence and pricing | Quarterly baseline + 2 hotpatch months; free on Azure IaaS, paid Arc subscription outside Azure ($1.50/core/month for Server 2025) | Ad-hoc per-CVE; distribution-included pricing on RHEL/SLES/Ubuntu/Oracle Linux |

The trust-anchor row is the load-bearing one. Linux's [in-tree livepatch documentation](https://www.kernel.org/doc/html/latest/livepatch/livepatch.html) describes the consistency model in considerable detail; it describes the kernel-module-signing policy in less detail because the policy is the same one Linux uses for any kernel module. The verifier is the kernel itself. If an attacker who has obtained the necessary capability to install kernel modules can also forge or replace the module-signing key, the verifier is downstream of the attacker. Windows's design moves the verifier behind an architectural boundary. The normal kernel that mediates the syscall does not perform the verification. The Secure Kernel does, in VTL1, behind a hypervisor that the normal kernel cannot subvert without first compromising the Secure Kernel directly.

The redirection row is the next most consequential. The Linux design uses ftrace trampolines because ftrace had already solved the safe-rewriting problem inside Linux when kpatch and kGraft started. Layering live patching on top of ftrace meant the live-patcher's mechanical scope was small: "redirect callers of this function." The Windows design rewrites the function prologue directly with an instruction-sized atomic write. The two primitives have different failure modes. ftrace adds a permanent indirection cost to every traced function on the system; the in-place rewrite has zero steady-state cost but a more complex one-time write.

<Mermaid caption="Linux consistency-model decision flow">
flowchart TD
    Start["Start: install patch P"] --> Phase1&#123;"Phase 1: stack check (kpatch)"&#125;
    Phase1 -- "Task's stack clean" --> Migrate1["Migrate task to new universe"]
    Phase1 -- "Patched fn on stack" --> Phase2&#123;"Phase 2: wait for kernel-exit (kGraft)"&#125;
    Phase2 -- "Task crosses kernel-exit" --> Migrate2["Migrate at exit"]
    Phase2 -- "Stuck in kernel" --> Phase3&#123;"Phase 3: idle-loop + forced-signal fallback"&#125;
    Phase3 -- "Idle swapper" --> Migrate3["Migrate idle task"]
    Phase3 -- "kthread" --> Special["Reliable-stacktrace gate; kthreads remain hard"]
    Migrate1 --> Done["Patch live for task"]
    Migrate2 --> Done
    Migrate3 --> Done
</Mermaid>

The scope row tells a related story. The November 2021 Windows OS Platform blog explicitly says Windows hot patches can target [user-mode binaries, drivers, the hypervisor, and the Secure Kernel itself](https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541). Linux's `livepatch` is kernel-only by design; Oracle's Ksplice has user-mode add-ons for glibc and OpenSSL [available to Oracle Linux Premier Support customers](https://web.mit.edu/ksplice/), but no other mainstream Linux live-patcher covers user-mode. The Windows choice to cover user-mode is operationally significant: many high-impact security fixes target services that run in `lsass.exe`, `svchost.exe`, or product-specific user-mode daemons, and Linux's userspace equivalent of those fixes still requires the affected processes to be restarted.

<Sidenote>The kpatch project [entered maintenance mode as of Linux 6.19](https://github.com/dynup/kpatch); new live-patch builds are now expected to use the upstream `klp-build` script in `scripts/livepatch/`. The kpatch project isn't gone -- the runtime remains, the build tooling is migrating into the tree.</Sidenote>

A brief tour of what is going on in the field today. **Ksplice** is [Oracle-Linux-Premier-Support-only](https://web.mit.edu/ksplice/) since the 2011 acquisition, with the glibc/OpenSSL user-mode coverage being the most distinctive remaining feature. **kpatch** is in maintenance mode; the build tooling has been promoted into the kernel tree as `klp-build`, and the project's [GitHub README](https://github.com/dynup/kpatch) documents the deprecation explicitly. **kGraft** survives as an out-of-tree front-end primarily for SUSE customers, with the relevant consistency-model logic having been merged into the in-tree hybrid years ago. **Windows Modern Hotpatch** is the system this article is about.

Both systems work. Both have ceilings. The next section is where the ceiling actually is.

## 8. The theoretical ceiling: what no function-replacement system can ever do

Every live-patching system on Earth ships with the same warning, in different words. There is a class of patches that none of them can apply. The class is well-defined and the explanation is not engineering -- it is logic.

**Data-layout changes.** A patch that changes the layout, size, or invariants of any static data structure read or written by code not also being patched in the same transaction breaks every function-replacement live-patcher. Ksplice's [88% headline](https://dspace.mit.edu/handle/1721.1/51698) is precisely the fraction of patches that *happen to* leave data structures alone. The 12% that does not is what every live-patching design defers to reboot.

The reason is structural. Suppose a kernel struct `foo` has fields `(a, b, c)` and the patch wants to add a field `d`. Every function that reads or writes a `foo` operates on the old layout; new functions added by the patch operate on the new layout. The transition window contains threads in flight that hold pointers into the old struct, and any new code that allocates or writes a `foo` would corrupt them. The general algorithmic question -- "can this layout change be applied safely to an arbitrary running kernel?" -- is undecidable in the general case, because deciding it is equivalent to deciding what an arbitrary running program's memory invariants are.

> **Note:** Rice's theorem says that every non-trivial semantic property of a program is undecidable. The property "this layout change is safe on the running kernel" is non-trivial and is a semantic property of the running program. Therefore no general algorithm decides it. Ksplice's shadow-data-member trick handles the easy case (additive-only fields) by allocating the new field out-of-band per object; it works because additive changes have a closed-form correctness argument. The hard cases -- changing field types, changing alignment, reordering, removing a field used elsewhere -- have no closed-form argument, and no live-patcher ever invented one.

**Boot-anchored measurements.** ELAM (Early Launch Anti-Malware) drivers, DRTM (Dynamic Root of Trust for Measurement) and Secure Launch components, and other measurement-scoped binaries have their hashes [extended into TPM PCRs at boot](/blog/measured-boot-the-tcg-event-log-from-srtm-to-pcr-bound-bitlo/). A hot patch that mutates such a binary after attestation breaks the post-attestation invariant: the verifier downstream of the attestation expected a measured value that no longer corresponds to the running binary. The post-rewrite memory is *not* inside the original attestation envelope; the attestation has to be re-rooted, which requires a reboot. Microsoft's exclusion list reflects this -- drivers (including ELAM), boot-loader components, and Secure Launch / DRTM measurement-scoped binaries are not hot-patchable in the [published servicing model](https://learn.microsoft.com/en-us/windows-server/get-started/hotpatch).

**Inlined or always-on-stack code.** Function-replacement systems require a single entry point per logical function. A function that has been inlined into every caller has no entry point to patch. A function that is always somewhere on a stack -- kpatch's classic examples of `schedule()`, `do_wait()`, and `irq_thread()` -- effectively behaves as if inlined for the purpose of the live-patcher, because the stack-check phase can never converge on a quiescent moment. LWN's coverage estimated [a few dozen such functions on a typical Linux kernel](https://lwn.net/Articles/597407/); the equivalent class for Windows is the never-quiescent kernel entry points that one cannot patch without first taking the system out of operation.

**Concurrency invariants.** Lock-free algorithms, RCU readers in flight, and code execution orderings that the patch quietly changes require quiescence beyond what any function-replacement primitive offers. The [Linux livepatch consistency-model debate at LWN 634649](https://lwn.net/Articles/634649/) and the [kernel.org `livepatch.rst` §7 "Limitations"](https://www.kernel.org/doc/html/latest/livepatch/livepatch.html) document this class of constraint: a patch that subtly changes the order of memory operations in a function that participates in a lock-free protocol can leave readers observing impossible states across the transition. The literature on this is mostly cautionary, not exhaustive; the live-patcher's job is to assume any patch that touches concurrent code is unsafe by default and require the patch author to argue otherwise.

The empirical upper bound, again, is the Ksplice 88% number from a finite window of x86-32 Linux security patches between May 2005 and May 2008. Microsoft has not published a comparable automation-rate study for the modern Windows pipeline; the public claim is that the channel [maintains parity with the content of security updates](https://learn.microsoft.com/en-us/windows-server/get-started/hotpatch) issued to the regular non-Hotpatch channel, with unplanned baselines preempting hotpatch months when the content is not eligible. That is an operational claim, not a percent-of-CVEs measurement.

> **Key idea:** The ceiling on every live-patching system is Rice's theorem applied to memory-layout semantics. No general algorithm decides whether an arbitrary data-layout change is safe to apply to an in-flight program; therefore every live-patcher treats data-layout changes the same way -- defer to reboot. The 12% that remains is the open research problem live-patching has been carrying for 18 years; Ksplice's 88% set the ceiling no successor has moved.

The remaining 12% is the problem of the next generation. The open problems are the subject of §9.

## 9. Open problems: where the pipeline is still evolving

Hot patching is "done" only in the sense that it ships. Four problems remain open as of May 2026.

### 9.1. Confidential VMs and the attestation envelope

[AMD SEV-SNP](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview) and [Intel TDX](https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/overview.html) provide a measured launch of a guest VM image attested to a relying party. Microsoft's own Azure confidential-VM documentation states the contract verbatim: ["Azure confidential VMs boot only after successful attestation of the platform's critical components and security settings"](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview), and an in-VM workload can issue an attestation request to "verify that your confidential VMs are running a hardware instance with either AMD SEV-SNP, or Intel TDX enabled processors." The attestation establishes that a specific image -- byte for byte, hash for hash -- is what is running inside the confidential VM. If `NtManageHotPatch` later rewrites guest `.text`, is the post-rewrite memory inside the attestation envelope? Does the relying party need to re-verify? Microsoft has not publicly documented this interaction. The hot-patch [SKU eligibility list](https://learn.microsoft.com/en-us/windows-server/get-started/hotpatch) covers Server 2022 and Server 2025 Datacenter: Azure Edition; confidential VM SKUs run on adjacent Azure infrastructure; the documented intersection is a gap. Framed as a documented gap, not speculated beyond.

### 9.2. The subscription metering question

$1.50 per CPU core per month for Server 2025 hot patching over Azure Arc is the [first time a major OS vendor has metered live patching with a per-CPU-core meter](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/) rather than per-machine (Canonical Livepatch via Ubuntu Pro) or per-CPU-pair (Oracle Ksplice bundled into Oracle Linux Premier Support). Azure Arc is itself a management plane, so the framing is "metered, per-core, on a management plane" rather than "metered outside any subscription tier." [Forbes' coverage](https://www.forbes.com/sites/daveywinder/2025/04/30/microsoft-confirms-150-windows-security-update-fee-starts-july-1/) confirms the pricing and the July 1, 2025 GA. The economic question -- does pricing accelerate or decelerate patch adoption across the global Windows Server fleet? -- has no public data yet. The fairness question -- should faster patching cost more, when faster patching makes the world safer? -- has no answer that does not depend on assumptions about which fleets are doing the patching.

### 9.3. Detection and abuse of the same primitive

Signal Labs has shown that the same `NtManageHotPatch` mechanism can [be repurposed for in-memory code injection PoCs under specific privilege conditions](https://signal-labs.com/windows-hotpatching-amp-process-injection/); an independent [PoC repository](https://github.com/chc/NtManageHotpatchTests) corroborates by exercising the syscall against a controlled target. The risk is structurally similar to the 2003-era hot-patch abuse Microsoft disclosed in April 2016, but with two important differences: the modern path requires the Secure Kernel to validate a signed payload (the 2003 path did not), and operators have an explicit registry knob -- [`HotPatchRestrictions=1` at `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`](https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates) -- documented as the way to disable CHPE servicing on Arm64 so those devices remain eligible for hot patching. EDR vendors who want to distinguish legitimate Microsoft-signed hot patches from hostile injection have to instrument both the syscall and the registry state. This is solvable, but it is not solved by default in every EDR.

### 9.4. Arm64 client porting and CHPE

[Arm64 Windows 11 24H2 hot patching](https://techcommunity.microsoft.com/blog/windows-itpro-blog/hotpatch-for-windows-client-now-available/4399808) remains in preview as of the April 2025 GA for x64, with the [CHPE compatibility issue](https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates) acting as the visible technical gate.

<Sidenote>The CHPE constraint is documented at Microsoft Learn verbatim: [Hotpatch updates are not compatible with servicing CHPE OS binaries located in the `%SystemRoot%\SyChpe32` folder](https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates). CHPE (Compiled Hybrid Portable Executable) is the format Windows uses to speed up x86 applications on Arm64 by inlining native Arm64 code into x86 binaries. The hot-patch metadata format and the CHPE format have an unresolved interaction in the current toolchain.</Sidenote>

The Linux equivalent of the Arm64 porting story is the [`HAVE_RELIABLE_STACKTRACE` gate](https://www.kernel.org/doc/html/latest/livepatch/livepatch.html) and the related kthread caveats. Kthreads on architectures without reliable stack-trace support remain a hard case for the in-tree hybrid consistency model.

For an operator deciding *today* which of these open problems matters, the answer depends on which of the three Windows products is theirs. The next section is the practical decision tree.

## 10. The operator's decision: adopting hot patching in 2026

The operator question is not "should I hot-patch?" but "which of the three products is mine and what does it actually cost?" Walk through the tree.

### 10.1. Windows Server 2022 Datacenter: Azure Edition

Free on Azure IaaS. The product was [announced as generally available on February 16, 2022](https://techcommunity.microsoft.com/blog/itopstalkblog/announcing-general-availability-of-hotpatch-for-windows-server-2022-azure-editio/3168095) (this is also confirmed by a [contemporaneous external mirror](https://thewindowsupdate.com/2022/02/16/announcing-general-availability-of-hotpatch-for-windows-server-2022-azure-edition/)). Onboarding is a SKU selection (`-Hotpatch` suffix variants), an Azure Update Manager association, and a baseline alignment to the current LCU. The Server 2022 hotpatch initially shipped Server-Core-only; the [Desktop Experience GA on July 18, 2023](https://techcommunity.microsoft.com/blog/windowsservernewsandbestpractices/hotpatching-is-now-available-for-windows-server-vms-on-azure-with-desktop-experi/3875003) removed the operationally-large adoption blocker for admins who refused Server Core. From that date forward, all common Server 2022 Azure Edition VM configurations are hot-patch-eligible.

### 10.2. Windows Server 2025 Datacenter / Standard via Azure Arc

$1.50 USD per CPU core per month outside Azure, [generally available since July 1, 2025](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/). Free on Azure IaaS / Azure Local for Server 2025 Datacenter: Azure Edition VMs. The math at $1.50/core/month is mechanical: a 128-core machine is $192/month or $2,304/year for the hot-patch subscription; an eight-machine 128-core cluster is $18,432/year. Whether that price is justified depends on the operator's per-reboot cost.

<Aside label="How operators should think about the $1.50/core/month math">
This is not a CFO-style break-even calculation -- the inputs differ too much across organizations to make a one-line answer useful. The framing question is: what does a reboot actually cost in your fleet? Revenue downtime during the maintenance window, on-call coordination overhead, the deferred-patch security risk created by the inevitable delay between Patch Tuesday and the night the operations team is willing to schedule the reboot. [Microsoft Inside Track](https://www.microsoft.com/insidetrack/blog/transforming-security-and-compliance-at-microsoft-with-windows-hotpatch/) quantifies Microsoft Digital's own number; every operator has to compute their own. A useful first-pass formula is below.
</Aside>

<RunnableCode lang="js" title="Hot-patch vs reboot: break-even calculator">{`
// Per-fleet break-even calculator. Inputs are organization-specific.
// The function returns whether the Arc hot-patch subscription is cheaper
// than the cost of the avoided reboots, assuming 8 hot-patch months a year
// (4 reboots/year baseline vs 12 without hot patching).

function breakEven({ cores, perCoreMonthly = 1.50,
                     rebootsAvoidedPerYear = 8,
                     costPerRebootEvent,
                     fleetSize = 1 }) {
  const subscriptionAnnual = cores * perCoreMonthly * 12 * fleetSize;
  const avoidedRebootCost  = costPerRebootEvent * rebootsAvoidedPerYear * fleetSize;
  return {
    subscriptionAnnual,
    avoidedRebootCost,
    netSavings: avoidedRebootCost - subscriptionAnnual,
    worthIt: avoidedRebootCost > subscriptionAnnual
  };
}

// Example: a 128-core box, 100-machine fleet, $1,200 per reboot event
// (coordination, downtime, ops overhead). 8 hotpatch months avoided per year.
const r = breakEven({
  cores: 128, fleetSize: 100, costPerRebootEvent: 1200, rebootsAvoidedPerYear: 8
});
console.log('Subscription annual: $' + r.subscriptionAnnual.toLocaleString());
console.log('Avoided reboot cost: $' + r.avoidedRebootCost.toLocaleString());
console.log('Net savings        : $' + r.netSavings.toLocaleString());
console.log('Worth it           : ' + r.worthIt);
`}</RunnableCode>

> **Note:** The formula is: subscription cost = `cores x $1.50 x 12 x fleet_size`. The avoided reboot cost is `cost_per_reboot_event x rebootsAvoided x fleet_size`. The intersection is your decision point. The most-underestimated input is the coordination cost of scheduling the reboot window across multiple operations teams in regulated organizations -- it is rarely zero and is often the largest single line item.

### 10.3. Windows 11 Enterprise 24H2 client

License-gated through Intune Autopatch. The license bar, per [Microsoft Learn](https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates), is one of Windows 11 Enterprise E3/E5, Microsoft 365 F3, Education A3/A5, M365 Business Premium, or Windows 365 Enterprise. VBS must be on. Ineligible devices (VBS off, CHPE binaries present on Arm64, or any other policy mismatch) silently fall back to LCU; the device's user experience is unchanged except that hot-patch months still require the usual monthly reboot. Hot patching is staged via Intune Autopatch quality update policy with the hot-patch toggle enabled; eligibility detection runs per device. The [Bleeping Computer coverage of the April 2025 client GA](https://www.bleepingcomputer.com/news/microsoft/microsoft-adds-hotpatching-support-to-windows-11-enterprise/) cross-confirms the dates and the licensing model.

[The Autopatch default-on flip](https://techcommunity.microsoft.com/blog/windows-itpro-blog/securing-devices-faster-with-hotpatch-updates-on-by-default/4500066) turns hot patching into the default for eligible Windows 11 24H2 Enterprise devices in the May 2026 servicing cycle; opt-out controls become effective on April 1, 2026 for organizations that need to delay the transition.

### 10.4. Operational rules that apply to all three

- **Quarterly baseline alignment is non-negotiable.** A machine that drifts off the current quarterly baseline cannot consume the next hot-patch month; it falls back to a full LCU until it realigns.
- **Unplanned baselines preempt hot-patch months for un-hotpatchable security content.** Operators cannot opt out of an unplanned baseline. The fix Microsoft has to ship for a kernel-struct-changing zero-day will land as a reboot-requiring LCU regardless of Hotpatch policy.
- **Monitor patch state via the management plane.** Azure Update Manager (Server, Azure), Intune Autopatch dashboards (clients), and Arc Hotpatch (Server outside Azure) each report per-device or per-VM patch state. Alert on baseline drift; alert on Hotpatch-policy-enrolled devices that have silently fallen back to LCU.

<Sidenote>Microsoft Digital's compliance numbers are the best public dataset on real-world hot-patch adoption: [81% compliance within 24 hours; 90% within 5 days; 95% within 3 weeks across 4.5 million devices since Windows 11 24H2 GA in April 2025](https://www.microsoft.com/insidetrack/blog/transforming-security-and-compliance-at-microsoft-with-windows-hotpatch/). The Xbox team's reduction was from "weeks down to just a couple of days." These are best-case numbers from a deeply Microsoft-fluent operations org; they are achievable, not universal.</Sidenote>

<Aside label="Compliance framing: regulated-fleet implications">
For operators under NIST, HIPAA, PCI, or SOX-style controls, "patched but not rebooted" is a status that did not cleanly exist in audit frameworks five years ago. Hot patching changes what "patched" means in a way that some auditor checklists were not written for. Operators in regulated environments should clear the new patch state with their auditor before depending on it for compliance reporting. The mechanism is sound; the audit framework's recognition of it is the operational variable.
</Aside>

<Spoiler kind="solution" label="Quick PowerShell to verify a device's hot-patch eligibility">
On a Win11 24H2 Enterprise client, the eligibility surface is partly visible via the `HotPatchRestrictions` registry key (Autopatch policy state), the VBS status (`Get-CimInstance -ClassName Win32_DeviceGuard | Select-Object SecurityServicesRunning, VirtualizationBasedSecurityStatus`), and the current servicing baseline build. Combining the three -- VBS on, Hotpatch policy enrolled, current quarterly baseline applied -- predicts whether the next month's release will land as a hot patch or as an LCU.
</Spoiler>

The remaining questions are the ones every reader hits. The FAQ is next.

## 11. Frequently asked questions

<FAQ title="Frequently asked questions">

<FAQItem question="Is Windows hot patching just kpatch for Windows?">
No. The mechanism is different (in-place `.text` rewrite of a signed PE image directed by HPAT, instead of an ftrace `mcount` trampoline redirecting callers to a replacement function). The trust anchor is different (the Secure Kernel in VTL1 under HVCI, instead of the kernel module-signing policy enforced by the same kernel being patched). The scope is different (user-mode DLLs and EXEs, drivers, the hypervisor, and the Secure Kernel itself, vs kernel-only on Linux mainline). The consistency model is different (per-process callback in `ntdll`, no global pause, vs Linux's [hybrid kGraft + kpatch + idle-loop + forced-signal model](https://www.kernel.org/doc/html/latest/livepatch/livepatch.html)). The two systems solve the same operational problem with structurally different primitives.
</FAQItem>

<FAQItem question="Does Windows hot patching eliminate reboots?">
No. Per [Microsoft's April 2025 Windows Server blog](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/), reboots drop from 12 a year to 4 a year on eligible fleets. The four quarterly baseline LCUs remain mandatory. Unplanned baselines (kernel struct changes, SSUs, drivers, language packs, any non-hotpatchable security content) preempt hot-patch months and require a reboot.
</FAQItem>

<FAQItem question="Can third-party drivers be hot-patched?">
No. [Drivers are excluded from the Hotpatch envelope](https://learn.microsoft.com/en-us/windows-server/get-started/hotpatch), including ELAM drivers and boot-loader components. Driver updates that ship as security fixes will land via the regular LCU on the next quarterly baseline (or sooner, as an unplanned baseline).
</FAQItem>

<FAQItem question="Why does this cost money on Server 2025 outside Azure?">
Microsoft frames Azure Arc as the delivery channel for Server 2025 hot patching outside Azure and [meters the subscription at $1.50 USD per CPU core per month](https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/). On Azure IaaS and Azure Local for Server 2025 Datacenter: Azure Edition VMs, hot patching is free. The Arc subscription is the first time a major OS vendor has metered live patching with a per-CPU-core meter (Canonical Livepatch is priced per machine; Oracle Ksplice is bundled into Oracle Linux Premier Support priced per CPU pair). The economic case is fleet-dependent and is the subject of §10.
</FAQItem>

<FAQItem question="Is HVCI / VBS mandatory?">
In practice, yes. The Windows OS Platform team's [November 2021 blog](https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541) is explicit: the hotpatch engine requires the Secure Kernel to be running. [The Autopatch documentation](https://learn.microsoft.com/en-us/windows/deployment/windows-autopatch/manage/windows-autopatch-hotpatch-updates) extends the requirement to clients: VBS must be turned on for a device to be offered Hotpatch updates. Server 2025 / Server 2022 Azure Edition treat the Secure Kernel as load-bearing for patch validation. VBS-off devices silently fall back to LCU.
</FAQItem>

<FAQItem question="Wasn't Server 2003 hotpatching already a thing?">
Yes, technically. The Server 2003 SP1 hot-patch engine shipped via the `/hotpatch` compile flag, [`.hotp1` PE sections](https://www.openrce.org/articles/full_view/22), and `NtSetSystemInformation(SystemHotpatchInformation)` (as walked through in [Johannes Passing's 2011 reverse-engineering writeup](https://jpassing.com/2011/05/03/windows-hotpatching-a-walkthrough/)). It was operationally rare, never had a trust anchor architecturally distinct from the kernel code it mutated, and was [first publicly documented as an APT code-injection primitive in Microsoft's April 2016 PLATINUM report](https://thehackernews.com/2016/04/windows-hotpatching-malware.html) (PLATINUM as a group dates to 2009; the exact start date for its hot-patch tradecraft is not in the public record). The modern pipeline is a 17-year revival on a different foundation -- a dedicated syscall, signed PE32+ patch images, and verification by the Secure Kernel in VTL1.
</FAQItem>

</FAQ>

Hot patching is a pipeline, not a feature. The mechanism Microsoft shipped in February 2022 is older than the public product; the real engineering work between 2003 and 2022 was the trust anchor (the Secure Kernel under HVCI, mature only after 2015), the servicing discipline (cumulative-update model from 2016, hot-patch / baseline cadence from 2022), and the management plane (Azure Update Manager, then Intune Autopatch, then Azure Arc, each a separate operations product layered on the same kernel engine). The mechanism is the easy part. The hard part is the architecture around it that makes in-memory mutation safe to operate at fleet scale.

Whether $1.50 per CPU core per month is worth it for your fleet is a math problem you can now do. Whether the Confidential VM attestation interaction gets cleanly documented before the next product wave is somebody else's problem. The compiler flag has not changed in 30 years. Everything around it has.

<StudyGuide slug="hot-patching-in-windows" keyTerms={[
  { term: "HPAT", definition: "Hot Patch Address Table; the per-function patch-site table inside IMAGE_HOT_PATCH_BASE.PatchTable, enumerating each individual function-level patch site." },
  { term: "IMAGE_HOT_PATCH_BASE", definition: "PE32+ structure carrying OriginalTimeDateStamp and OriginalCheckSum binding fields plus a pointer to the HPAT; used by the kernel to verify a hot-patch PE matches the exact build of its base image." },
  { term: "NtManageHotPatch", definition: "Dedicated NT syscall (Windows 11 / Server 2022+) that manages hot-patch creation, activation, mapping, and listing via HOT_PATCH_INFORMATION_CLASS dispatch." },
  { term: "Secure Kernel", definition: "The kernel-side counterpart to Isolated User Mode running in VTL1 under VBS; in the hot-patch pipeline it verifies signed patch payloads and performs the .text rewrite under HVCI." },
  { term: "LCU", definition: "Latest Cumulative Update; Microsoft's monthly full security-and-quality bundle. Hot patching uses an LCU as the quarterly baseline and ships only the security delta in the two hotpatch-only months between baselines." },
  { term: "ftrace", definition: "Linux's in-kernel function tracer; the substrate that both kpatch and kGraft used to install live-patch trampolines, and the mechanism by which the in-tree mainline livepatch redirects callers of a patched function." },
  { term: "Consistency model", definition: "The set of rules a live-patcher uses to decide when a thread of execution has finished using the old version of a function and may begin using the new one. Linux uses a hybrid of stack-check + per-task + kernel-exit + idle-loop. Windows uses per-process notification with no global pause." },
  { term: "Unplanned baseline", definition: "A quarterly-cycle interruption in which a month that would normally be hotpatch-only ships a full LCU instead, because the month's security content is not hot-patchable (kernel struct changes, drivers, SSUs, etc.)." }
]} />
