هندسة AVF

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

يوفر Android تطبيقًا مرجعيًا لجميع المكونات اللازمة لتنفيذ Android Virtualization Framework. حاليًا يقتصر هذا التنفيذ على ARM64. تشرح هذه الصفحة بنية الإطار.

خلفية

تسمح بنية Arm بما يصل إلى أربعة مستويات استثناء ، مع استثناء المستوى 0 (EL0) هو الأقل امتيازًا ، والاستثناء المستوى 3 (EL3) هو الأكثر. يعمل الجزء الأكبر من قاعدة رموز Android (جميع مكونات مساحة المستخدمين) في EL0. بقية ما يسمى "Android" هو Linux kernel ، والذي يعمل في EL1.

تسمح طبقة EL2 بإدخال برنامج Hypervisor الذي يتيح عزل الذاكرة والأجهزة في أجهزة pVM الفردية في EL1 / EL0 ، مع ضمانات قوية للسرية والنزاهة.

برنامج Hypervisor

تم بناء الجهاز الظاهري المحمي المستند إلى kernel (pKVM) على Linux KVM hypervisor ، والذي تم توسيعه مع القدرة على تقييد الوصول إلى الحمولات التي تعمل في الأجهزة الظاهرية الضيف التي تم وضع علامة "محمية" عليها في وقت الإنشاء.

يدعم KVM / arm64 أوضاع تنفيذ مختلفة اعتمادًا على توفر ميزات معينة لوحدة المعالجة المركزية ، مثل امتدادات مضيف المحاكاة الافتراضية (VHE) (ARMv8.1 والإصدارات الأحدث). في أحد هذه الأوضاع ، المعروف باسم الوضع non-VHE ، يتم فصل كود hypervisor من صورة kernel أثناء التمهيد وتثبيته في EL2 ، بينما تعمل النواة نفسها في EL1. على الرغم من كونه جزءًا من قاعدة بيانات Linux ، إلا أن مكون EL2 الخاص بـ KVM هو مكون صغير مسؤول عن التبديل بين EL1s المتعددة ، ويتم التحكم فيه بالكامل بواسطة نواة المضيف. يتم تجميع مكون برنامج hypervisor مع Linux ، ولكنه موجود في قسم ذاكرة منفصل ومخصص من صورة vmlinux . يستفيد pKVM من هذا التصميم من خلال توسيع كود برنامج Hypervisor بميزات جديدة تسمح له بوضع قيود على نواة مضيف Android ومساحة المستخدم ، وتقييد وصول المضيف إلى ذاكرة الضيف وبرنامج Hypervisor.

إجراء التمهيد

يوضح الشكل 1. إجراء تمهيد pKVM. الخطوة الأولى هي أن يدخل محمل الإقلاع نواة لينوكس تدعم pKVM في EL2. أثناء التمهيد المبكر ، تكتشف النواة أنها تعمل في EL2 ، وتحرم نفسها من EL1 ، تاركة وراءها pKVM. من هذه النقطة فصاعدًا ، تستمر نواة Linux في التمهيد بشكل طبيعي ، وتحميل جميع برامج تشغيل الأجهزة الضرورية ، حتى الوصول إلى مساحة المستخدم. تحدث هذه الخطوات أثناء التحكم في pKVM.

يثق إجراء التمهيد في أداة تحميل التشغيل للحفاظ على تكامل صورة kernel فقط أثناء التمهيد المبكر. عندما يتم حرمان النواة ، فإنها لم تعد موثوقًا بها من قبل المشرف ، والذي يكون مسؤولاً بعد ذلك عن حماية نفسه حتى لو تم اختراق النواة.

إجراء التمهيد pKVM

الشكل 1. إجراء التمهيد pKVM

يسمح وجود Android kernel و Hypervisor في نفس الصورة الثنائية بواجهة اتصال شديدة الترابط بينهما. يضمن هذا الاقتران الضيق التحديثات الذرية للمكونين ، مما يتجنب الحاجة إلى الحفاظ على ثبات الواجهة بينهما ، ويوفر قدرًا كبيرًا من المرونة دون المساس بإمكانية الصيانة على المدى الطويل. كما يسمح الاقتران الضيق أيضًا بتحسينات الأداء عندما يمكن لكلا المكونين التعاون دون التأثير على ضمانات الأمان التي يوفرها برنامج Hypervisor.

علاوة على ذلك ، يسمح اعتماد GKI في نظام Android البيئي تلقائيًا بنشر pKVM hypervisor على أجهزة Android في نفس النظام الثنائي مثل kernel.

حماية الوصول إلى ذاكرة وحدة المعالجة المركزية

تحدد بنية Arm وحدة إدارة الذاكرة (MMU) مقسمة إلى مرحلتين مستقلتين ، ويمكن استخدام كل منهما لتنفيذ ترجمة العنوان والتحكم في الوصول إلى أجزاء مختلفة من الذاكرة. يتم التحكم في المرحلة 1 MMU بواسطة EL1 وتسمح بالمستوى الأول من ترجمة العنوان. يستخدم Linux المرحلة 1 MMU لإدارة مساحة العنوان الافتراضية المتوفرة لكل عملية مساحة مستخدم وإلى مساحة العنوان الافتراضية الخاصة بها.

يتم التحكم في المرحلة 2 MMU بواسطة EL2 وتمكّن من تطبيق ترجمة العنوان الثاني على عنوان الإخراج للمرحلة 1 MMU ، مما يؤدي إلى عنوان فعلي (PA). يمكن استخدام ترجمة المرحلة الثانية بواسطة برامج Hypervisor للتحكم في عمليات الوصول إلى الذاكرة وترجمتها من جميع أجهزة VM الخاصة بالضيف. كما هو مبين في الشكل 2 ، عند تمكين كلتا مرحلتي الترجمة ، يُطلق على عنوان إخراج المرحلة 1 عنوان مادي وسيط (IPA) ملاحظة: يتم ترجمة العنوان الظاهري (VA) إلى IPA ثم إلى PA.

حماية الوصول إلى ذاكرة وحدة المعالجة المركزية

الشكل 2. حماية الوصول إلى ذاكرة وحدة المعالجة المركزية

تاريخيًا ، يعمل KVM مع تمكين ترجمة المرحلة 2 أثناء تشغيل الضيوف ومع تعطيل المرحلة 2 أثناء تشغيل نواة Linux المضيفة. تسمح هذه البنية بوصول الذاكرة من المرحلة المضيفة 1 MMU بالمرور عبر المرحلة 2 MMU ، وبالتالي السماح بالوصول غير المقيد من المضيف إلى صفحات ذاكرة الضيف. من ناحية أخرى ، يتيح pKVM حماية المرحلة 2 حتى في سياق المضيف ، ويضع برنامج Hypervisor مسؤولاً عن حماية صفحات ذاكرة الضيف بدلاً من المضيف.

تستفيد KVM بالكامل من ترجمة العنوان في المرحلة 2 لتنفيذ تعيينات IPA / PA المعقدة للضيوف ، مما يخلق وهم الذاكرة المتجاورة للضيوف على الرغم من التجزئة المادية. ومع ذلك ، فإن استخدام المرحلة 2 MMU للمضيف يقتصر على التحكم في الوصول فقط. المرحلة المضيفة 2 معينة للهوية ، مما يضمن أن الذاكرة المتجاورة في مساحة IPA المضيفة متجاورة في مساحة PA. تسمح هذه البنية باستخدام التعيينات الكبيرة في جدول الصفحات وبالتالي تقلل الضغط على المخزن المؤقت للترجمة (TLB). نظرًا لأنه يمكن فهرسة تعيين الهوية بواسطة PA ، تُستخدم المرحلة المضيفة 2 أيضًا لتتبع ملكية الصفحة مباشرة في جدول الصفحة.

حماية الوصول المباشر للذاكرة (DMA)

كما هو موضح سابقًا ، يعد إلغاء تعيين صفحات الضيف من مضيف Linux في جداول صفحات وحدة المعالجة المركزية خطوة ضرورية ولكنها غير كافية لحماية ذاكرة الضيف. يحتاج pKVM أيضًا إلى الحماية من عمليات الوصول إلى الذاكرة التي يتم إجراؤها بواسطة أجهزة قادرة على الوصول المباشر للذاكرة (DMA) تحت سيطرة نواة المضيف ، وإمكانية حدوث هجوم DMA بواسطة مضيف ضار. لمنع مثل هذا الجهاز من الوصول إلى ذاكرة الضيف ، تتطلب pKVM أجهزة وحدة إدارة ذاكرة الإدخال والإخراج (IOMMU) لكل جهاز قادر على الوصول المباشر للذاكرة (DMA) في النظام ، كما هو موضح في الشكل 3.

حماية الوصول إلى ذاكرة DMA

الشكل 3. حماية الوصول إلى ذاكرة DMA

كحد أدنى ، توفر أجهزة IOMMU وسائل منح وإلغاء حق الوصول للقراءة / الكتابة لجهاز ما إلى الذاكرة الفعلية بدقة الصفحة. ومع ذلك ، فإن جهاز IOMMU هذا يحد من استخدام الأجهزة في pVMs لأنها تفترض المرحلة 2 المعينة للهوية.

لضمان العزل بين الأجهزة الافتراضية ، يجب أن تكون معاملات الذاكرة التي تم إنشاؤها نيابة عن كيانات مختلفة قابلة للتمييز بواسطة IOMMU بحيث يمكن استخدام المجموعة المناسبة من جداول الصفحات للترجمة.

بالإضافة إلى ذلك ، يعد تقليل كمية الكود الخاص بـ SoC في EL2 استراتيجية رئيسية لتقليل قاعدة الحوسبة الشاملة الموثوقة (TCB) لـ pKVM وتتعارض مع تضمين برامج تشغيل IOMMU في برنامج Hypervisor. للتخفيف من هذه المشكلة ، يكون المضيف في EL1 مسؤولاً عن مهام إدارة IOMMU المساعدة ، مثل إدارة الطاقة والتهيئة ومعالجة المقاطعة عند الاقتضاء.

ومع ذلك ، فإن وضع المضيف في حالة التحكم في حالة الجهاز يضع متطلبات إضافية على واجهة البرمجة لجهاز IOMMU لضمان عدم تجاوز عمليات التحقق من الأذونات بوسائل أخرى ، على سبيل المثال ، بعد إعادة تعيين الجهاز.

وحدة IOMMU القياسية والمدعومة جيدًا لأجهزة Arm التي تجعل كل من العزل والتخصيص المباشر ممكنًا هي بنية وحدة إدارة ذاكرة نظام الذراع (SMMU). هذه البنية هي الحل المرجعي الموصى به.

ملكية الذاكرة

في وقت التمهيد ، يُفترض أن جميع الذاكرة التي لا تحتوي على برنامج Hypervisor مملوكة للمضيف ، ويتم تتبعها على هذا النحو بواسطة برنامج Hypervisor. عندما يتم إنتاج pVM ، يتبرع المضيف بصفحات الذاكرة للسماح لها بالتمهيد ويقوم برنامج Hypervisor بنقل ملكية تلك الصفحات من المضيف إلى pVM. وبالتالي ، يضع برنامج Hypervisor قيودًا للتحكم في الوصول في جدول صفحات المرحلة 2 للمضيف لمنعه من الوصول إلى الصفحات مرة أخرى ، مما يوفر السرية للضيف.

أصبح الاتصال بين المضيف والضيوف ممكنًا من خلال مشاركة الذاكرة التي يتم التحكم فيها بينهم. يُسمح للضيوف بمشاركة بعض صفحاتهم مرة أخرى مع المضيف باستخدام hypercall ، والذي يوجه برنامج Hypervisor لإعادة تخطيط تلك الصفحات في جدول صفحة المضيف في المرحلة 2. وبالمثل ، أصبح اتصال المضيف مع TrustZone ممكنًا من خلال مشاركة الذاكرة و / أو عمليات الإقراض ، والتي تتم مراقبتها جميعًا عن كثب والتحكم فيها بواسطة pKVM باستخدام مواصفات إطار عمل البرامج الثابتة لـ Arm (FF-A) .

برنامج Hypervisor مسؤول عن تتبع ملكية جميع صفحات الذاكرة في النظام وما إذا كانت تتم مشاركتها أو إقراضها لكيانات أخرى. يتم إجراء معظم تتبع الحالة هذا باستخدام البيانات الوصفية المرفقة بجداول صفحات المضيف والضيوف في المرحلة 2 ، باستخدام وحدات البت المحجوزة في إدخالات جدول الصفحات (PTEs) والتي ، كما يوحي اسمها ، محجوزة لاستخدام البرنامج.

يجب على المضيف التأكد من أنه لا يحاول الوصول إلى الصفحات التي يتعذر الوصول إليها بواسطة برنامج Hypervisor. يؤدي الوصول غير القانوني للمضيف إلى إدخال استثناء متزامن في المضيف بواسطة برنامج Hypervisor ، والذي يمكن أن يؤدي إما إلى تلقي مهمة مساحة المستخدمين المسؤولة لإشارة SEGV ، أو تعطل نواة المضيف. لمنع الوصول غير المقصود ، تصبح الصفحات الممنوحة للضيوف غير مؤهلة للتبديل أو الدمج بواسطة نواة المضيف.

معالجة المقاطعة وأجهزة ضبط الوقت

تعد المقاطعات جزءًا أساسيًا من الطريقة التي يتفاعل بها الضيف مع الأجهزة وللتواصل بين وحدات المعالجة المركزية (CPU) ، حيث تكون مقاطعات المعالجات (IPI) هي آلية الاتصال الرئيسية. نموذج KVM هو تفويض كل إدارة المقاطعة الافتراضية إلى المضيف في EL1 ، والذي يتصرف لهذا الغرض كجزء غير موثوق به من برنامج Hypervisor.

تقدم pKVM محاكاة كاملة للإصدار 3 من وحدة تحكم المقاطعة العامة (GICv3) بناءً على كود KVM الحالي. يتم التعامل مع Timer و IPIs كجزء من رمز المحاكاة غير الموثوق به هذا.

دعم GICv3

يجب أن تضمن الواجهة بين EL1 و EL2 أن حالة المقاطعة الكاملة مرئية لمضيف EL1 ، بما في ذلك نسخ من سجلات برنامج Hypervisor المتعلقة بالمقاطعات. يتم تحقيق هذه الرؤية عادةً باستخدام مناطق الذاكرة المشتركة ، واحدة لكل وحدة معالجة مركزية افتراضية (vCPU).

يمكن تبسيط رمز دعم وقت تشغيل تسجيل النظام لدعم ملاءمة تسجيل المقاطعة الذي تم إنشاؤه بواسطة البرامج (SGIR) فقط. تنص البنية على أن هذه السجلات تحاصر دائمًا EL2 ، بينما لم تكن المصائد الأخرى مفيدة حتى الآن إلا لتخفيف الأخطاء الوصفية. كل شيء آخر يتم التعامل معه في الأجهزة.

على جانب MMIO ، يتم محاكاة كل شيء في EL1 ، وإعادة استخدام كل البنية التحتية الحالية في KVM. أخيرًا ، يتم دائمًا ترحيل Wait for Interrupt (WFI) إلى EL1 ، لأن هذا أحد أساسيات الجدولة الأساسية التي يستخدمها KVM.

دعم الموقت

يجب تعريض قيمة المقارنة للمؤقت الظاهري لـ EL1 في كل WFI الملاءمة بحيث يمكن لـ EL1 إدخال مقاطعات المؤقت أثناء حظر وحدة المعالجة المركزية الافتراضية (vCPU). يتم محاكاة المؤقت الفيزيائي بالكامل ، ويتم نقل جميع المصائد إلى EL1.

التعامل مع MMIO

للتواصل مع شاشة الجهاز الظاهري (VMM) وإجراء محاكاة GIC ، يجب إعادة مصائد MMIO إلى المضيف في EL1 لمزيد من الفرز. تتطلب pKVM ما يلي:

  • IPA وحجم الوصول
  • البيانات في حالة الكتابة
  • Endianness لوحدة المعالجة المركزية عند نقطة الملاءمة

بالإضافة إلى ذلك ، يتم ترحيل المصائد التي لها سجل للأغراض العامة (GPR) كمصدر / وجهة باستخدام سجل زائف للنقل المجرد.

واجهات الضيف

يمكن للضيف التواصل مع ضيف محمي باستخدام مزيج من المكالمات المفرطة والوصول إلى الذاكرة للمناطق المحاصرة. يتم عرض المكالمات الفائقة وفقًا لمعيار SMCCC ، مع نطاق مخصص لتخصيص البائع بواسطة KVM. تعتبر المكالمات الفائقة التالية ذات أهمية خاصة لضيوف pKVM.

hypercalls عامة

  • يوفر PSCI آلية قياسية للضيف للتحكم في دورة حياة وحدات المعالجة المركزية الافتراضية الخاصة به بما في ذلك الاتصال بالإنترنت وعدم الاتصال بالإنترنت وإيقاف تشغيل النظام.
  • يوفر TRNG آلية قياسية للضيف لطلب الانتروبيا من pKVM الذي ينقل المكالمة إلى EL3. هذه الآلية مفيدة بشكل خاص حيث لا يمكن الوثوق بالمضيف لإضفاء الطابع الافتراضي على مولد رقم عشوائي للأجهزة (RNG).

pKVM hypercalls

  • مشاركة الذاكرة مع المضيف. يتعذر الوصول إلى جميع ذاكرة الضيف في البداية من قبل المضيف ، ولكن الوصول إلى المضيف ضروري لاتصال الذاكرة المشتركة وللأجهزة شبه الافتراضية التي تعتمد على المخازن المؤقتة المشتركة. تتيح المكالمات الفائقة لمشاركة الصفحات وإلغاء مشاركتها مع المضيف للضيف أن يقرر بالضبط أجزاء الذاكرة التي يمكن الوصول إليها لبقية أجهزة Android دون الحاجة إلى المصافحة.
  • الوصول إلى الذاكرة الملائمة للمضيف. تقليديًا ، إذا وصل ضيف KVM إلى عنوان لا يتوافق مع منطقة ذاكرة صالحة ، فسيخرج مؤشر ترابط vCPU إلى المضيف ويتم استخدام الوصول عادةً لـ MMIO ويتم محاكاته بواسطة VMM في مساحة المستخدم. لتسهيل هذه المعالجة ، يُطلب من pKVM الإعلان عن تفاصيل حول التعليمات المعيبة مثل عنوانها ومعلمات التسجيل ومحتوياتها المحتملة مرة أخرى إلى المضيف ، مما قد يؤدي عن غير قصد إلى كشف البيانات الحساسة من الضيف المحمي إذا لم يتم توقع المصيدة. يحل pKVM هذه المشكلة من خلال التعامل مع هذه الأخطاء على أنها قاتلة ما لم يكن الضيف قد أصدر مسبقًا مكالمة فاشلة لتحديد نطاق IPA المعيب باعتباره النطاق الذي يُسمح لوصول الوصول إليه بالعودة إلى المضيف. يشار إلى هذا الحل باسم حارس MMIO .

جهاز إدخال / إخراج افتراضي (Virtio)

يعتبر Virtio معيارًا شائعًا ومحمولًا وناضجًا للتنفيذ والتفاعل مع الأجهزة شبه الافتراضية. يتم تنفيذ غالبية الأجهزة المعرضة للضيوف المحميين باستخدام Virtio. يدعم Virtio أيضًا تطبيق vsock المستخدم للتواصل بين الضيف المحمي وبقية أجهزة Android.

عادةً ما يتم تنفيذ أجهزة Virtio في مساحة مستخدم المضيف بواسطة VMM ، والتي تعترض وصول الذاكرة المحاصرة من الضيف إلى واجهة MMIO لجهاز Virtio ويحاكي السلوك المتوقع. يعد الوصول إلى MMIO مكلفًا نسبيًا لأن كل وصول إلى الجهاز يتطلب رحلة ذهابًا وإيابًا إلى VMM والعودة ، لذا فإن معظم نقل البيانات الفعلي بين الجهاز والضيف يحدث باستخدام مجموعة من الفضائل في الذاكرة. الافتراض الأساسي لـ Virtio هو أن المضيف يمكنه الوصول إلى ذاكرة الضيف بشكل تعسفي. يتضح هذا الافتراض في تصميم Virtqueue ، والذي قد يحتوي على مؤشرات للمخازن المؤقتة في الضيف والتي تهدف محاكاة الجهاز للوصول إليها مباشرةً.

على الرغم من أنه يمكن استخدام الاستدعاءات التشعبية لمشاركة الذاكرة الموصوفة سابقًا لمشاركة المخازن المؤقتة لبيانات Virtio من الضيف إلى المضيف ، إلا أن هذه المشاركة يتم إجراؤها بالضرورة عند مستوى دقة الصفحة ويمكن أن ينتهي بك الأمر إلى عرض بيانات أكثر مما هو مطلوب إذا كان حجم المخزن المؤقت أقل من حجم الصفحة . بدلاً من ذلك ، يتم تكوين الضيف لتخصيص كل من الفضائل ومخازن البيانات المقابلة لها من نافذة ثابتة للذاكرة المشتركة ، مع نسخ البيانات (المرتدة) من النافذة وإليها كما هو مطلوب.

جهاز افتراضي

الشكل 4. جهاز Virtio

التفاعل مع TrustZone

على الرغم من أن الضيوف غير قادرين على التفاعل مباشرة مع TrustZone ، يجب أن يظل المضيف قادرًا على إصدار مكالمات SMC في العالم الآمن. يمكن أن تحدد هذه الاستدعاءات مخازن ذاكرة معنونة فعليًا لا يمكن للمضيف الوصول إليها. نظرًا لأن البرنامج الآمن بشكل عام غير مدرك لإمكانية الوصول إلى المخزن المؤقت ، فقد يستخدم مضيف ضار هذا المخزن المؤقت لتنفيذ هجوم نائب مرتبك (مشابه لهجوم DMA). لمنع مثل هذه الهجمات ، يقوم pKVM باعتراض جميع مكالمات SMC للمضيف إلى EL2 ويعمل كوكيل بين المضيف والشاشة الآمنة في EL3.

يتم إعادة توجيه مكالمات PSCI من المضيف إلى البرامج الثابتة EL3 مع الحد الأدنى من التعديلات. على وجه التحديد ، تتم إعادة كتابة نقطة الدخول لوحدة المعالجة المركزية القادمة عبر الإنترنت أو الاستئناف من التعليق بحيث يتم تثبيت جدول صفحات المرحلة 2 في EL2 قبل العودة إلى المضيف في EL1. أثناء التمهيد ، يتم فرض هذه الحماية بواسطة pKVM.

تعتمد هذه البنية على SoC الداعمة لـ PSCI ، ويفضل أن يكون ذلك من خلال استخدام إصدار محدث من TF-A كبرنامج ثابت EL3.

يعمل إطار البرامج الثابتة لـ Arm (FF-A) على توحيد معايير التفاعلات بين العالمين العادي والآمن ، لا سيما في وجود برنامج Hypervisor آمن. يحدد جزء كبير من المواصفات آلية لمشاركة الذاكرة مع العالم الآمن ، باستخدام تنسيق رسالة مشترك ونموذج أذونات محدد جيدًا للصفحات الأساسية. رسائل وكلاء pKVM FF-A للتأكد من أن المضيف لا يحاول مشاركة الذاكرة مع الجانب الآمن الذي لا يمتلك أذونات كافية له.

تعتمد هذه البنية على برنامج العالم الآمن الذي يفرض نموذج الوصول إلى الذاكرة ، لضمان أن التطبيقات الموثوقة وأي برامج أخرى تعمل في العالم الآمن يمكنها الوصول إلى الذاكرة فقط إذا كانت مملوكة حصريًا للعالم الآمن أو تمت مشاركتها معه صراحةً باستخدام FF -أ. في نظام مع S-EL2 ، يجب أن يتم فرض نموذج الوصول إلى الذاكرة بواسطة Secure Partition Manager Core (SPMC) ، مثل Hafnium ، الذي يحافظ على جداول صفحات المرحلة 2 للعالم الآمن. في نظام بدون S-EL2 ، يمكن لـ TEE بدلاً من ذلك فرض نموذج الوصول إلى الذاكرة من خلال جداول صفحات المرحلة 1.

إذا لم يكن استدعاء SMC لـ EL2 مكالمة PSCI أو رسالة محددة FF-A ، فسيتم إعادة توجيه SMC غير المعالج إلى EL3. الافتراض هو أن البرامج الثابتة الآمنة (الموثوقة بالضرورة) يمكنها التعامل مع SMCs غير المعالجة بأمان لأن البرنامج الثابت يتفهم الاحتياطات اللازمة للحفاظ على عزل pVM.

مراقبة الآلة الافتراضية

crosvm هي شاشة جهاز افتراضية (VMM) تعمل على تشغيل الأجهزة الافتراضية من خلال واجهة KVM في Linux. ما يجعل crosvm فريدًا هو تركيزه على الأمان باستخدام لغة البرمجة Rust وصندوق الحماية حول الأجهزة الافتراضية لحماية النواة المضيفة.

واصفات الملفات و ioctls

يعرض /dev/kvm kvm لمساحة المستخدمين باستخدام ioctls التي تشكل واجهة برمجة تطبيقات KVM. تنتمي ioctls إلى الفئات التالية:

  • يقوم النظام بالاستعلام عن السمات العامة وتعيين السمات العامة التي تؤثر على نظام KVM الفرعي بأكمله ، وإنشاء pVMs.
  • يقوم VM ioctls بالاستعلام عن السمات وتعيين السمات التي تنشئ وحدات المعالجة المركزية الافتراضية (vCPUs) والأجهزة ، وتؤثر على pVM بالكامل ، مثل تضمين تخطيط الذاكرة وعدد وحدات المعالجة المركزية الافتراضية (vCPUs) والأجهزة.
  • vCPU ioctls للاستعلام وتعيين السمات التي تتحكم في تشغيل وحدة المعالجة المركزية الافتراضية الواحدة.
  • يقوم جهاز ioctls بالاستعلام عن السمات التي تتحكم في تشغيل جهاز افتراضي واحد وتعيينه.

تقوم كل عملية crosvm بتشغيل مثيل واحد من آلة افتراضية. تستخدم هذه العملية نظام KVM_CREATE_VM ioctl لإنشاء واصف ملف VM يمكن استخدامه لإصدار pVM ioctls. يقوم KVM_CREATE_VCPU أو KVM_CREATE_DEVICE ioctl على VM FD بإنشاء vCPU / جهاز ويعيد واصف ملف يشير إلى المورد الجديد. يمكن استخدام ioctls على وحدة المعالجة المركزية الافتراضية أو جهاز FD للتحكم في الجهاز الذي تم إنشاؤه باستخدام ioctl على جهاز VM FD. بالنسبة لوحدات المعالجة المركزية الافتراضية ، يتضمن ذلك المهمة المهمة لتشغيل كود الضيف.

داخليًا ، يسجل crosvm واصفات ملفات VM باستخدام kernel باستخدام واجهة epoll المشغلة على الحافة. تقوم النواة بعد ذلك بإعلام crosvm عندما يكون هناك حدث جديد معلق في أي من واصفات الملفات.

يضيف pKVM إمكانية جديدة ، KVM_CAP_ARM_PROTECTED_VM ، والتي يمكن استخدامها للحصول على معلومات حول بيئة pVM وإعداد الوضع المحمي لـ VM. يستخدم crosvm هذا أثناء إنشاء pVM إذا تم تمرير العلامة --protected-vm ، للاستعلام عن المقدار المناسب من الذاكرة للبرامج الثابتة لـ pVM وحجزه ، ثم لتمكين الوضع المحمي.

تخصيص الذاكرة

تتمثل إحدى المسؤوليات الرئيسية لجهاز VMM في تخصيص ذاكرة الجهاز الظاهري وإدارة تخطيط الذاكرة. ينشئ crosvm تخطيط ذاكرة ثابت موصوف بشكل فضفاض في الجدول أدناه.

FDT في الوضع العادي PHYS_MEMORY_END - 0x200000
مساحة فارغة ...
رامديسك ALIGN_UP(KERNEL_END, 0x1000000)
نواة 0x80080000
الإقلاع 0x80200000
FDT في وضع BIOS 0x80000000
قاعدة الذاكرة المادية 0x80000000
البرامج الثابتة pVM 0x7FE00000
ذاكرة الجهاز 0x10000 - 0x40000000

يتم تخصيص الذاكرة الفعلية باستخدام mmap ويتم التبرع بالذاكرة إلى الجهاز الظاهري لملء مناطق الذاكرة الخاصة به ، والتي تسمى فتحات الذاكرة ، KVM_SET_USER_MEMORY_REGION ioctl . لذا تُنسب كل ذاكرة pVM الخاصة بالضيف إلى مثيل crosvm الذي يديرها ويمكن أن يؤدي إلى قتل العملية (إنهاء VM) إذا بدأ المضيف في نفاد الذاكرة الحرة. عند إيقاف جهاز افتراضي ، يتم مسح الذاكرة تلقائيًا بواسطة برنامج Hypervisor وإعادتها إلى نواة المضيف.

تحت KVM العادي ، يحتفظ VMM بالوصول إلى جميع ذاكرة الضيف. باستخدام pKVM ، يتم إلغاء تعيين ذاكرة الضيف من مساحة العنوان الفعلي للمضيف عندما يتم التبرع بها للضيف. الاستثناء الوحيد هو الذاكرة التي تمت مشاركتها بشكل صريح بواسطة الضيف ، مثل أجهزة Virtio.

يتم ترك مناطق MMIO في مساحة عنوان الضيف بدون تعيين. الوصول إلى هذه المناطق من قبل الضيف محاصر وينتج عنه حدث I / O على VM FD. تستخدم هذه الآلية لتنفيذ الأجهزة الافتراضية. في الوضع المحمي ، يجب أن يقر الضيف بأنه يتم استخدام منطقة من مساحة العنوان الخاصة به لـ MMIO باستخدام hypercall ، لتقليل مخاطر تسرب المعلومات العرضي.

الجدولة

يتم تمثيل كل وحدة معالجة مركزية افتراضية بواسطة مؤشر ترابط POSIX ويتم جدولتها بواسطة برنامج جدولة Linux المضيف. يستدعي مؤشر الترابط KVM_RUN ioctl على vCPU FD ، مما يؤدي إلى تحويل برنامج Hypervisor إلى سياق vCPU الضيف. يحسب مجدول المضيف الوقت الذي يقضيه في سياق الضيف كوقت مستخدم بواسطة مؤشر ترابط vCPU المقابل. يعود KVM_RUN عندما يكون هناك حدث يجب معالجته بواسطة VMM ، مثل الإدخال / الإخراج أو نهاية المقاطعة أو توقف وحدة المعالجة المركزية الافتراضية (vCPU). يعالج VMM الحدث ويستدعي KVM_RUN مرة أخرى.

أثناء KVM_RUN ، يظل مؤشر الترابط قابلاً للاستباق بواسطة مجدول المضيف ، باستثناء تنفيذ كود EL2 Hypervisor ، وهو أمر غير استباقي. لا يوجد لدى pVM الضيف نفسه آلية للتحكم في هذا السلوك.

نظرًا لأنه تتم جدولة جميع سلاسل عمليات vCPU مثل أي مهام أخرى في مساحة المستخدمين ، فإنها تخضع لجميع آليات جودة الخدمة القياسية. على وجه التحديد ، يمكن ربط كل مؤشر ترابط vCPU بوحدات المعالجة المركزية المادية ، أو وضعها في مجموعات cpusets ، أو تعزيزها أو تغطيتها باستخدام لقط الاستخدام ، وتغيير سياسة الأولوية / الجدولة الخاصة بها ، والمزيد.

أجهزة افتراضية

يدعم crosvm عددًا من الأجهزة ، بما في ذلك ما يلي:

  • Virtio-blk لصور القرص المركب ، للقراءة فقط أو للقراءة والكتابة
  • vhost-vsock للتواصل مع المضيف
  • Virtio-PCI كوسيلة نقل Virtio
  • ساعة الوقت الحقيقي pl030 (RTC)
  • 16550a UART للاتصال التسلسلي

البرامج الثابتة pVM

البرنامج الثابت pVM (pvmfw) هو أول كود يتم تنفيذه بواسطة pVM ، على غرار ROM التمهيد لجهاز مادي. الهدف الأساسي لـ pvmfw هو تمهيد التمهيد الآمن واشتقاق السر الفريد لـ pVM. لا يقتصر استخدام pvmfw مع أي نظام تشغيل محدد ، مثل Microdroid ، طالما أن نظام التشغيل مدعوم من قبل crosvm وتم توقيعه بشكل صحيح.

يتم تخزين الملف الثنائي pvmfw في قسم فلاش يحمل نفس الاسم ويتم تحديثه باستخدام OTA .

تمهيد الجهاز

يتم إضافة التسلسل التالي من الخطوات إلى إجراء التمهيد لجهاز يدعم pKVM:

  1. يقوم Android Bootloader (ABL) بتحميل pvmfw من قسمه إلى الذاكرة ويتحقق من الصورة.
  2. تحصل ABL على أسرار محرك تكوين معرف الجهاز (DICE) (معرفات الأجهزة المركبة (CDIs) وسلسلة شهادة التمهيد (BCC)) من أصل الثقة.
  3. تقوم ABL بالقياس واشتقاق النرد لأسرار pvmfw (CDIs) ، وإلحاقها بالثنائي pvmfw.
  4. يضيف ABL عقدة منطقة ذاكرة محفوظة linux,pkvm-guest-firmware-memory المحجوزة إلى DT ، مع وصف موقع وحجم الملف الثنائي pvmfw والأسرار التي اشتقها في الخطوة السابقة.
  5. تسلم ABL التحكم إلى Linux ويقوم Linux بتهيئة pKVM.
  6. تقوم pKVM بفك خرائط منطقة ذاكرة pvmfw من جداول صفحات المرحلة 2 للمضيف وتحميها من المضيف (والضيوف) طوال وقت تشغيل الجهاز.

بعد تمهيد الجهاز ، يتم تمهيد Microdroid وفقًا للخطوات الموجودة في قسم تسلسل التمهيد في مستند Microdroid .

التمهيد pVM

عند إنشاء pVM ، يجب أن ينشئ crosvm (أو VMM آخر) فتحة memslot كبيرة بدرجة كافية ليتم ملؤها بالصورة pvmfw بواسطة برنامج hypervisor. يتم تقييد VMM أيضًا في قائمة السجلات التي يمكن تعيين قيمتها الأولية (x0-x14 لـ vCPU الأساسي ، ولا شيء لـ vCPUs الثانوية). يتم حجز السجلات المتبقية وهي جزء من برنامج hypervisor-pvmfw ABI.

عند تشغيل pVM ، يتحكم المشرف أولاً في وحدة المعالجة المركزية الافتراضية الأساسية إلى pvmfw. يتوقع البرنامج الثابت أن يكون crosvm قد قام بتحميل نواة موقعة من AVB ، والتي يمكن أن تكون أداة تحميل إقلاع أو أي صورة أخرى ، و FDT غير موقعة على الذاكرة عند إزاحات معروفة. يتحقق pvmfw من صحة توقيع AVB ، وفي حالة نجاحه ، يقوم بإنشاء شجرة جهاز موثوق بها من FDT المستلم ، ويمسح أسراره من الذاكرة ، ويتفرع إلى نقطة دخول الحمولة. إذا فشلت إحدى خطوات التحقق ، يقوم البرنامج الثابت بإصدار PSCI SYSTEM_RESET hypercall.

بين الأحذية ، يتم تخزين المعلومات حول مثيل pVM في قسم (جهاز Virtio-blk) ويتم تشفيرها بسر pvmfw للتأكد من أنه ، بعد إعادة التشغيل ، يتم توفير السر للمثيل الصحيح.