英語

5. KVM x86

5.1. 前言

KVM 努力成為一個友好的社群;來自新人的貢獻受到重視和鼓勵。請不要因為本文件的長度以及其中包含的許多規則/指南而感到沮喪或害怕。每個人都會犯錯,而且每個人都曾是新手。只要你真誠地努力遵循 KVM x86 的指南,樂於接受反饋,並從你所犯的任何錯誤中學習,你就會受到熱烈歡迎,而不是火把和乾草叉。

5.2. TL;DR

測試是強制性的。與已建立的樣式和模式保持一致。

5.3.

KVM x86 目前正處於從主 KVM 樹的一部分過渡到“僅僅是另一個 KVM 架構”的過渡期。因此,KVM x86 分佈在主 KVM 樹 git.kernel.org/pub/scm/virt/kvm/kvm.git 和 KVM x86 特定樹 github.com/kvm-x86/linux.git 中。

一般來說,當前週期的修復程式直接應用於主 KVM 樹,而下一個週期的所有開發都透過 KVM x86 樹進行。在不太可能的情況下,當前週期的修復程式透過 KVM x86 樹進行路由,它將在到達主 KVM 樹之前應用於 fixes 分支。

請注意,預計此過渡期將持續相當長的時間,即在可預見的未來將是現狀。

5.3.1. 分支

KVM x86 樹被組織成多個主題分支。使用更細粒度的主題分支的目的是更容易跟蹤開發領域,並限制人為錯誤和/或錯誤提交的附帶損害,例如,刪除主題分支的 HEAD 提交不會對其他正在進行的提交的 SHA1 雜湊產生影響,並且由於錯誤而拒絕拉取請求只會延遲該主題分支。

nextfixes 之外的所有主題分支都透過 Cthulhu 合併按需滾動到 next 中,即在更新主題分支時。因此,強制推送到 next 是常見的。

5.3.2. 生命週期

針對當前版本(也稱為主線)的修復程式通常直接應用於主 KVM 樹,即不透過 KVM x86 樹進行路由。

針對下一個版本的更改透過 KVM x86 樹進行路由。拉取請求(從 KVM x86 到主 KVM)是為每個 KVM x86 主題分支傳送的,通常是在 Linus 開放合併視窗的前一週,例如,對於“正常”版本,是在 rc7 之後的一週。如果一切順利,主題分支將滾動到 Linus 合併視窗期間傳送的主 KVM 拉取請求中。

KVM x86 樹沒有自己的官方合併視窗,但是對於新功能,在 rc5 附近有一個軟關閉,對於修復程式(針對下一個版本,請參見上文針對當前版本的修復程式),在 rc6 附近有一個軟關閉。

5.3.3. 時間線

提交通常按先進先出的順序進行審查和應用,對於系列的大小、“快取熱”補丁等有一些迴旋餘地。修復程式,尤其是針對當前版本和/或穩定樹的修復程式,可以跳過佇列。將透過非 KVM 樹(最常見的是透過 tip 樹)進行的補丁和/或具有其他 acks/reviews 的補丁也在一定程度上跳過佇列。

請注意,絕大多數審查是在 rc1 和 rc6 之間完成的,上下浮動。 rc6 和下一個 rc1 之間的時間段用於趕上其他任務,即在此期間保持沉默並不罕見。

歡迎使用 Pings 獲取狀態更新,但請記住當前版本的釋出週期,並抱有現實的期望。如果您正在 ping 以尋求接受,即不僅僅是為了反饋或更新,請在合理範圍內盡一切努力確保您的補丁已準備好合併!對破壞構建或測試失敗的系列進行 Ping 會導致維護者不高興!

5.4. 開發

5.4.1. 基礎樹/分支

針對當前版本(也稱為主線)的修復程式應基於 git://git.kernel.org/pub/scm/virt/kvm/kvm.git master。請注意,修復程式不會自動保證包含在當前版本中。沒有單一規則,但通常只有緊急、關鍵和/或在當前版本中引入的錯誤的修復程式才應針對當前版本。

所有其他內容應基於 kvm-x86/next,即無需選擇特定的主題分支作為基礎。如果主題分支之間存在衝突和/或依賴關係,則由維護者負責解決它們。

使用 kvm-x86/next 作為基礎的唯一例外是補丁/系列是多架構系列,即對常見 KVM 程式碼進行了非平凡的修改,和/或對其他架構的程式碼進行了超過表面的更改。多架構補丁/系列應基於 KVM 歷史記錄中的一個常見穩定點,例如,kvm-x86 next 所基於的候選版本。如果您不確定補丁/系列是否真的是多架構的,請謹慎行事,並將其視為多架構,即使用通用基礎。

5.4.2. 編碼風格

在風格、命名、模式等方面,一致性是 KVM x86 的首要任務。如果一切都失敗了,請匹配已存在的樣式。

除了下面列出的少數注意事項外,請遵循 tip 樹維護者首選的 編碼風格說明,因為補丁/系列經常同時觸及 KVM 和非 KVM x86 檔案,即引起 KVM tip 樹維護者的注意。

對於變數宣告,使用反向冷杉樹(也稱為反向聖誕樹或反向 XMAS 樹)不是嚴格要求的,儘管仍然是首選。

除了少數特殊的 snowflakes 外,不要對函式使用 kernel-doc 註釋。絕大多數“公共”KVM 函式並不是真正的公共函式,因為它們僅供 KVM 內部使用(有計劃使 KVM 的標頭檔案和匯出私有化以強制執行此操作)。

5.4.3. 註釋

使用祈使語氣編寫註釋並避免使用代詞。使用註釋來提供程式碼的高階概述,和/或解釋程式碼執行的原因。不要重複程式碼字面意義上的作用;讓程式碼自己說話。如果程式碼本身難以理解,註釋將無濟於事。

5.4.4. SDM 和 APM 引用

KVM 的大部分程式碼庫直接與 Intel 軟體開發手冊 (SDM) 和 AMD 架構程式設計師手冊 (APM) 中定義的架構行為相關聯。使用“Intel 的 SDM”和“AMD 的 APM”,甚至僅僅使用“SDM”或“APM”,而沒有其他上下文是可以接受的。

不要按編號引用特定的章節、表格、圖形等,尤其是在註釋中。相反,如果需要(請參見下文),請複製貼上相關的程式碼片段,並按名稱引用章節/表格/圖形。 SDM 和 APM 的佈局不斷變化,因此編號/標籤不穩定。

一般來說,不要在註釋中明確引用或複製貼上 SDM 或 APM 中的內容。除了少數例外,KVM 必須 遵守架構行為,因此暗示 KVM 行為正在模擬 SDM 和/或 APM 行為。請注意,在變更日誌中引用 SDM/APM 以證明更改的合理性並提供上下文是完全可以的,並且鼓勵這樣做。

5.4.5. Shortlog

首選的字首格式是 KVM: <topic>:,其中 <topic> 是以下之一

- x86
- x86/mmu
- x86/pmu
- x86/xen
- selftests
- SVM
- nSVM
- VMX
- nVMX

不要使用 x86/kvm! x86/kvm 專門用於 Linux-as-a-KVM-guest 更改,即用於 arch/x86/kernel/kvm.c。不要使用檔名或完整檔案路徑作為主題/shortlog 字首。

請注意,這些與主題分支不一致(主題分支更關心程式碼衝突)。

所有名稱都區分大小寫! KVM: x86: 是好的,kvm: vmx: 不是。

將精簡補丁描述的第一個單詞大寫,但省略結尾的標點符號。例如

KVM: x86: Fix a null pointer dereference in function_xyz()

不是

kvm: x86: fix a null pointer dereference in function_xyz.

如果一個補丁觸及多個主題,則遍歷概念樹以找到第一個共同父項(通常只是 x86)。如有疑問,git log path/to/file 應提供合理的提示。

偶爾會出現新主題,但如果您想建議引入新主題,請首先啟動線上討論,即不要獨行。

有關更多資訊,請參見 規範補丁格式,但有一項修改:不要將 70-75 個字元的限制視為絕對的硬性限制。相反,將 75 個字元用作堅定的但不是硬性的限制,並將 80 個字元用作硬性限制。也就是說,如果您有充分的理由這樣做,則可以使 shortlog 超過標準限制幾個字元。

5.4.6. Changelog

最重要的是,使用祈使語氣編寫變更日誌並避免使用代詞。

有關更多資訊,請參見 描述您的更改,但有一項修改:首先簡要介紹一下實際更改,然後跟進背景資訊。注意!此順序與 tip 樹的首選方法直接衝突!在傳送主要針對 _NOT_ KVM 程式碼的 arch/x86 程式碼的補丁時,請遵循 tip 樹的首選樣式。

KVM x86 首選在深入研究細節之前說明補丁的作用,原因有幾個。首先,實際更改的程式碼可以說是最重要的資訊,因此應該很容易找到該資訊。在 3 個或更多段落的背景資訊之後,在單行程式碼中埋沒“實際更改的內容”的變更日誌使得很難找到該資訊。

對於初始審查,有人可能會爭辯說“什麼壞了”更重要,但是對於瀏覽日誌和 git 考古學,血淋淋的細節越來越不重要。例如,在進行一系列“git blame”時,沿途每次更改的細節都毫無用處,細節僅對罪魁禍首很重要。提供“更改了什麼”使快速確定提交是否可能感興趣變得容易。

首先說明“更改了什麼”的另一個好處是,幾乎總是有可能用一個句子說明“更改了什麼”。相反,除了最簡單的錯誤外,所有錯誤都需要多個句子或段落才能完全描述問題。如果“更改了什麼”和“錯誤是什麼”都非常短,那麼順序無關緊要。但是,如果一個較短(幾乎總是“更改了什麼”),那麼首先介紹較短的一個是有利的,因為對於具有嚴格排序偏好的讀者/審閱者來說,這不太方便。例如,跳過一個句子來獲取上下文比跳過三個段落來獲取“更改了什麼”的痛苦要小。

5.4.7. Fixes

如果更改修復了 KVM/核心錯誤,即使更改不需要向後移植到穩定核心,即使更改修復了舊版本中的錯誤,也要新增 Fixes: 標記。

相反,如果修復確實需要向後移植,請使用“Cc: stable@vger.kernel”顯式標記補丁(儘管電子郵件本身不需要 Cc: stable);預設情況下,KVM x86 選擇不向後移植 Fixes:。一些自動選擇的補丁確實會被向後移植,但需要維護者明確批准(搜尋 MANUALSEL)。

5.4.8. 函式引用

當在註釋、變更日誌或 shortlog(或任何地方)中提到函式時,請使用 function_name() 格式。括號提供上下文並消除引用歧義。

5.5. 測試

至少,一個系列中的所有補丁都必須為 KVM_INTEL=m KVM_AMD=m 和 KVM_WERROR=y 清理構建。構建每個可能的 Kconfig 組合是不可行的,但是越多越好。 KVM_SMM、KVM_XEN、PROVE_LOCKING 和 X86_64 是特別有趣的調整項。

執行 KVM 自檢和 KVM 單元測試也是強制性的(並且顯而易見,測試需要透過)。唯一的例外是更改對執行時行為的影響機率可以忽略不計的更改,例如僅修改註釋的補丁。如果可能且相關,強烈建議在 Intel 和 AMD 上都進行測試。鼓勵啟動實際 VM,但不是強制性的。

對於觸及 KVM 的影子分頁程式碼的更改,必須停用 TDP(EPT/NPT)執行。對於影響常見 KVM MMU 程式碼的更改,強烈建議停用 TDP 執行。對於所有其他更改,如果被修改的程式碼依賴於和/或與模組引數互動,則必須使用相關設定進行測試。

請注意,KVM 自檢和 KVM 單元測試確實存在已知故障。如果您懷疑故障不是由於您的更改造成的,請驗證在有和沒有您的更改的情況下是否發生完全相同的故障。

觸及 reStructured Text 文件(即 .rst 檔案)的更改必須清理構建 htmldocs,即沒有新的警告或錯誤。

如果您無法完全測試更改(例如,由於缺少硬體),請清楚地說明您能夠進行的測試級別,例如,在求職信中。

5.5.1. 新功能

除了一個例外,新功能必須帶有測試覆蓋率。並非嚴格要求 KVM 特定測試,例如,如果透過執行足夠啟用的 guest VM 或在 VM 中執行相關的核心自檢來提供覆蓋率,但是在所有情況下都首選專用 KVM 測試。特別是對於啟用新硬體功能,必須進行否定測試用例,因為很少透過簡單地執行 VM 來執行錯誤和異常流。

此規則的唯一例外是 KVM 只是透過 KVM_GET_SUPPORTED_CPUID 宣傳對某個功能的支援,即對於 KVM 無法阻止 guest 使用的指令/功能,並且沒有真正的啟用。

請注意,“新功能”不僅僅是指“新硬體功能”!無法使用現有 KVM 自檢和/或 KVM 單元測試很好地驗證的新功能必須帶有測試。

歡迎釋出沒有測試的新功能開發以獲取早期反饋,但是此類提交應標記為 RFC,並且求職信應清楚說明請求/期望的反饋型別。不要濫用 RFC 流程; RFC 通常不會收到深入審查。

5.5.2. Bug 修復

除了“明顯”的檢查發現的錯誤外,修復必須附帶要修復的錯誤的重現程式。在許多情況下,重現程式是隱式的,例如對於構建錯誤和測試失敗,但是讀者仍然應該清楚什麼是壞的以及如何驗證修復。對於透過非公共工作負載/測試發現的錯誤,可以給予一定的迴旋餘地,但是強烈建議為此類錯誤提供迴歸測試。

一般來說,對於任何不容易發生的錯誤,都首選迴歸測試。例如,即使該錯誤最初是由諸如 syzkaller 之類的模糊測試器發現的,但如果該錯誤需要達到百萬分之一的型別競爭條件,則可能有必要進行有針對性的迴歸測試。

請注意,KVM 錯誤很少緊急難以重現。在沒有重現程式的情況下發布修復之前,請問問自己一個錯誤是否真的真正是世界末日。

5.6. 釋出

5.6.2. Git Base

如果您使用的是 git 版本 2.9.0 或更高版本(Google 員工,這就是你們所有人!),請使用帶有 --base 標誌的 git format-patch 以自動在生成的補丁中包含基本樹資訊。

請注意,當且僅當分支的上游設定為基本主題分支時,--base=auto 才能按預期工作,例如,如果您的上游設定為您的個人儲存庫以進行備份,則它將做錯誤的事情。另一種“自動”解決方案是根據其 KVM x86 主題派生開發分支的名稱,並將其饋送到 --base 中。例如 x86/pmu/my_branch_name,然後編寫一個小包裝器以從當前分支名稱中提取 pmu 以產生 --base=x/pmu,其中 x 是您的儲存庫用於跟蹤 KVM x86 遠端的任何名稱。

5.6.3. 共同釋出測試

與 KVM 更改關聯的 KVM 自檢(例如,針對 bug 修復的迴歸測試)應與 KVM 更改一起作為單個系列釋出。標準的核心對分規則適用,即導致測試失敗的 KVM 更改應在自檢更新之後排序,反之亦然,由於 KVM bug 而失敗的新測試應在 KVM 修復之後排序。

KVM 單元測試應始終單獨釋出。工具(例如 b4 am)不知道 KVM 單元測試是一個單獨的儲存庫,並且當系列中的補丁應用於不同的樹時會感到困惑。要將 KVM 單元測試補丁連結回 KVM 補丁,請首先發布 KVM 更改,然後在 KVM 單元測試補丁中提供 KVM 補丁/系列的 lore Link:。

5.7. 通知

當補丁/系列被正式接受時,將傳送一封通知電子郵件以回覆原始帖子(多補丁系列的求職信)。通知將包括樹和主題分支,以及已應用補丁的提交的 SHA1。

如果應用了補丁的子集,將在通知中明確說明這一點。除非另有說明,否則暗示系列中未接受的任何補丁都需要更多工作,應在新版本中提交。

如果由於某種原因在正式接受後刪除了補丁,將傳送一封回覆通知電子郵件,解釋刪除補丁的原因以及後續步驟。

5.7.1. SHA1 穩定性

在 SHA1 進入 Linus 的樹之前,不能 100% 保證 SHA1 的穩定!在傳送通知後,SHA1 通常是穩定的,但是會發生一些事情。在大多數情況下,如果應用的補丁的 SHA1 發生更改,將提供通知電子郵件的更新。但是,在某些情況下,例如,如果需要重新構建所有 KVM x86 分支,則不會給出單獨的通知。

5.8. 漏洞

guest 可以利用來攻擊主機(核心或使用者空間)的錯誤,或者巢狀 VM 可以利用來攻擊主機(L2 攻擊 L1)的錯誤,是 KVM 特別感興趣的。如果您懷疑某個錯誤可能導致轉義、資料洩漏等,請遵循 安全錯誤 的協議。