Wirtualizacja wspomagana sprzętowo

https://chacker.pl/

Do tej pory widzieliśmy, jak wirtualizację osiągnięto w architekturze x86 przed pojawieniem się wirtualizacji wspomaganej sprzętowo. Aby przezwyciężyć wcześniejsze ograniczenia architektoniczne i pomóc w rozwoju VMM, wprowadzono rozszerzenia sprzętowe. Około 2005 r. niezależnie opracowano dwie główne implementacje: Intel Virtualization Technology Extensions (VT-x) i AMD Virtualization (AMD-V), wcześniej znane jako Secure Virtual Machine (SVM). Pozostała część tego rozdziału obejmie niektóre aspekty VT-x.

Parawirtualizacja

https://chacker.pl/

Widzieliśmy, że prawidłowa wirtualizacja architektury x86 jest skomplikowana i w niektórych przypadkach powolna. Mając na celu uproszczenie projektu hiperwizora i poprawę jego wydajności, niektóre implementacje obrały inny kierunek. Zamiast symulować prawdziwy sprzęt, zapewniono syntetyczne interfejsy do komunikacji i współpracy między maszynami wirtualnymi a VMM. Aby korzystać z tych alternatywnych interfejsów, wymagane są modyfikacje systemu operacyjnego gościa. Jednym ze sposobów, w jaki goście parawirtualizowani mogą komunikować się z VMM, są hiperwywołania. Jest to analogiczne do koncepcji wywołań systemowych używanych przez programy użytkownika do żądania usług z jądra systemu operacyjnego, ale w tym przypadku to gość żąda usług od VMM. Hiperwywołania zastępują funkcjonalność zwykle oferowaną przez komponenty sprzętowe, takie jak procesor, MMU,21 sprzętowych timerów i kontroler przerwań, ale mogą również rozszerzać funkcjonalność o powiadomienia między maszynami wirtualnymi i obsługę pamięci współdzielonej. Urządzenia parawirtualizowane mogą zastąpić emulowaną kartę sieciową i urządzenia pamięci masowej, zastępując je modelem podzielonego sterownika. Urządzenia back-endowe działają w hoście (lub w uprzywilejowanej maszynie wirtualnej), a ich zadaniem jest zarządzanie zasobami systemowymi, oferując jednocześnie gościom syntetyczny interfejs (prostszy i szybszy niż emulowany interfejs sprzętowy). Sterowniki front-endowe działające w gościu komunikują się z urządzeniami back-endowymi. Podstawowa warstwa transportowa dla tego modelu może być zbudowana na wierzchu udogodnień komunikacji między maszynami wirtualnymi, zwykle opartych na buforach pierścieniowych nad pamięcią współdzieloną. Wiele aspektów parawirtualizacji pozostaje, nawet po tym, jak wirtualizacja wspomagana sprzętowo pokonała wiele ograniczeń, które ją spowodowały. Ponadto koncepcja hiperwywołania została włączona do sprzętu (VMCALL22). Obecnie większość hiperwizorów oferuje różne stopnie możliwości parawirtualizacji.

Stronicowanie w tle

https://chacker.pl/

Jednostka zarządzania pamięcią x86 (MMU) mapuje adresy wirtualne (VA) na adresy fizyczne (PA) za pomocą widocznej dla oprogramowania, drzewiastej struktury danych znanej jako wielopoziomowe tabele stron. W normalnych okolicznościach jądro systemu operacyjnego stale uzyskuje dostęp do tabel stron; jednak w wirtualizacji stanowią one krytyczny zasób i bezpośredni dostęp z maszyn wirtualnych nie może być dozwolony. Aby wirtualizować MMU, adresy fizyczne maszyn (czyli adresy fizyczne systemów, czyli SPA) muszą być niewidoczne dla gości, którzy zamiast tego powinni być prezentowani za pomocą zestawu pseudo-fizycznych adresów (czyli adresów fizycznych gości, czyli GPA). MMU można postrzegać jako „mapę ϕ”; zwirtualizowany MMU mapowałby GVA na GPA. Do mapowania GPA na SPA potrzebna jest „mapa f”, ale początkowo x86 nie posiadał takiego mechanizmu (został on później wprowadzony wraz z EPT). Aby obejść to ograniczenie, zaimplementowano techniki stronicowania w tle. Stronicowanie w tle polega na przejęciu „mapy ϕ” (tabel stron używanych przez MMU) i przedstawieniu gościom zestawu wirtualnych tabel stron(mapowanie GVA na GPA). Każda próba zapisu gościa do zestawu wirtualnych tabel stron zostanie zatrzymana w VMM, który odpowiednio synchronizuje rzeczywisty zestaw tabel stron (mapowanie GVA i HVA na SPA). Translacja adresów jest wykonywana poprzez przechodzenie przez wielopoziomowe tabele stron, co jest procesem całkowicie opartym na PA i rozpoczynającym się od PA najwyższej tabeli wskazywanej przez rejestr CR3. Natomiast po włączeniu stronicowania dostęp do pamięci spowodowany przez instrukcje jest oparty na VA, w tym na samych tabelach stron, dla których muszą być one mapowane samodzielnie, aby uzyskać do nich dostęp. Ta zasada samoodniesienia może być wykorzystana przez VMM do wdrożenia stronicowania w tle.

UWAGA Będziemy używać terminu system physical address (SPA) w odniesieniu do adresu fizycznego maszyny, a terminu guest physical address (GPA) w odniesieniu do pseudo-fizycznego adresu widzianego przez gościa. W przypadku numeru ramki strony (PFN) będziemy używać numeru ramki strony systemowej (SPFN) lub numeru ramki strony gościa (GPFN). W przypadku adresu wirtualnego (VA) będziemy używać adresu wirtualnego hosta (HVA) lub adresu wirtualnego gościa (GVA). Należy pamiętać, że istnieją inne schematy nazewnictwa odnoszące się do tych samych terminów, których używamy.

VMM musi obsługiwać próby dostępu gościa do konfiguracji MMU i/lub tabel stron. Aby uzyskać dostęp do konfiguracji MMU, gość musi wykonać uprzywilejowane instrukcje (aby uzyskać dostęp, na przykład, do rejestrów CR3 lub CR4). Pułapka na uprzywilejowane instrukcje, więc obsługa tego przypadku jest prosta. Obsługa dostępu gościa do tabel stron jest bardziej skomplikowana i obejmuje konstrukcję zestawu pseudo-tabel stron. Gdy gość próbuje ustawić PA na CR3, PA jest w rzeczywistości GPA dla tego, co gość uważa za najwyższy poziom własnych tabel stron. Pułapki dostępu do zapisu CR3 trafiają do VMM, który obsługuje je, wykonując następujące kroki:

  1. Pobierz SPA odpowiadające GPA użytemu przez gościa do ustawienia CR3.
  2. Zmapuj SPA na HVA i zacznij przeglądać pseudo-tabelę stron przez nią wskazywaną; każdy wpis zawiera GPA (GPFN) następnego poziomu tabel stron.
  3. Dla każdej tabeli stron GPA pobierz jej SPA i powtórz od kroku 2.
  4. Dla każdej tabeli stron utwórz tabelę stron cienia. Ta tabela stron cienia będzie używana przez MMU, ale będzie niewidoczna dla gościa. Wpisy będą albo wskazywać na tabelę następnego poziomu, albo mapować GVA. Jeśli wpis wskazuje na tabelę następnego poziomu, jej SPA musi wskazywać na odpowiadającą jej tabelę stron cienia. Jeśli mapuje GVA, to wpis musi kodować SPA GPA, który odpowiada GVA.
  5. Jeśli GVA mapuje GPA należące do zestawu pseudo-tabel stron, to odpowiadający mu wpis w tabeli stron cienia jest ustawiany jako tylko do odczytu.

W ten sposób za każdym razem, gdy gość próbuje zaktualizować własne tabele stron, próba zapisu zostanie przechwycona w VMM, który obsłuży dostęp i zaktualizuje odpowiadające im tabele stron cienia. Poniższa ilustracja pokazuje przykład, w jaki sposób GVA PDPT gościa może zostać przetłumaczony przez mechanizm stronicowania cienia.

Goście mogą czytać bezpośrednio ze swoich pseudo-tabel stron. Ponadto tłumaczenia MMU są wykonywane bezpośrednio z GPA do SPA przez tabele stron w tle, więc nie ma tam kosztów wydajnościowych. Z drugiej strony obsługa aktualizacji tabel stron jest złożona i kosztowna z dwóch powodów. Po pierwsze, specjalistyczne procedury interpretera (emulator x86) są wymagane dla każdej potencjalnej instrukcji wykonującej aktualizację. Po drugie, zarówno pseudo-tabele stron, jak i tabele stron w tle muszą być zsynchronizowane. Minimalnym kosztem każdej aktualizacji tabeli stron jest koszt pułapki w VMM (jak wyjaśniono wcześniej, koszt ten można zmniejszyć dzięki adaptacyjnemu tłumaczeniu binarnemu).

Kompresja pierścieniowa

https://chacker.pl/

Wiemy, że architektura wirtualizowalna wymaga dwóch trybów działania: trybu nadzorcy do uruchamiania VMM i trybu użytkownika do uruchamiania programów VM. Gdy x86 przejdzie w tryb chroniony, zapewnione są cztery poziomy ochrony (pierścienia), z których dwa są powszechnie używane przez systemy operacyjne: Ring-0 dla kodu jądra i Ring-3 dla programów użytkownika. Próby wykonania instrukcji uprzywilejowanej na dowolnym poziomie pierścienia innym niż Ring-0 powodują pułapkę (#GPF). Zgodnie z tym projektem maszyny wirtualne powinny być wykonywane tylko na poziomach pierścienia 1–3, podczas gdy VMM powinien działać na poziomie Ring-0. Aby to osiągnąć, jądro systemu operacyjnego działające na maszynie wirtualnej musi zostać zdegradowane z poziomu Ring-0 do jednego z pozostałych poziomów. Mechanizm stronicowania x86 może rozróżniać tylko strony „supervisor” i „user”. Poziomy pierścienia 0–2 mogą uzyskać dostęp do obu (z wyjątkiem sytuacji, gdy wymuszane są SMAP i SMEP15), podczas gdy Ring-3 może uzyskać dostęp tylko do stron „user”. Tak więc, jeśli chcemy użyć stronicowania do ochrony pamięci VMM, maszyny wirtualne powinny mieć możliwość działania tylko w trybie Ring-3. Oznacza to, że nie byłoby różnicy w poziomie uprawnień jądra i jego procesów użytkownika. W typowej implementacji systemu operacyjnego wirtualna przestrzeń adresowa jest podzielona na dwie połowy, mapując pamięć jądra na każdy proces użytkownika. Ten schemat ma kilka zalet, takich jak proste rozróżnianie wskaźników użytkownika/jądra, przechowywanie adresów jądra w pamięci podręcznej w TLB i możliwość wykonywania bezpośrednich operacji kopiowania z jądra na adresy użytkownika. Z drugiej strony, takie współdzielenie przestrzeni adresowej ułatwiało eksploatację jądra przez długi czas i stworzyło potrzebę wielu środków zaradczych (KASLR,16 UDEREF,17 SMEP i SMAP).

UWAGA W ostatnich latach odkryto szereg luk w zabezpieczeniach związanych z wykonywaniem przejściowym, które mogą być wykorzystane między innymi do wycieku zawartości pamięci uprzywilejowanej do trybu użytkownika. Aby złagodzić wiele z nich, wymuszana jest izolacja tabeli stron jądra (KPTI19); co zabawne, działa ona poprzez usuwanie większości mapowań jądra z procesów użytkownika, co niweczy większość korzyści wydajnościowych zapewnianych przez podział pamięci.

Współdzielenie przestrzeni adresowej staje się problematyczne, gdy jądro zostanie umieszczone w Ring-3. Tak jak jest, VMM nie może chronić pamięci jądra dla procesów użytkownika, chyba że zostanie ona odmapowana i ponownie zamapowana między przełączeniami kontekstowymi, ale byłoby to zbyt kosztowne. Rozwiązaniem jest umieszczenie jądra w Ring-1. W ten sposób stronicowanie może chronić pamięć jądra (strony nadzorcy) przed przestrzenią użytkownika. Jest pewien haczyk: stronicowanie nie może chronić stron nadzorcy VMM przed Ring-1, jednak nadal możemy użyć segmentacji, aby chronić pamięć VMM przed jądrem gościa.

UWAGA: x86_64 usunął większość funkcji segmentacji, więc rozwiązanie Ring-1 nie może być używane w trybie długim. Niektóre modele częściowo obsługują limity segmentów za pośrednictwem funkcji EFER.LMSLE20, ale obecnie częściej spotyka się procesory x86_64 z rozszerzeniami wirtualizacji sprzętowej, co, jak zobaczymy później, oszczędzi nam kłopotu związanego z martwieniem się o kompresję pierścieniową.

UWAGA: x86_64 usunął większość funkcji segmentacji, więc rozwiązanie Ring-1 nie może być używane w trybie długim. Niektóre modele częściowo obsługują limity segmentów za pośrednictwem funkcji EFER.LMSLE20, ale obecnie częściej spotyka się procesory x86_64 z rozszerzeniami wirtualizacji sprzętowej, co, jak zobaczymy później, oszczędzi nam kłopotu związanego z martwieniem się o kompresję pierścieniową.

Dynamiczne tłumaczenie binarne

https://chacker.pl/

Dynamiczne tłumaczenie binarne (DBT) to technika używana do przepisania kodu binarnego celu na natywny kod odpowiedniego hosta. Jest powszechnie używana przez emulatory w połączeniu z interpretacją binarną lub jako jej zamiennik (gdzie każda instrukcja jest interpretowana przez oprogramowanie) w celu osiągnięcia szybszych prędkości wykonywania. Instrukcje docelowe są tłumaczone w locie, jak w kompilatorze JIT. DBT może być złożone i wymaga specjalnego traktowania przypadków skrajnych, takich jak samomodyfikujący się kod. DBT można używać do obejścia problemów spowodowanych przez nieuprzywilejowane, wrażliwe instrukcje. W przeciwieństwie do emulatorów, w których wykonywany jest złożony, międzyarchitekturowy typ tłumaczenia, stosowana jest prostsza, lekka translacja x86-x86, w której zachowana jest większość oryginalnych instrukcji. Modyfikacje są wprowadzane tylko do wrażliwych nieuprzywilejowanych instrukcji, adresowania względnego i instrukcji przepływu sterowania. Konieczność wykonania modyfikacji w dwóch ostatnich jest bezpośrednią konsekwencją efektów ubocznych w rozmiarze kodu spowodowanych przez sam proces tłumaczenia. Instrukcje wrażliwe są tłumaczone na kod, który symuluje wykonanie oryginalnej instrukcji z punktu widzenia celu. Implementatorzy VMM zdali sobie sprawę, że mogą rozszerzyć użycie DBT, aby tłumaczyć uprzywilejowane instrukcje, aby uniknąć nadmiernych pułapek i poprawić wydajność. Koncepcja została dodatkowo rozszerzona, aby wykonywać adaptacyjne tłumaczenie binarne”13 instrukcji, które będą przechwytywać podczas uzyskiwania dostępu do zasobów systemowych (na przykład aktualizacje tabeli stron, gdy używana jest pamięć cienia). Nastąpiły inne ulepszenia, takie jak tłumaczenie klastrów instrukcji powodujących pułapki

Wirtualizacja x86

https://chacker.pl/

Przed pojawieniem się rozszerzeń wirtualizacji sprzętowej w architekturze x86 nie było żadnych mechanizmów zapewniających mapy niewidoczne dla oprogramowania (f-map) ani pułapki (VM-fault). Nadal jednak możliwe byłoby zaimplementowanie VMM na mechanizmach widocznych dla oprogramowania (pamięć wirtualna i wyjątki sprzętowe). Pytanie brzmi, czy architektura x86 spełnia wymagania wirtualizacji Popka i Goldberga? Pierwsze twierdzenie wirtualizacji mówi, że zestaw wrażliwych instrukcji powinien być podzbiorem instrukcji uprzywilejowanych. Architektura x86 nie spełnia tego wymogu, ponieważ jej zestaw instrukcji zawiera wrażliwe instrukcje, które nie należą do zestawu instrukcji uprzywilejowanych.10 Aby zrozumieć, dlaczego jest to ważne ograniczenie, przyjrzyjmy się bliżej jednej z tych instrukcji. Naszym studium przypadku jest instrukcja Store Interrupt Descriptor Table Register (SIDT), która przechowuje zawartość rejestru IDTR, składającą się z rozmiaru i podstawy bieżącego IDT11, w adresie pamięci jego operandu docelowego. Wiadomo, że instrukcja SIDT jest problematyczna, ponieważ można ją wykonać w trybie użytkownika, aby pobrać adres jądra bieżącego IDT. Ta sytuacja zmusiła programistów jądra do podjęcia środków, takich jak mapowanie IDT z dala od reszty jądra i uczynienie go tylko do odczytu, aby zapobiec jego wykorzystaniu jako wektora eksploatacji.

UWAGA Intel w końcu wprowadził funkcję o nazwie User-Mode Instruction Prevention (UMIP12), aby zabronić wykonywania w trybie użytkownika następujących instrukcji: SGDT, SIDT, SLDT, SMSW i STR. Wszystkie te instrukcje są poufne i nieuprzywilejowane!

Wdrożenie VMM dla x86 wymagałoby przejęcia mechanizmu pułapki poprzez zainstalowanie własnego IDT VMM i zapewnienie gościom zwirtualizowanych IDT, które z ich perspektywy powinny być nieodróżnialne od prawdziwych IDT. Maszyna wirtualna nie powinna mieć możliwości wykonywania kodu w Ring-0, aby upewnić się, że każda próba wykonania w niej uprzywilejowanej instrukcji spowoduje ogólny błąd ochrony (#GPF). W ten sposób VMM może przechwytywać i emulować uprzywilejowane instrukcje wykonywane przez maszyny wirtualne. W jaki sposób SIDT może zakłócać działanie tego VMM? Wyobraź sobie maszynę wirtualną wykonującą kod jądra w Ring-3. Ten kod jądra chce uzyskać informacje o swoim własnym wirtualnym IDT i robi to, wykonując instrukcję SIDT. Ponieważ nie jest to uprzywilejowana instrukcja, procesor ją wykonuje i nigdy nie występuje #GPF. Gość nie otrzymuje „IDTR” swojego własnego wirtualnego IDT, ale zawartość IDTR rzeczywistego IDT zainstalowanego przez VMM. Właściwość równoważności jest uszkodzona, a właściwość kontroli zasobów jest naruszona przez ujawnienie poufnych informacji o hoście gościowi.

Typ 1 i Typ 2 VMM

https://chacker.pl/

Implementacja VMM może działać na gołym metalu lub na rozszerzonym interfejsie maszyny. Implementacje hypervisora ​​działające na gołym metalu są znane jako Typ 1 (natywne), podczas gdy te działające na rozszerzonym interfejsie maszyny są znane jako Typ 2 (hostowane). Obecnie różne rozwiązania wirtualizacji twierdzą, że są Typu 1 lub Typu 2. Jeśli będziemy się czepiać, zobaczymy, że większość z nich nie do końca pasuje do tej kategoryzacji, ponieważ w tym rozróżnieniu VMM jest uważany za monolityczny komponent, podczas gdy w rzeczywistości proces wirtualizacji jest zwykle rozproszony między kilka komponentów działających na różnych poziomach uprawnień.

Typ 2 VMM powinien być łatwiejszy do wdrożenia, ponieważ może wykorzystywać istniejące funkcje udostępniane przez system operacyjny hosta. Jednak zazwyczaj wymaga rozszerzenia systemu operacyjnego hosta o funkcje potrzebne VMM. Zazwyczaj widzimy rozwiązania wirtualizacyjne tego typu (takie jak VMware Workstation i VirtualBox6), które instalują w tym celu zestaw sterowników jądra. Resztą zajmuje się proces roboczy działający w trybie użytkownika. Niektóre rozwiązania podające się za typ 1, takie jak KVM7, nie różnią się zbytnio od tego schematu implementacji. Trudnością, z jaką borykają się VMM typu 1, jest potrzeba ogromnej liczby sterowników sprzętowych. Niektóre implementacje rozwiązują ten problem, umożliwiając VMM przekazywanie niektórych zasobów systemowych do uprzywilejowanych maszyn wirtualnych. Podczas procesu rozruchu VMM tworzy uprzywilejowaną maszynę wirtualną, aby odciążyć wiele zadań wirtualizacji, takich jak obsługa urządzeń sprzętowych i zapewnianie rozszerzonego interfejsu maszyny dla procesów roboczych. W Xen8 ta uprzywilejowana maszyna wirtualna jest znana jako dom0, podczas gdy w Hyper-V9 nazywa się ją partycją główną. Inne rozwiązania typu 1, takie jak VMware ESXi, uruchamiają własne jądro (VMkernel) w celu uruchomienia pozostałej części stosu wirtualizacji.

Goldberg’s Hardware Virtualizer

https://chacker.pl/

Architektury wirtualizowalne i sprzęt zaprojektowany do obsługi wielozadaniowych systemów operacyjnych mają podobne cechy. Te podobieństwa wynikają z istnienia mechanizmów sprzętowych, które chronią zasoby systemowe przed programami nieuprzywilejowanymi (użytkownika). W Tabeli możemy zobaczyć porównanie obok siebie.

Możemy również zaobserwować podobieństwa między VMM a wielozadaniowym jądrem systemu operacyjnego. Jądro systemu operacyjnego działa w trybie wykonywania uprzywilejowanego, ma kontrolę nad zasobami systemowymi (czas procesora, pamięć i pamięć masowa) i zapewnia programom użytkownika środowisko, w którym działają wydajnie. Różnica polega na tym, że nie ma właściwości równoważności, ponieważ środowisko dostarczane przez system operacyjny nie ma być duplikatem rzeczywistej maszyny. Zamiast tego programy użytkownika są prezentowane z „rozszerzonym interfejsem maszyny”, który jest kombinacją zasobów sprzętowych dostępnych z trybu nieuprzywilejowanego i interfejsu oprogramowania jądra. Wydajna wirtualizacja tych mechanizmów ochrony może być trudna. Goldberg rozważał to w jednej ze swoich poprzednich prac, gdy zaproponował „wirtualizator sprzętowy”. Wprowadził koncepcję dwóch różnych typów mapowań zasobów: mapowań widocznych dla oprogramowania kontrolowanych przez system operacyjny i mapowań niewidocznych dla oprogramowania kontrolowanych przez VMM. Rozróżnia się również pułapki widoczne dla oprogramowania (obsługiwane przez system operacyjny) i pułapki niewidoczne dla oprogramowania (obsługiwane przez maszynę VMM), nazywane błędami maszyny wirtualnej.

UWAGA: Moduł jądra Windows 9x został nazwany „Virtual Machine Manager” (VMM.vxd), co jest ciekawym wyborem nazwy dla jądra, które nie radziło sobie najlepiej z ochroną zasobów systemowych przed programami bez uprawnień.

Przykładem mapowania zasobów widocznych w oprogramowaniu jest mechanizm stronicowania, którego systemy operacyjne używają do mapowania adresu pamięci wirtualnej na stronę fizyczną lub nieobecną stronę. Gdy program próbuje uzyskać dostęp do pamięci z mapowania adresu wirtualnego na nieobecną stronę, powoduje to wyjątek błędu strony. Wyjątek jest obsługiwany przez jądro systemu operacyjnego, które decyduje, co z nim zrobić. Goldberg definiuje to mapowanie widoczne w oprogramowaniu jako „mapę ϕ”, a wyjątek błędu strony byłby pułapką widoczną w oprogramowaniu.

Wirtualizator sprzętowy wprowadza nowy rodzaj mapowania zwany „fmap”, który jest niewidoczny dla oprogramowania uruchomionego na maszynie wirtualnej i jest kontrolowany przez VMM. Mówiąc prościej, f-map mapuje wirtualne zasoby maszyny wirtualnej na rzeczywiste zasoby sprzętowe. Oprogramowanie uruchomione na maszynie wirtualnej uzyskuje dostęp do swoich zasobów za pośrednictwem złożonej mapy „f ° ϕ”.

Mapa f może również odwoływać się do zasobu, który nie istnieje; w takim przypadku próba dostępu spowoduje błąd maszyny wirtualnej.

Wreszcie, f-mapę można zdefiniować w kategoriach rekurencyjnego VMM, więc mówi się, że mapuje zasoby wirtualne poziomu „n+1” na zasoby poziomu „n”. Gdy poziom „n” wynosi 0, mapa odnosi się do rzeczywistych zasobów sprzętowych. Zagnieżdżona wirtualizacja jest możliwa dzięki rekurencyjnej kompozycji f-mapy dla „n” poziomów. Poniższa ilustracja pokazuje prosty przykład, gdzie „n=1”.

Twierdzenia wirtualizacji Popka i Goldberga

https://chacker.pl/

W 1974 r. Gerald J. Popek i Robert P. Goldberg opublikowali swoje twierdzenia wirtualizacji3, w których formalnie przedstawili wymagania dotyczące wydajnych architektur wirtualizowalnych. Musimy poznać tę teorię, zanim przejdziemy do bardziej namacalnych implementacji, abyśmy mogli zrozumieć ich powiązania.

Ich praca zaczyna się od założenia modelu komputera składającego się z procesora z trybami wykonywania użytkownika/nadzorcy i prostym mechanizmem pułapki. W tym modelu pamięć jest jedynym zasobem systemowym, do którego procesor uzyskuje dostęp poprzez liniowe, względne adresowanie z rejestru relokacji. Instrukcje procesora są klasyfikowane w następujący sposób:

  • Instrukcje uprzywilejowane Te instrukcje są dostępne tylko w trybie wykonywania nadzorcy. W tym modelu każda próba wykonania instrukcji uprzywilejowanej powoduje pułapkę, jeśli tryb wykonywania procesora jest trybem użytkownika.
  • Instrukcje wrażliwe na sterowanie Te instrukcje mają wpływ na konfigurację jednego lub wielu zasobów systemowych. W obecnym modelu te efekty obejmują wartość rejestru relokacji i tryb wykonywania procesora.
  • Instrukcje wrażliwe na zachowanie Te instrukcje wykazują różne zachowanie w zależności od konfiguracji zasobów systemowych. W obecnym modelu mogą być one dotknięte konfiguracją rejestru relokacji (wrażliwe na lokalizację) lub bieżącym trybem wykonywania procesora (wrażliwe na tryb).
  • Instrukcje nieszkodliwe Te instrukcje nie są ani wrażliwe na sterowanie, ani wrażliwe na zachowanie.

UWAGA Niektóre z oryginalnych definicji odzwierciedlają aspekty architektur, które istniały w czasie publikacji pracy. Dla uproszczenia niektóre definicje zastąpiono mniej precyzyjnymi.

VMM jest definiowany jako część oprogramowania działająca w trybie nadzorcy i składa się z następujących modułów:

  • Dispatcher Jest to punkt wejścia obsługi pułapki i wywołuje albo alokator, albo interpreter w zależności od źródła pułapki.
  • Allocator Jest wywoływany przez dyspozytora, gdy VM próbuje wykonać instrukcję wrażliwą na sterowanie. Alokator zarządza zasobami systemu, izolując zasoby VMM od maszyn wirtualnych i te przypisane do maszyn wirtualnych od siebie.
  • Interpreter Jest wywoływany przez dyspozytora, gdy VM próbuje wykonać instrukcję uprzywilejowaną. Interpreter symuluje zachowanie błędnej instrukcji, tak jakby była wykonywana natywnie.

VM jest definiowany jako środowisko wirtualne — a dokładniej jako „wydajny, odizolowany duplikat rzeczywistej maszyny”. Maszyny wirtualne działają w trybie użytkownika i prezentują następujące właściwości:

  • Equivalence Programy działające na maszynie wirtualnej powinny wykazywać identyczne zachowanie jak wykonywanie natywne.
  • Wydajność Nieszkodliwe instrukcje powinny być wykonywane bezpośrednio przez

CPU. Programy uruchamiane na maszynie wirtualnej powinny wykazywać „w najgorszym przypadku tylko niewielkie spadki prędkości”.

  • Kontrola zasobów Programy uruchamiane na maszynie wirtualnej nie mogą uzyskać dostępu do zasobów, które nie zostały wyraźnie przydzielone przez maszynę wirtualną lub które w jakikolwiek sposób wpływają na inne zasoby systemu.

Z tych definicji wynikają trzy twierdzenia wirtualizacji:

  • Dla dowolnego komputera można skonstruować maszynę wirtualną, jeśli zestaw jego wrażliwych instrukcji jest podzbiorem zestawu instrukcji uprzywilejowanych.
  • Komputer jest rekurencyjnie wirtualizowalny, jeśli (a) jest wirtualizowalny i (b) można skonstruować dla niego maszynę wirtualną bez zależności czasowych.
  • Hybrydową maszynę wirtualną (HVM) można skonstruować dla dowolnego komputera, w którym zestaw wrażliwych instrukcji użytkownika jest podzbiorem zestawu instrukcji uprzywilejowanych.

Pierwsze twierdzenie ma ważne implikacje dla właściwości równoważności i kontroli zasobów. Jeśli zbiór wrażliwych instrukcji (związek instrukcji wrażliwych na sterowanie i wrażliwych na zachowanie) jest instrukcjami uprzywilejowanymi, wówczas każda próba wykonania wrażliwej instrukcji przez maszynę wirtualną spowoduje pułapkę w dyspozytorze maszyny wirtualnej. Dyspozytor wywoła alokator, jeśli pułapka pochodzi z instrukcji wrażliwej na sterowanie (właściwość kontroli zasobów jest zachowana) lub interpreter, jeśli pułapka pochodzi z instrukcji wrażliwej na zachowanie (właściwość równoważności jest zachowana). Nieszkodliwe instrukcje są albo bezpośrednio wykonywane przez procesor, albo obsługiwane przez interpreter, jeśli są instrukcjami uprzywilejowanymi (właściwość równoważności jest zachowana). Ten rodzaj implementacji maszyny wirtualnej jest znany jako „pułapka i emulator”, a architektura jest uważana za „klasycznie wirtualizowalną”, jeśli maszynę wirtualną można w pełni zaimplementować w ten sposób. Drugie twierdzenie odnosi się do komputera rekurencyjnie wirtualizowalnego, obecnie nazywanego „wirtualizacją zagnieżdżoną”. Podczas gdy teoretycznie środowisko wirtualne dostarczane przez maszynę wirtualną powinno być duplikatem rzeczywistej maszyny, w praktyce nie zawsze tak jest. Zamiast tego może reprezentować ograniczony podzbiór lub podobną rodzinę komputerów. Przykładem z tamtego okresu jest CP-67 działający na IBM S/360-67, który obsługiwał stronicowanie, ale udostępniał środowisko wirtualne S/360-65 bez obsługi stronicowania. Brak stronicowania nie pozwalał na rekurencyjne uruchamianie CP-67, do czego wymagał modyfikacji. Nawet jeśli VMM zapewnia środowisko wirtualne ze wszystkimi wymaganymi przez siebie funkcjami, nadal musi działać wydajnie w tym środowisku. W trzecim twierdzeniu napotykamy kilka nowych definicji: instrukcja wrażliwa na użytkownika jest definiowana jako instrukcja, która jest wrażliwa, gdy jest wykonywana w trybie użytkownika; podobnie instrukcja wrażliwa na nadzorcę jest wrażliwa, gdy jest wykonywana w trybie nadzorcy. Wreszcie, HVM jest definiowany jako mniej wydajna implementacja VMM, w której cały kod wykonywany w trybie wirtualnego nadzorcy jest interpretowany. Twierdzenie to łagodzi wymagania pierwszego twierdzenia, dzięki czemu niektóre istniejące wówczas architektury mogą je spełnić.

Czym jest hiperwizor?

https://chacker.pl/

Hiperwizor lub monitor maszyny wirtualnej (VMM) to składnik działający w hoście, który zarządza tworzeniem, przydzielaniem zasobów i wykonywaniem maszyn wirtualnych (VM). Każda maszyna wirtualna zapewnia odizolowane środowisko wirtualne, w którym mogą działać różne systemy operacyjne (OS). Wirtualizacja to koncepcja sięgająca końca lat 60., kiedy IBM rozwijał swoje pierwsze systemy CP/CMS1: oprogramowanie VMM o nazwie Control Program (CP), które mogło uruchamiać maszyny wirtualne z lekkim systemem operacyjnym o nazwie CMS. Jednak pierwszy udany produkt, który w pełni wirtualizował 32-bitowe procesory x86, pojawił się dekady później, kiedy w 1999 r. wprowadzono VMware Workstation2.