VPS Linux Kernel LUO kexec KVM Hypervisor

Hypervisor 每打一次 kernel CVE 就得把整批 VM 搬到別台:Linux 6.19 的 LUO 用 kexec handover 讓客體記憶體原地留下、熱重啟後接上

Linux 6.19 於 2026 年 2 月 8 日正式釋出,隨版本合併進主線的 Live Update Orchestrator(LUO)把 kexec 熱重啟做成生產可用的 hypervisor 升級路徑。這篇拆解 LUO 的四狀態生命週期、memfd 保留機制、跟 live migration 的定位差異,以及對自架 KVM 平台跟 VPS 主機商實際意義。

自架 KVM 平台或跑 VPS 生意的團隊,每個月都在跟同一件事拉扯:kernel 又出了一支高危 CVE,patch 要打,但底下正跑著幾十上百台 VM,客戶不會接受「維護窗口停機兩小時」。目前檯面上的解法只有兩條——排程 live migration 把 VM 全部搬到隔壁台、或者硬著頭皮排維護通知。前者需要冗餘節點跟共享儲存,後者影響顧客體驗。Linux 6.19 於 2026 年 2 月 8 日正式釋出的 Live Update Orchestrator(LUO),第一次讓「hypervisor kernel 原地重啟、VM 記憶體不動」變成 upstream 支援的路徑。

LUO 不是遙遠的實驗性 feature。Google 已經在生產環境跑這條路徑處理內部虛擬化基礎架構的安全更新,Amazon、Intel、Oracle 都掛名在 patch series 上,主要作者 Pasha Tatashin 也把 memfd handler、VFIO handler 這幾塊關鍵拼圖陸續推進 mainline。這件事在英文技術圈已經有 LWN 深度追蹤好幾輪,中文技術社群目前幾乎沒有討論。

kexec handover 是這一切的地基

kexec 這個機制存在超過二十年,本質上就是「跳過 BIOS,直接從舊 kernel 載入並跳進新 kernel」,時間可以壓到秒級。但傳統 kexec 有個致命問題:新 kernel 起來之後記憶體是白紙,任何舊 kernel 手上抓著的資源——包括正在跑的 VM 記憶體、DMA 中的裝置緩衝區、開著的 file descriptor——全部一起消失。

Kexec Handover(KHO)是 6.18 進來的補丁,把「跨 kernel 保留物理記憶體區塊」這件事寫進協定。做法是舊 kernel 在 kexec 前把「這一段實體記憶體不要被新 kernel 覆蓋,並且有這樣的 metadata 描述它」打包成一份序列化資料,透過 FDT(Flattened Device Tree)傳給新 kernel。新 kernel boot 起來時看到這份 metadata,就知道哪些頁面必須跳過,並可以反序列化回可用的資料結構。

KHO 只解決「記憶體不被踩掉」這一層。真正把它變成可用產品的,是 LUO 這層上面的協調器——決定什麼時候呼叫誰的 preserve callback、什麼時候把系統推進 freeze 狀態、新 kernel 起來後又該怎麼把資料交回給對應的 subsystem。

四個狀態決定升級能不能取消

LUO 把整個熱升級流程切成四個明確的狀態:Normal、Prepared、Frozen、Updated。這個切分不是文件上的裝飾,而是實際控制介面——透過 /dev/liveupdate ioctl,userspace 可以把系統從一個狀態推到下一個,也可以在某些節點反悔退回。

Normal 是預設狀態,跟一般 Linux 沒差別。使用者要開始準備升級時,透過 ioctl 建立一個 session,把要保留的資源(例如某個 memfd 對應的一大塊 guest RAM)註冊到這個 session 底下。註冊完成後系統進入 Prepared 狀態,這時 VM 還在跑、hypervisor 還在服務請求,但 kernel 已經知道哪些頁面下一次 kexec 時要保留。

Frozen 是升級前最後的靜止點。這個階段呼叫每個 handler 的 .freeze() callback,讓 subsystem 做最後一次狀態序列化——例如 KVM 需要把 VM 的 CPU 狀態保存,VFIO 需要把裝置的 DMA 描述符寫入保留區。Frozen 狀態不允許新增資源,但可以退回 Prepared,讓運維人員發現不對勁時還來得及煞車。

真正的 kexec 執行後系統跳到 Updated 狀態。新 kernel 起來後,userspace 透過同一個 session 名字重新開啟 /dev/liveupdate,逐一領回之前保留的資源。每個資源都有一個 opaque handle 跟 compatible string,配對成功後 handler 的 .finish() callback 就把資料還給 subsystem。全部領完後 session 關閉,系統回到 Normal。

這個四狀態設計最實用的一件事是可觀測性:任何監控系統都能透過 sysfs 看到當前狀態,Ansible playbook 或 CI pipeline 也能寫死「必須是 Prepared 才能繼續」的檢查點。

memfd 是保住 VM 記憶體的唯一路徑

VM 記憶體要怎麼跨 kexec 保存,答案很技術性但值得攤開講。QEMU/KVM 起 VM 的時候,guest RAM 通常是透過 anonymous mmap 或 memfd_create 分配的一大塊虛擬記憶體,KVM 再透過 slot 機制把它映射給 guest。傳統 anonymous mmap 建立的區塊在 kexec 後完全消失,因為它的 owner 是 process、process 在 kexec 時已死。

memfd 不一樣。memfd 建立的是一個有 file descriptor 的匿名記憶體 backing,實體頁面在 kernel 追蹤下不必綁在單一 process 生命週期。LUO 在 6.19 上游的第一批 handler 就是 memfd handler——正因為它是把 VM 記憶體原地保住的最少入侵路徑。

實際運作起來是這樣:hypervisor 進程(例如 cloud-hypervisor 或 QEMU)用 memfd 分配 guest RAM,把 memfd 的 fd 透過 /dev/liveupdate 註冊到某個 session。LUO 呼叫 memfd handler 的 .preserve(),記憶體區塊被打上「跨 kexec 保留」標記。Kexec 執行後 hypervisor 進程當然也重啟了,但它可以透過 session 名字重新領回同一個 memfd fd,重新 mmap 進來,記憶體內容一位元都沒動。

搭配的就是 QEMU 或 cloud-hypervisor 端的 stop/cont 機制——kexec 前 pause guest CPU 執行、序列化 vCPU 狀態;kexec 後領回 guest RAM、還原 vCPU 狀態、resume 執行。從 guest OS 的視角就是「時間被凍結了三到五秒」,不會看到裝置消失、不會看到 vCPU 被熱插拔。這跟 live migration 從 guest 角度的觀感很像,但底下運作完全不同。

跟 live migration 是互補而不是取代

會混淆 LUO 跟 live migration 是正常的,兩者從 guest 角度看效果類似。但決策層面差得很遠。

Live migration 需要一台目的地主機、一條夠寬的網路、共享或可複製的儲存後端,本質是「把 VM 搬到另一台」。優點是原本那台主機可以完全下線做任何維護——換 CPU、換記憶體、甚至升級硬體。缺點是需要冗餘容量、需要頻寬預算、記憶體越大搬得越久(TB 級 VM 搬過去可能要幾十分鐘),對記憶體寫入頻繁的 workload 甚至可能追不上。

LUO 是「原地重啟這台主機的 kernel」。它不需要目的地主機、不需要跨主機頻寬、不受 VM 記憶體大小影響(因為記憶體根本沒動)。停機時間就是新 kernel boot 起來加上 hypervisor 進程重新 attach 這些資源的時間,實測落在 5 到 15 秒區間。缺點是這條路只能升級 kernel、不能換硬體,而且新 kernel 必須跟舊 kernel 的 handler ABI 相容。

實際運維上兩者是互補的。Kernel CVE patch 一年可能來十次,這是 LUO 的戰場——快速、原地、對 VM 幾乎無感。硬體維護、機房搬遷、大版本 kernel 升級(例如從 6.19 跳到未來的 7.x),live migration 還是唯一解。有計劃在自建 KVM 平台上長期運維的團隊,兩套機制都要準備好。

開啟方式跟目前的邊界

LUO 在 6.19 內核裡預設是關掉的,需要在開機參數加 liveupdate=on 才會啟用。這個決定很合理——LUO 需要在 boot 早期預留一段特殊記憶體(給下一次 kexec 用的 handover buffer),這段記憶體在整個系統 lifetime 都不能被一般 allocator 拿走。對沒有熱升級需求的一般伺服器來說是白白鎖住幾百 MB 到幾 GB 的 RAM。

開啟之後透過 sysfs 可以看到當前狀態,透過 /dev/liveupdate ioctl 建 session、註冊資源。真正的難度不在 kernel 這邊,而在 userspace stack 要怎麼跟上:QEMU 目前有實驗性的 -object memory-backend-memfd,share=on,reserved=false 支援;cloud-hypervisor 有一支還沒 merge 的 branch;libvirt 這一層還完全沒動。這意味著現階段真正能用 LUO 熱升級 kernel 的,多數是自研 hypervisor 或直接跑 QEMU 加自製管理層的團隊。

支援的 handler 目前也不齊。memfd 進了 mainline,VFIO passthrough 裝置的 handler 有 patch series 但還沒完全上游,IOMMU 狀態、SR-IOV VF 綁定、bridge 網路設定這些都得等後續。想在生產環境用,Google 那條路徑是自己維護 handler patch、跟 upstream 保持同步;規模不到那個量體的團隊,比較實際的做法是先在測試環境跑起來、追 6.20 跟 6.21 的進度,估計 2026 年底到 2027 上半年會有更多 out-of-the-box 支援。

有一件事一定要在測試環境先撞牆

新 kernel 起來後如果 .finish() callback 失敗,LUO 會把資源 ownership 留住直到下一次 live update cycle——白話說就是 memfd fd 領不回來、VM 記憶體變成孤兒。這件事在生產環境發生會非常尷尬,因為 guest RAM 還在記憶體裡但沒人能存取,得等下一次熱升級或直接 hard reboot。

這個行為的設計理由是保守:與其在領取失敗時把資料丟掉,寧可先留著給運維人員排查。實務上有兩個對策:一是保留一個 rollback plan,任何 handler 版本相容性有疑慮就先 pilot;二是把 hypervisor 進程重啟後的 attach 邏輯寫得非常防禦性,任何步驟失敗就記錄 handle 讓下一次能重試。

另外一個容易踩到的點是「非 memfd 的匿名記憶體」——如果 hypervisor 進程還用了 malloc 或 anonymous mmap 存 VM metadata(例如 vCPU state、interrupt controller state),這些東西在 kexec 後同樣消失。標準做法是把所有 across-kexec 需要留下的資料都搬到 memfd 或其他 LUO 已知的 backing 上,這通常需要改 hypervisor 端的資料結構配置。

對自架平台跟 VPS 生意的影響

LUO 的真正戰略意義在於降低「多久打一次 kernel patch」的邊際成本。今天很多自架 KVM 平台的實際做法是把安全 patch 攢一批、一個月或一季做一次維護窗口。原因是每一次維護窗口都要開 announcement、聯絡受影響客戶、準備 rollback 方案,人力成本比 kernel 本身高很多。

當熱升級變成「排定一個 5 到 15 秒的短暫抖動」,patch 節奏就可以完全跟著 CVE 走。這件事在 2024 到 2026 幾波 container escape 級別的 kernel 漏洞(例如 CopyFail、GhostLock 這些)之後意義特別明顯:客戶會挑主機商挑得越來越細,能不能在 CVE 公告當週打完 patch 開始變成競爭條件。

自架 hypervisor 的規模不夠支撐 live migration 冗餘的中小團隊,LUO 提供第一次「沒有隔壁節點也能熱升級 kernel」的可能性。這對只有一到兩個機房的服務商特別關鍵——不需要為了熱升級 kernel 而先蓋一整個 N+1 冗餘架構。

對純粹的雲客戶而言,LUO 這件事的可觀察指標是「主機商多久打一次 CVE patch」。這個資訊未來會逐漸變成 SLA 之外的一項重要決策依據。

需要一套穩定的臺灣本地 VPS 主機用來部署 KVM 環境、測試 LUO 或跑對延遲敏感的自架服務,NCSE Network 提供搭載 Intel Gold CPU 與 NVMe SSD 的 VPS 方案,機房位於是方電訊南港,並可搭配 10M 至 100G 彈性頻寬的 IP Transit 服務。歡迎至 ncse.tw 了解更多方案細節。

需要穩定的雲端主機?

NCSE Network 提供企業級 VPS,7 天免費試用,臺灣是方電訊機房,99% SLA 保證。

查看 VPS 方案 →