Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Wirtualny tryb bezpieczny (VSM) to zestaw funkcji hypervisor i oświecenia oferowanych do hostowania i partycji gościa, co umożliwia tworzenie i zarządzanie nowymi granicami zabezpieczeń w oprogramowaniu systemu operacyjnego. VSM to funkcja hypervisor, w której są oparte funkcje zabezpieczeń systemu Windows, takie jak Device Guard, Credential Guard, wirtualne moduły TPM i chronione maszyny wirtualne. Te funkcje zabezpieczeń zostały wprowadzone w systemach Windows 10 i Windows Server 2016.
Program VSM umożliwia oprogramowanie systemu operacyjnego w partycjach głównych i partycji gościa w celu utworzenia izolowanych regionów pamięci na potrzeby przechowywania i przetwarzania zasobów zabezpieczeń systemu. Dostęp do tych izolowanych regionów jest kontrolowany i udzielany wyłącznie za pośrednictwem funkcji hypervisor, która jest wysoce uprzywilejowaną, wysoce zaufaną częścią zaufanej bazy obliczeniowej systemu (TCB). Ponieważ funkcja hypervisor działa na wyższym poziomie uprawnień niż oprogramowanie systemu operacyjnego i ma wyłączną kontrolę nad kluczowymi zasobami sprzętowymi systemu, takimi jak kontrola uprawnień dostępu do pamięci w mmu procesora CPU i IOMMU na wczesnym etapie inicjowania systemu, funkcja hypervisor może chronić te odizolowane regiony przed nieautoryzowanym dostępem, nawet z oprogramowania systemu operacyjnego (np. jądra systemu operacyjnego i sterowników urządzeń) z dostępem w trybie nadzorcy (tj. CPL0, lub "Pierścień 0").
W przypadku tej architektury, nawet jeśli normalne oprogramowanie na poziomie systemu działające w trybie nadzorcy (np. jądro, sterowniki itp.) zostało naruszone przez złośliwe oprogramowanie, zasoby w izolowanych regionach chronionych przez funkcję hypervisor mogą pozostać zabezpieczone.
Wirtualny poziom zaufania (VTL)
Program VSM osiąga i utrzymuje izolację za pomocą wirtualnych poziomów zaufania (VTLs). Listy VTL są włączone i zarządzane zarówno dla poszczególnych partycji, jak i na procesor wirtualny.
Wirtualne poziomy zaufania są hierarchiczne, a wyższe poziomy są bardziej uprzywilejowane niż niższe poziomy. VTL0 jest najniższym poziomem uprzywilejowanym, a VTL1 jest bardziej uprzywilejowany niż VTL0, VTL2 jest bardziej uprzywilejowany niż VTL1 itp.
Obsługiwane są architektury do 16 poziomów list wirtualnych; jednak funkcja hypervisor może zdecydować się na zaimplementowanie mniej niż 16 wirtualnych bibliotek. Obecnie implementowane są tylko dwie listy VTLs.
typedef UINT8 HV_VTL, *PHV_VTL;
#define HV_NUM_VTLS 2
#define HV_INVALID_VTL ((HV_VTL) -1)
#define HV_VTL_ALL 0xF
Każda sieć VTL ma własny zestaw ochrony dostępu do pamięci. Te zabezpieczenia dostępu są zarządzane przez funkcję hypervisor w fizycznej przestrzeni adresowej partycji, a tym samym nie mogą być modyfikowane przez oprogramowanie na poziomie systemu działające w partycji.
Ponieważ bardziej uprzywilejowane listy VTL mogą wymuszać własne zabezpieczenia pamięci, wyższe listy VTLs mogą skutecznie chronić obszary pamięci przed niższymi listami VTLs. W praktyce pozwala to na ochronę regionów izolowanej pamięci przez zabezpieczenie ich przy użyciu wyższej biblioteki VTL. Na przykład VTL0 może przechowywać wpis tajny w wersji VTL1, w którym tylko VTL1 może uzyskać do niego dostęp. Nawet jeśli bezpieczeństwo VTL0 zostanie naruszone, wpis tajny będzie bezpieczny.
Zabezpieczenia biblioteki VTL
Istnieje wiele aspektów do osiągnięcia izolacji między wirtualnymi listami wirtualnymi:
- Ochrona dostępu do pamięci: każda wersja VTL utrzymuje zestaw ochrony dostępu do pamięci fizycznej gościa. Oprogramowanie działające w określonej sieci VTL może uzyskiwać dostęp tylko do pamięci zgodnie z tymi zabezpieczeniami.
- Stan procesora wirtualnego: procesory wirtualne zachowują oddzielny stan na VTL. Na przykład każda sieć VTL definiuje zestaw prywatnych rejestrów vp. Oprogramowanie działające w niższej wersji wirtualnej nie może uzyskać dostępu do wyższego stanu rejestru prywatnego procesora wirtualnego VTL.
- Przerwania: Wraz z oddzielnym stanem procesora każda biblioteka VTL ma również własny podsystem przerwania (lokalny interfejs APIC na x64, interfejs procesora GIC w arm64). Dzięki temu wyższe listy VTL przetwarzają przerwania bez ryzyka zakłóceń z niższej sieci VTL.
- Strony nakładki: niektóre strony nakładki są utrzymywane dla sieci VTL, tak aby wyższe listy VTLs miały niezawodny dostęp. Na przykład istnieje oddzielna strona nakładki hipercall na bibliotekę VTL.
Wykrywanie i stan programu VSM
Funkcja VSM jest anonsowana do partycji za pośrednictwem flagi uprawnień partycji AccessVsm. Tylko partycje ze wszystkimi następującymi uprawnieniami mogą korzystać z programu VSM: AccessVsm, AccessVpRegisters i AccessSynicRegs.
Wykrywanie możliwości programu VSM
Goście mogą uzyskać dostęp do raportu na temat możliwości programu VSM za pośrednictwem rejestru syntetycznego.
Na platformach x64
Na platformach x64 ten rejestr jest dostępny za pośrednictwem msR:
| Adres MSR | Nazwa rejestracji | Description |
|---|---|---|
| 0x000D0006 | HV_X64_REGISTER_VSM_CAPABILITIES | Raport dotyczący możliwości programu VSM. |
Na platformach ARM64
Na platformach ARM64 ten rejestr jest dostępny za pośrednictwem HvRegisterVsmCapabilities przy użyciu funkcji hypercallVpRegisters HvCallGetVpRegisters.
Format rejestrowania
Na platformach x64
| Bity | Description | Attributes |
|---|---|---|
| 63 | Dr6Shared | Przeczytaj |
| 62:47 | MbecVtlMask | Przeczytaj |
| 46 | DenyLowerVtlStartup | Przeczytaj |
| 45:0 | RsvdZ | Przeczytaj |
Na platformach ARM64
| Bity | Description | Attributes |
|---|---|---|
| 63 | RsvdZ | Przeczytaj |
| 62:47 | MbecVtlMask | Przeczytaj |
| 46 | DenyLowerVtlStartup | Przeczytaj |
| 45:0 | RsvdZ | Przeczytaj |
Opisy pól
Dr6Shared (tylko x64): wskazuje gościowi, czy dr6 jest rejestrem udostępnionym między listami wirtualnymi.
MbecVtlMask: wskazuje gościa listy VTLs, dla których można włączyć MBEC.
DenyLowerVtlStartup: wskazuje gościowi, czy VTL może odmówić zresetowania vp reset przez niższą bibliotekę VTL.
Rejestrowanie stanu programu VSM
Oprócz flagi uprawnień partycji można użyć dwóch rejestrów wirtualnych, aby dowiedzieć się więcej o stanie programu VSM: HvRegisterVsmPartitionStatus i HvRegisterVsmVpStatus.
HvRegisterVsmPartitionStatus
HvRegisterVsmPartitionStatus to rejestr tylko do odczytu dla partycji, który jest współużytkowany we wszystkich listach VTLs. Ten rejestr zawiera informacje o tym, które listy VTL zostały włączone dla partycji, które maszyny wirtualne mają włączone kontrolki wykonywania opartego na trybie, a także maksymalną dozwoloną bibliotekę VTL.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 EnabledVtlSet : 16;
UINT64 MaximumVtl : 4;
UINT64 MbecEnabledVtlSet: 16;
UINT64 ReservedZ : 28;
};
} HV_REGISTER_VSM_PARTITION_STATUS;
HvRegisterVsmVpStatus
HvRegisterVsmVpStatus to rejestr tylko do odczytu i jest współużytkowany na wszystkich listach VTLs. Jest to rejestr na vp, co oznacza, że każdy procesor wirtualny utrzymuje własne wystąpienie. Ten rejestr zawiera informacje o tym, które listy VTL zostały włączone, które są aktywne, a także tryb MBEC aktywny w vp.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 ActiveVtl : 4;
UINT64 ActiveMbecEnabled : 1;
UINT64 ReservedZ0 : 11;
UINT64 EnabledVtlSet : 16;
UINT64 ReservedZ1 : 32;
};
} HV_REGISTER_VSM_VP_STATUS;
ActiveVtl jest identyfikatorem kontekstu VTL, który jest obecnie aktywny na procesorze wirtualnym.
ActiveMbecEnabled określa, że MBEC jest obecnie aktywny na procesorze wirtualnym.
EnabledVtlSet to mapa bitowa biblioteki VTL, która jest włączona na procesorze wirtualnym.
Partycjonowanie stanu początkowego biblioteki VTL
Po uruchomieniu lub zresetowaniu partycji rozpoczyna się ono w pliku VTL0. Wszystkie pozostałe listy VTL są wyłączone podczas tworzenia partycji.
Włączanie biblioteki VTL
Aby rozpocząć korzystanie z biblioteki VTL, niższa wersja VTL musi zainicjować następujące elementy:
- Włącz docelową bibliotekę VTL dla partycji. Dzięki temu VTL jest ogólnie dostępna dla partycji.
- Włącz docelową bibliotekę VTL na co najmniej jednym procesorze wirtualnym. Spowoduje to udostępnienie biblioteki VTL dla vp i ustawienie jej kontekstu początkowego. Zaleca się, aby wszystkie maszyny wirtualne miały te same włączone listy VTLS. Włączenie biblioteki VTL na niektórych maszynach wirtualnych (ale nie wszystkich) może prowadzić do nieoczekiwanego zachowania.
- Po włączeniu biblioteki VTL dla partycji i vp można rozpocząć ustawianie ochrony dostępu po ustawieniu flagi EnableVtlProtection.
Należy pamiętać, że listy VTLs nie muszą być kolejne.
Włączanie docelowej biblioteki VTL dla partycji
HvCallEnablePartitionVtl hypercall służy do włączania biblioteki VTL dla określonej partycji. Należy pamiętać, że aby oprogramowanie było w rzeczywistości wykonywane w określonej wersji VTL, należy włączyć bibliotekę VTL na procesorach wirtualnych w partycji.
Włączanie docelowej biblioteki VTL dla procesorów wirtualnych
Po włączeniu biblioteki VTL dla partycji można ją włączyć na procesorach wirtualnych partycji. HypercallEnableVpVtl funkcji hypercall HvCall może służyć do włączania list VTLs dla procesora wirtualnego, który ustawia swój kontekst początkowy.
Procesory wirtualne mają jeden "kontekst" na bibliotekę VTL. W przypadku przełączenia biblioteki VTL stan prywatny biblioteki VTL jest również przełączany.
Konfiguracja biblioteki VTL
Po włączeniu biblioteki VTL jej konfiguracja może zostać zmieniona przez wiceprezesa działającego w równej lub wyższej wersji wirtualnej.
Konfiguracja partycji
Atrybuty dla całej partycji można skonfigurować przy użyciu rejestru HvRegisterVsmPartitionConfig. Istnieje jedno wystąpienie tego rejestru dla każdej biblioteki VTL (większej niż 0) na każdej partycji.
Każda VTL może modyfikować własne wystąpienie HV_REGISTER_VSM_PARTITION_CONFIG, a także wystąpienia dla niższych list wirtualnych. Listy VTLs mogą nie modyfikować tego rejestru dla wyższych list VTLs.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 EnableVtlProtection : 1;
UINT64 DefaultVtlProtectionMask : 4;
UINT64 ZeroMemoryOnReset : 1;
UINT64 DenyLowerVtlStartup : 1;
UINT64 ReservedZ : 2;
UINT64 InterceptVpStartup : 1;
UINT64 ReservedZ : 54; };
} HV_REGISTER_VSM_PARTITION_CONFIG;
Pola tego rejestru zostały opisane poniżej.
Włączanie ochrony biblioteki VTL
Po włączeniu biblioteki VTL należy ustawić flagę EnableVtlProtection przed rozpoczęciem stosowania ochrony pamięci. Ta flaga jest zapisywana raz, co oznacza, że po jej ustawieniu nie można go modyfikować.
Domyślna maska ochrony
Domyślnie system stosuje ochronę RWX do wszystkich aktualnie zamapowanych stron i wszystkich przyszłych stron "dodanych do gorąco". Strony dodane na gorąco odwołują się do każdej pamięci dodawanej do partycji podczas operacji zmiany rozmiaru.
Wyższa wartość VTL może ustawić inne domyślne zasady ochrony pamięci, określając wartość DefaultVtlProtectionMask w HV_REGISTER_VSM_PARTITION_CONFIG. Ta maska musi być ustawiona w momencie włączenia biblioteki VTL. Nie można go zmienić po jego ustawieniu i jest czyszczone tylko przez resetowanie partycji.
| Bit | Description |
|---|---|
| 0 | Przeczytaj |
| 1 | Napisz |
| 2 | Wykonywanie trybu jądra (KMX) |
| 3 | Wykonywanie trybu użytkownika (UMX) |
Zero pamięci przy resetowaniu
ZeroMemOnReset jest bitem, który kontroluje, czy pamięć jest zerowana przed zresetowanie partycji. Ta konfiguracja jest domyślnie włączona. Jeśli bit jest ustawiony, pamięć partycji jest zerowa po zresetowaniu, dzięki czemu wyższa pamięć VTL nie może zostać naruszona przez niższą bibliotekę VTL. Jeśli ten bit zostanie wyczyszczone, pamięć partycji nie zostanie zerowana podczas resetowania.
DenyLowerVtlStartup
Flaga DenyLowerVtlStartup określa, czy procesor wirtualny może zostać uruchomiony lub zresetowany przez niższe listy VTLs. Obejmuje to sposoby resetowania procesora wirtualnego (np. SIPI na X64), a także funkcji hypercall HvCallStartVirtualProcessor .
InterceptVpStartup
Jeśli flaga InterceptVpStartup jest ustawiona, uruchomienie lub zresetowanie procesora wirtualnego generuje przechwycenie do wyższej biblioteki VTL.
Konfigurowanie niższych list wirtualnych
Poniższy rejestr może być używany przez wyższe listy VTLs w celu skonfigurowania zachowania niższych list VTLs:
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 MbecEnabled : 1;
UINT64 TlbLocked : 1;
UINT64 ReservedZ : 62;
};
} HV_REGISTER_VSM_VP_SECURE_VTL_CONFIG;
Każda wartość VTL (wyższa niż 0) ma wystąpienie tego rejestru dla każdej biblioteki VTL niższej niż sama. Na przykład VTL2 będzie mieć dwa wystąpienia tego rejestru — jedno dla VTL1, a drugi dla VTL0.
Pola tego rejestru zostały opisane poniżej.
MbecEnabled
To pole określa, czy mbEC jest włączony dla niższej listy VTL.
TlbLocked
To pole blokuje dolną wartość TLB biblioteki VTL. Tej funkcji można użyć, aby zapobiec powstawaniu niższych list VTL powodujących unieważnienie TLB, które mogą zakłócać wyższą bibliotekę VTL. Po ustawieniu tego bitu wszystkie żądania opróżniania przestrzeni adresowej z dolnej listy VTL są blokowane do momentu usunięcia blokady.
Aby odblokować moduł TLB, wyższa wartość VTL może wyczyścić ten bit. Ponadto po powrocie vp do niższej wersji VTL zwalnia wszystkie blokady TLB, które posiada w tym czasie.
Wpis VTL
VTL jest "wprowadzony", gdy vp przełącza się z niższej VTL do wyższej. Może się to zdarzyć z następujących powodów:
- Wywołanie biblioteki VTL: jest to, gdy oprogramowanie jawnie chce wywołać kod w wyższej wersji VTL.
- Bezpieczne przerwanie: jeśli zostanie odebrane przerwanie dla wyższej biblioteki VTL, wiceprezes wejdzie do wyższego poziomu VTL.
- Bezpieczne przechwytywanie: niektóre akcje spowodują bezpieczne przerwanie (na przykład uzyskanie dostępu do określonych msR).
Po wprowadzeniu biblioteki VTL musi dobrowolnie wyjść. Wyższej biblioteki VTL nie można wywłaszeć przez niższą bibliotekę VTL.
Identyfikowanie przyczyny wpisu biblioteki VTL
Aby odpowiednio zareagować na wpis, może być konieczne zapoznanie się z przyczyną wprowadzenia wyższej biblioteki VTL. Aby odróżnić przyczyny wejścia, wpis VTL jest zawarty w strukturze HV_VP_VTL_CONTROL .
Wywołanie VTL
Wywołanie "VTL" jest wtedy, gdy niższa VTL inicjuje wpis do wyższej biblioteki VTL (na przykład w celu ochrony regionu pamięci z wyższym VTL) za pośrednictwem funkcji hypercall HvCallVtlCall .
Wywołania VTL zachowują stan rejestrów udostępnionych w przełącznikach VTL. Rejestry prywatne są zachowywane na poziomie na poziomie VTL. Wyjątkiem od tych ograniczeń są rejestry/instrukcje wymagane przez sekwencję wywołań VTL.
Na platformach x64
Następujące rejestry są wymagane do wywołania VTL na x64:
| x64 | x86 | Description |
|---|---|---|
| RCX | EDX:EAX | Określa wejście kontrolki wywołania VTL do funkcji hypervisor |
| RAX | ECX | Zarezerwowana |
Wszystkie bity w danych wejściowych kontrolek wywołań VTL są obecnie zarezerwowane.
Na platformach ARM64
Na platformach ARM64 wywołanie VTL jest inicjowane przy użyciu instrukcji HVC z natychmiastową wartością 2. Funkcja hypervisor dekoduje tę konkretną natychmiastową wartość i przetwarza ją jako hipercall HvCallVtlCall. Dla danych wejściowych kontrolki w usłudze ARM64 nie jest wymagany określony stan rejestracji.
Ograniczenia połączeń VTL
Wywołania VTL można inicjować tylko z trybu procesora najbardziej uprzywilejowanego. Na przykład w systemach x64 wywołanie VTL może pochodzić tylko z CPL0 i w systemach ARM64 z EL1. Wywołanie VTL zainicjowane z trybu procesora, który jest dowolny, ale najbardziej uprzywilejowany w systemie powoduje, że funkcja hypervisor wprowadza wyjątek do procesora wirtualnego (#UD na x64, niezdefiniowany wyjątek instrukcji na arm64).
Wywołanie VTL może przełączyć się tylko na następny najwyższy poziom VTL. Innymi słowy, jeśli jest włączona wiele list wirtualnych, wywołanie nie może "pominąć" biblioteki VTL. Następujące akcje powodują wyjątek (#UD na x64, niezdefiniowana instrukcja w usłudze ARM64):
- Wywołanie VTL zainicjowane z trybu procesora, który jest dowolny, ale najbardziej uprzywilejowany w systemie (specyficzne dla architektury).
- Wywołanie VTL z trybu rzeczywistego (tylko x86/x64)
- Wywołanie VTL na procesorze wirtualnym, w którym docelowa sieć VTL jest wyłączona (lub nie została jeszcze włączona).
- Wywołanie VTL z nieprawidłową wartością wejściową kontrolki
Zamykanie biblioteki VTL
Przełącznik do niższej biblioteki VTL jest znany jako "return". Po zakończeniu przetwarzania biblioteki VTL może zainicjować powrót VTL w celu przełączenia się do niższej listy VTL. Jedynym sposobem, w jaki może wystąpić zwrot VTL, jest to, że wyższa VTL dobrowolnie inicjuje. Niższa VTL nigdy nie może wyprzedać wyższego.
Zwracanie biblioteki VTL
Zwrot "VTL" jest wtedy, gdy wyższe VTL inicjuje przełącznik do niższej VTL za pośrednictwem HvCallVtlReturn hypercall. Podobnie jak wywołanie VTL, stan prywatnego procesora jest wyłączony, a stan współużytkowany pozostaje w miejscu. Jeśli niższa biblioteka VTL jawnie wywoła do wyższej biblioteki VTL, funkcja hypervisor zwiększa wskaźnik instrukcji wyższej biblioteki VTL przed zakończeniem powrotu, aby można było kontynuować po wywołaniu biblioteki VTL.
Na platformach x64
Sekwencja kodu zwrotnego VTL na x64 wymaga użycia następujących rejestrów:
| x64 | x86 | Description |
|---|---|---|
| RCX | EDX:EAX | Określa wejście kontrolki powrotnej VTL do funkcji hypervisor |
| RAX | ECX | Zarezerwowana |
Na platformach ARM64
Na platformach ARM64 zwracana wartość VTL jest inicjowana przy użyciu instrukcji HVC z natychmiastową wartością 3. Funkcja hypervisor dekoduje tę konkretną natychmiastową wartość i przetwarza ją jako hipercall HvCallVtlReturn.
Wejście kontrolki zwrotnej VTL
Dane wejściowe kontrolki zwracanej VTL mają następujący format:
| Bity | (No changes needed) | Description |
|---|---|---|
| 63:1 | RsvdZ | |
| 0 | Szybki zwrot | Rejestry nie są przywracane |
Następujące akcje spowodują wygenerowanie wyjątku #UD:
- Próba zwrócenia listy VTL, gdy najniższa wartość VTL jest obecnie aktywna
- Próba zwrócenia biblioteki VTL z nieprawidłową wartością wejściową kontrolki
- Próba zwrotu biblioteki VTL z trybu procesora, który jest czymś, co jest najbardziej uprzywilejowane w systemie (specyficzne dla architektury)
Szybki zwrot
W ramach przetwarzania zwrotu funkcja hypervisor może przywrócić stan rejestrowania niższej biblioteki VTL ze struktury HV_VP_VTL_CONTROL . Na przykład po przetworzeniu bezpiecznego przerwania wyższa wersja VTL może chcieć powrócić bez zakłócania stanu niższej sieci VTL. W związku z tym funkcja hypervisor udostępnia mechanizm umożliwiający po prostu przywrócenie rejestrów niższej biblioteki VTL do ich wartości przed wywołaniami przechowywanej w strukturze sterowania biblioteki VTL.
Jeśli to zachowanie nie jest konieczne, wyższa wartość VTL może używać "szybkiego powrotu". Szybki zwrot występuje, gdy funkcja hypervisor nie przywraca stanu rejestru ze struktury sterowania. Powinno to być używane zawsze, gdy jest to możliwe, aby uniknąć niepotrzebnego przetwarzania.
To pole można ustawić z bitem 0 zwracanych danych wejściowych biblioteki VTL. Jeśli ustawiono wartość 0, rejestry zostaną przywrócone ze struktury HV_VP_VTL_CONTROL. Jeśli ten bit ma wartość 1, rejestry nie zostaną przywrócone (szybki zwrot).
Asystent strony funkcji Hypercall (tylko x64)
Na platformach x64 funkcja hypervisor udostępnia mechanizmy ułatwiające wywołania VTL i zwracane za pośrednictwem strony hypercall. Ta strona stanowi abstrakcję konkretnej sekwencji kodu wymaganej do przełączenia list wirtualnych.
Sekwencje kodu służące do wykonywania wywołań I zwracania biblioteki VTL mogą być dostępne przez wykonanie określonych instrukcji na stronie hypercall. Fragmenty wywołań/powrotu znajdują się na przesuniętej stronie hiperwołania określonej przez wirtualny rejestr HvRegisterVsmCodePageOffsets. Jest to rejestr tylko do odczytu i dla całej partycji z oddzielnym wystąpieniem na dysk VTL.
VTL może wykonać wywołanie/zwrócenie biblioteki VTL przy użyciu instrukcji CALL. Wywołanie poprawnej lokalizacji na stronie hypercall spowoduje zainicjowanie wywołania/zwrotu biblioteki VTL.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 VtlCallOffset : 12;
UINT64 VtlReturnOffset : 12;
UINT64 ReservedZ : 40;
};
} HV_REGISTER_VSM_CODE_PAGE_OFFSETS;
Podsumowując, kroki wywoływania sekwencji kodu przy użyciu strony hypercall na x64 są następujące:
- Mapowanie strony hipercall na przestrzeń gpA biblioteki VTL
- Określ poprawne przesunięcie sekwencji kodu (wywołanie lub zwrócenie biblioteki VTL).
- Wykonaj sekwencję kodu przy użyciu metody CALL.
Uwaga: Na platformach ARM64 wywołania I zwroty biblioteki VTL są wykonywane bezpośrednio przy użyciu instrukcji HVC z określonymi wartościami bezpośrednimi (2 dla wywołania VTL, 3 dla zwrotu VTL), zgodnie z opisem w sekcjach Wywołanie VTL i zwracanie biblioteki VTL. Rejestr HvRegisterVsmCodePageOffsets nie jest dostępny w usłudze ARM64.
Ochrona dostępu do pamięci
Jedną z niezbędnych ochrony zapewnianych przez program VSM jest możliwość izolowania dostępu do pamięci.
Wyższe listy VTL mają wysoki stopień kontroli nad typem dostępu do pamięci dopuszczalnym przez niższe listy VTLs. Istnieją trzy podstawowe typy ochrony, które można określić przez wyższą bibliotekę VTL dla określonej strony gpA: Odczyt, Zapis i eXecute. Są one zdefiniowane w poniższej tabeli:
| Name | Description |
|---|---|
| Przeczytaj | Określa, czy dostęp do odczytu jest dozwolony na stronie pamięci |
| Napisz | Określa, czy dostęp do zapisu jest dozwolony na stronie pamięci |
| Wykonaj | Określa, czy pobieranie instrukcji jest dozwolone dla strony pamięci. |
Te trzy połączenia dla następujących typów ochrony pamięci:
- Brak dostępu
- Tylko do odczytu, bez wykonywania
- Wykonywanie tylko do odczytu
- Odczyt/zapis, bez wykonywania
- Odczyt/zapis, wykonywanie
Jeśli jest włączona opcja "kontrola wykonywania oparta na trybie (MBEC)," można ustawić oddzielnie zabezpieczenia wykonywania w trybie użytkownika i jądra.
Wyższe listy VTL mogą ustawiać ochronę pamięci dla gpA za pośrednictwem funkcji hypercall HvCallModifyVtlProtectionMask .
Hierarchia ochrony pamięci
Uprawnienia dostępu do pamięci można ustawić według wielu źródeł dla określonej biblioteki VTL. Uprawnienia każdej biblioteki VTL mogą być potencjalnie ograniczone przez wiele innych list wirtualnych, a także przez partycję hosta. Kolejność stosowania ochrony jest następująca:
- Ochrona pamięci ustawiona przez hosta
- Ochrona pamięci ustawiona przez wyższe listy VTLs
Innymi słowy, ochrona VTL zastępuje ochronę hosta. Listy VTLs wyższego poziomu zastępują listy VTLS niższego poziomu. Należy pamiętać, że sieć VTL może nie ustawiać uprawnień dostępu do pamięci dla siebie.
Oczekuje się, że zgodny interfejs nie nakłada żadnego typu innego niż RAM na pamięć RAM.
Naruszenia dostępu do pamięci
Jeśli wiceprezes działający w niższej wersji wirtualnej próbuje naruszyć ochronę pamięci ustawioną przez wyższą bibliotekę VTL, zostanie wygenerowany przechwycenie. Przechwycenie jest odbierane przez wyższą bibliotekę VTL, która ustawia ochronę. Dzięki temu wyższe listy VTL mogą radzić sobie z naruszeniem w zależności od przypadku. Na przykład wyższa wartość VTL może wybrać opcję zwrócenia błędu lub emulować dostęp.
Mode Based Execute Control (MBEC)
Gdy VTL umieszcza ograniczenie pamięci na niższej liście VTL, może być konieczne rozróżnienie między użytkownikiem a trybem jądra podczas udzielania uprawnień "wykonaj". Jeśli na przykład kontrole integralności kodu miały miejsce w wyższej wersji VTL, możliwość rozróżnienia między trybem użytkownika i trybem jądra oznaczałaby, że VTL może wymusić integralność kodu tylko dla aplikacji w trybie jądra.
Oprócz tradycyjnych trzech ochrony pamięci (odczyt, zapis, wykonywanie), MBEC wprowadza rozróżnienie między trybem użytkownika i trybem jądra w celu wykonywania ochrony. W związku z tym, jeśli MBEC jest włączony, VTL ma możliwość ustawienia czterech typów ochrony pamięci:
| Name | Description |
|---|---|
| Przeczytaj | Określa, czy dostęp do odczytu jest dozwolony na stronie pamięci |
| Napisz | Określa, czy dostęp do zapisu jest dozwolony na stronie pamięci |
| Wykonywanie trybu użytkownika (UMX) | Określa, czy pobieranie instrukcji wygenerowane w trybie użytkownika jest dozwolone dla strony pamięci. UWAGA: Jeśli mbEC jest wyłączony, to ustawienie jest ignorowane. |
| Wykonywanie trybu jądra (KMX) | Określa, czy pobieranie instrukcji wygenerowane w trybie jądra jest dozwolone dla strony pamięci. UWAGA: Jeśli mbEC jest wyłączony, to ustawienie kontroluje dostęp zarówno w trybie użytkownika, jak i w trybie jądra. |
Pamięć oznaczona ochroną "User-Mode Execute" będzie wykonywalna tylko wtedy, gdy procesor wirtualny działa w trybie użytkownika. Podobnie "Kernel-Mode Execute" pamięć będzie wykonywalna tylko wtedy, gdy procesor wirtualny jest uruchomiony w trybie jądra.
KmX i UMX można ustawić niezależnie, tak aby uprawnienia wykonywania są wymuszane inaczej między użytkownikiem a trybem jądra. Obsługiwane są wszystkie kombinacje UMX i KMX, z wyjątkiem KMX=1, UMX=0. Zachowanie tej kombinacji jest niezdefiniowane.
MbEC jest domyślnie wyłączony dla wszystkich maszyn wirtualnych i procesorów wirtualnych. Gdy funkcja MBEC jest wyłączona, bit wykonywania w trybie jądra określa ograniczenie dostępu do pamięci. W związku z tym, jeśli MBEC jest wyłączony, kod KMX=1 jest wykonywalny zarówno w trybie jądra, jak i użytkownika.
Tabele deskryptora (tylko x64)
Na platformach x64 każdy kod trybu użytkownika, który uzyskuje dostęp do tabel deskryptora, musi znajdować się na stronach GPA oznaczonych jako KMX=UMX=1. Oprogramowanie w trybie użytkownika, które uzyskuje dostęp do tabel deskryptorów z poziomu strony GPA oznaczonej jako KMX=0, jest nieobsługiwane i powoduje ogólną usterkę ochrony.
Arm64 nie używa tabel deskryptorów w stylu x86; Uprawnienia dostępu do pamięci są kontrolowane za pośrednictwem wpisów tabeli tłumaczenia i modelu uprawnień opartych na el.
Konfiguracja MBEC
Aby można było korzystać z kontrolki wykonywania opartej na trybie, musi być ona włączona na dwóch poziomach:
- Po włączeniu biblioteki VTL dla partycji należy włączyć protokół MBEC przy użyciu biblioteki HvCallEnablePartitionVtl
- MbEC należy skonfigurować dla poszczególnych vp i na VTL przy użyciu HvRegisterVsmVpSecureConfigVtlX.
Interakcja MBEC z zapobieganiem wykonywaniu trybu nadzorcy (SMEP) (tylko x64)
Supervisor-Mode Execution Prevention (SMEP) to funkcja procesora obsługiwana na platformach x64. SmeP może mieć wpływ na działanie MBEC ze względu na ograniczenie dostępu nadzorcy do stron pamięci. Funkcja hypervisor jest zgodna z następującymi zasadami związanymi z smep:
- Jeśli smeP nie jest dostępny dla systemu operacyjnego gościa (niezależnie od tego, czy jest to spowodowane możliwościami sprzętowymi lub trybem zgodności procesora), mbEC działa bez wpływu.
- Jeśli narzędzie SMEP jest dostępne i jest włączone, mbEC działa bez wpływu.
- Jeśli rozwiązanie SMEP jest dostępne i jest wyłączone, wszystkie ograniczenia wykonywania podlegają kontrolce KMX. W związku z tym tylko kod oznaczony jako KMX=1 będzie mógł zostać wykonany.
Izolacja stanu procesora wirtualnego
Procesory wirtualne zachowują oddzielne stany dla każdej aktywnej biblioteki VTL. Jednak niektóre z tych stanów są prywatne dla konkretnej biblioteki VTL, a pozostały stan jest współużytkowany między wszystkie listy VTLs.
Funkcja hypervisor obsługuje kontekst dla każdego procesora wirtualnego, przechowując cały stan procesora widocznego dla gościa, który musi być odizolowany między wirtualnymi listami wirtualnymi. Każda biblioteka VTL ma własne wystąpienie stanu prywatnego, w tym rejestry kontrolek, wektory wyjątków, rejestry konfiguracji systemu i syntetyczne rejestry funkcji hypervisor. Ten magazyn dla biblioteki VTL zapewnia pełną izolację kontekstu wykonywania podczas przełączania między poziomami zaufania.
Stan, który jest zachowywany dla listy VTL (czyli stanu prywatnego) jest zapisywany przez funkcję hypervisor w przejściach biblioteki VTL. Jeśli przełącznik VTL jest inicjowany, funkcja hypervisor zapisuje bieżący stan prywatny dla aktywnej biblioteki VTL, a następnie przełącza się do stanu prywatnego docelowej biblioteki VTL. Stan udostępniony pozostaje aktywny niezależnie od przełączników VTL.
Stan prywatny
Każda wersja VTL zachowuje swój własny pełny kontekst wykonywania składający się z:
- Stan wykonywania: wskaźnik instrukcji (PC/RIP), wskaźnik stosu (SP/RSP), flagi procesora (PSTATE/RFLAGS)
- Rejestry kontrolek: Konfiguracja zarządzania pamięcią (tabele stron, kontrolki tłumaczenia, atrybuty pamięci)
- Obsługa wyjątków: wektory wyjątków/przerwania, rejestry zespołów wyjątków, rejestry adresów błędów
- Konfiguracja systemu: kontrolki funkcji procesora, kontrolki debugowania, konfiguracja czasomierza
- Rejestry syntetyczne: interfejs funkcji Hypervisor rejestruje specyficzne dla każdej biblioteki VTL (strona hypercall, identyfikator systemu operacyjnego gościa, odwołanie do TSC, syntetyczny kontroler przerwań)
Ta izolacja gwarantuje, że każda maszyna wirtualna ma niezależną kontrolę nad środowiskiem wykonywania i nie może obserwować ani zakłócać stanu prywatnego innych maszyn wirtualnych.
Na platformach x64
Na platformach x64 każda biblioteka VTL utrzymuje swój własny kontekst wykonywania za pomocą reguł MSR specyficznych dla architektury i rejestrów. Funkcja hypervisor zachowuje je w przełącznikach VTL, zapewniając pełną izolację środowiska wykonawczego.
Prywatne procedury MSR kontrolują mechanizmy wywołań systemowych, atrybuty pamięci, funkcje procesora i interfejs funkcji hypervisor.
Architektury MSRs:
- SYSENTER_CS, SYSENTER_ESP, SYSENTER_EIP, STAR, LSTAR, CSTAR, SFMASK, EFER, PAT, KERNEL_GSBASE, FS. BASE, GS. BASE, TSC_AUX
- Lokalne rejestry APIC (w tym CR8/TPR)
Syntetyczne msrs:
- HV_X64_MSR_HYPERCALL
- HV_X64_MSR_GUEST_OS_ID
- HV_X64_MSR_REFERENCE_TSC
- HV_X64_MSR_APIC_FREQUENCY
- HV_X64_MSR_EOI
- HV_X64_MSR_ICR
- HV_X64_MSR_TPR
- HV_X64_MSR_VP_ASSIST_PAGE
- HV_X64_MSR_NPIEP_CONFIG
- HV_X64_MSR_SIRBP
- HV_X64_MSR_SCONTROL
- HV_X64_MSR_SVERSION
- HV_X64_MSR_SIEFP
- HV_X64_MSR_SIMP
- HV_X64_MSR_EOM
- HV_X64_MSR_SINT0 — HV_X64_MSR_SINT15
- HV_X64_MSR_STIMER0_CONFIG — HV_X64_MSR_STIMER3_CONFIG
- HV_X64_MSR_STIMER0_COUNT — HV_X64_MSR_STIMER3_COUNT
Rejestry prywatne kontrolują środowisko wykonywania, zarządzanie pamięcią i obsługę wyjątków:
- Stan wykonywania: RIP (wskaźnik instrukcji), RSP (wskaźnik stosu), RFLAGS (flagi procesora)
- Zarządzanie pamięcią: CR0 (sterowanie procesorem), CR3 (podstawa tabeli stron), CR4 (funkcje procesora)
- Tabele deskryptorów: IDTR (tabela deskryptorów przerwań), GDTR (tabela deskryptora globalnego)
- Rejestry segmentów: CS, DS, ES, FS, GS, SS, TR, LDTR
- Kontrolka debugowania: DR7 (rejestr kontrolek debugowania)
- Sygnatura czasowa: TSC (licznik sygnatury czasowej, zapewniając niezależne odwołanie do czasu na bibliotekę VTL)
- Stan debugowania: DR6 (rejestr stanu debugowania — zależny od typu procesora; przeczytaj HvRegisterVsmCapabilities, aby określić, czy jest współużytkowany, czy prywatny)
Na platformach ARM64
Na platformach ARM64 każda wersja VTL utrzymuje własny pełny kontekst rejestru systemu. Funkcja hypervisor zachowuje te rejestry w przełącznikach VTL, zapewniając pełną izolację środowiska wykonywania i wyjątków.
Stan wykonywania rejestruje przepływ programu sterowania i tryb procesora:
- PC (licznik programu), SP_EL0, SP_EL1 (wskaźniki stosu)
- PSTATE (flagi stanu procesora), FPCR/FPSR (zmiennoprzecinkowa kontrola/stan)
- ELR_EL1, SPSR_EL1 (rejestr linków wyjątków, zapisany stan programu)
Rejestry zarządzania pamięcią i kontroli tłumaczenia konfigurują pamięć wirtualną:
- TTBR0_EL1, TTBR1_EL1 (rejestry podstawowe tabel tłumaczenia)
- TCR_EL1 (rejestr kontrolek tłumaczenia)
- MAIR_EL1 (rejestr pośredni atrybutu pamięci)
- SCTLR_EL1 (rejestr sterowania systemu)
- CONTEXTIDR_EL1 (identyfikator kontekstu)
Obsługa wyjątków i przerwań rejestruje zachowanie wyjątków kontroli:
- VBAR_EL1 (rejestr adresów podstawowych wektorów — lokalizacja tabeli wektorów wyjątków)
- ESR_EL1 (rejestr zespołu wyjątków)
- FAR_EL1 (rejestr adresów błędów)
- AFSR0_EL1, AFSR1_EL1 (pomocnicze rejestry stanu błędów)
Konfiguracja systemu rejestruje funkcje procesora sterowania:
- CPACR_EL1 (kontrola dostępu współprocesora)
- ACTLR_EL1 (pomocniczy rejestr sterowania)
- AMAIR_EL1 (pomocniczy rejestr pośredni atrybutu pamięci)
- ZCR_EL1, SMCR_EL1 (konfiguracja SVE/SME, jeśli jest obsługiwana)
Rejestry debugowania i monitorowania wydajności są prywatne. Obejmuje to wszystkie rejestry systemu debugowania (MDSCR_EL1, DBGBCR_EL1[], DBGBVR_EL1[], DBGWCR_EL1[], DBGWVR_EL1[], itp.) i wszystkie rejestry monitora wydajności (PMCR_EL0 i powiązane rejestry PMU)
Rejestry konfiguracji czasomierza :
- CNTKCTL_EL1 (kontrolka czasomierza jądra)
- CNTV_CTL_EL0, CNTV_CVAL_EL0 (wirtualna kontrolka czasomierza i porównywanie wartości)
Rejestry identyfikacji wątków:
- TPIDR_EL0, TPIDR_EL1, TPIDRRO_EL0 (rejestry identyfikatorów wątków)
Syntetyczne rejestry funkcji Hypervisor (dostępne za pośrednictwem funkcji hypercalls, a nie bezpośrednio jako rejestry systemowe):
- HvRegisterGuestOsId (identyfikacja systemu operacyjnego gościa)
- HvRegisterHypercallMsrValue (włączanie interfejsu hypercall)
- HvRegisterReferenceTsc (strona licznika sygnatury czasowej odwołania)
- HvRegisterVpAssistPage (strona pomocy VP dla tej biblioteki VTL)
- Syntetyczne rejestry kontrolerów przerwań (SynIC)
- Syntetyczne rejestry czasomierzy (Stimer0-3)
- Interfejs lokalnego kontrolera przerwań (interfejs procesora GIC)
Ta kompleksowa izolacja rejestrowania dla sieci VTL gwarantuje, że każda biblioteka VTL ma pełną kontrolę nad środowiskiem wykonywania, zarządzaniem pamięcią, obsługą wyjątków i interfejsem funkcji hypervisor bez ingerencji z innych list wirtualnych.
Stan wspólny
Listy VTLs współużytkują określony stan procesora, aby zmniejszyć nakład pracy związany z przejściami biblioteki VTL i umożliwić wydajną komunikację między poziomami zaufania. Stan udostępniony obejmuje rejestry ogólnego przeznaczenia używane do obliczeń i przekazywania danych, stanu zmiennoprzecinkowego i niektórych rejestrów stanu systemu, które nie mają wpływu na granice zabezpieczeń.
Dzięki udostępnieniu rejestrów ogólnego przeznaczenia na listach wirtualnych wywołanie biblioteki VTL może przekazywać parametry bezpośrednio w rejestrach, a zwrot VTL może przekazywać wyniki z powrotem bez konieczności komunikacji opartej na pamięci. Ten projekt znacznie poprawia wydajność wywołań między VTL przy zachowaniu izolacji zabezpieczeń zapewnianej przez stan prywatny.
Na platformach x64
Na platformach x64 stan udostępniony obejmuje rejestry ogólnego przeznaczenia na potrzeby obliczeń, rejestrów informacji systemowych i niektórych rejestrów stanu, które nie mają wpływu na izolację zabezpieczeń.
Udostępnione msrs zapewniają informacje o systemie i konfigurację, która jest powszechna w różnych listach VTLs:
- HV_X64_MSR_TSC_FREQUENCY
- HV_X64_MSR_VP_INDEX
- HV_X64_MSR_VP_RUNTIME
- HV_X64_MSR_RESET
- HV_X64_MSR_TIME_REF_COUNT
- HV_X64_MSR_GUEST_IDLE
- HV_X64_MSR_DEBUG_DEVICE_OPTIONS
- RTRR
- MCG_CAP
- MCG_STATUS
Rejestry udostępnione umożliwiają wydajne przekazywanie i obliczanie danych między wirtualnymi listami wirtualnymi:
- rejestryGeneral-Purpose: Rax, Rbx, Rcx, Rdx, Rsi, Rdi, Rbp, R8-R15 (używane do obliczeń i przekazywania parametrów podczas wywołań VTL)
- Informacje o wyjątku: CR2 (adres liniowy błędu strony — udostępniony dla kontekstu obsługi wyjątków)
- Dane debugowania: DR0-DR3 (rejestry adresów debugowania — używane dla adresów punktów przerwania)
-
Floating-Point i stan wektora:
- Stan zmiennoprzecinkowa X87 (starsze obliczenia zmiennoprzecinkowe)
- Stan XMM (wektory SSE 128-bitowe)
- Stan AVX (wektory 256-bitowe)
- XCR0/XFEM (rozszerzona maska włączania funkcji)
- Stan debugowania: DR6 (rejestr stanu debugowania — zależny od typu procesora; przeczytaj HvRegisterVsmCapabilities, aby określić, czy jest współużytkowany, czy prywatny)
Na platformach ARM64
Na platformach ARM64 stan udostępniony obejmuje rejestry używane do obliczeń, przekazywania danych i operacji zmiennoprzecinkowych. To udostępnianie umożliwia wydajne wywołania biblioteki VTL, umożliwiając przekazywanie parametrów i wyników bezpośrednio w rejestrach.
Rejestry udostępnione umożliwiają obliczanie i komunikację między wirtualnymi listami wirtualnymi:
-
rejestryGeneral-Purpose: X0-X17, X19-X28 (używane do obliczania i przekazywania parametrów)
- X0-X7 zwykle używane dla parametrów funkcji i zwracanych wartości podczas wywołań VTL
- X8-X17, X19-X28 dostępne do obliczeń ogólnych
- Uwaga: X18 (rejestr platformy) i komputer pc są prywatne na VTL ze względów bezpieczeństwa
- Uwaga: X29 (wskaźnik FP/ramka), X30 (rejestr LR/link) i SP są prywatne na VTL
-
Floating-Point i stan wektora:
- Q0-Q31 (128-bitowe rejestry NEON/zmiennoprzecinkowe na potrzeby obliczeń wektorowych)
- Zaawansowany stan SIMD (NEON) dla operacji wektorowych
- Uwaga: stan SVE (Z0-Z31, P0-P15, FFR) i stan SME są prywatne. Dolna część 128-bitowa (rejestry Q) jest współdzielona, ale górne bity rejestrów Z mogą być uszkodzone w przejściach biblioteki VTL. Oprogramowanie nie powinno polegać na zachowywaniu zawartości rejestru Z w przełącznikach VTL.
- Uwaga: stan SPE (statystycznego rozszerzenia profilowania) jest współużytkowany między wirtualnymi listami wirtualnymi, z wyjątkiem PMBSR_EL1, która jest prywatna sieci VTL
-
Rejestry informacji systemowych (tylko do odczytu lub niekrytyczne dla zabezpieczeń):
- Rejestry identyfikacji systemu i funkcji
- Informacje o typie pamięci podręcznej i TLB
Usługa ARM64 jest zgodna z tą samą zasadą co x64: ogólny stan obliczeń jest współużytkowany pod kątem wydajności, podczas gdy stan kontroli i konfiguracji, który wpływa na granice zabezpieczeń, pozostaje prywatny dla każdej biblioteki VTL.
Tryb rzeczywisty (tylko x64)
Tryb rzeczywisty nie jest obsługiwany dla żadnej biblioteki VTL większej niż 0 na platformach x64. Listy VTLs większe niż 0 mogą działać w trybie 32-bitowym lub 64-bitowym w trybie x64.
Zarządzanie przerwaniami biblioteki VTL
Aby osiągnąć wysoki poziom izolacji między poziomami zaufania wirtualnego, wirtualny tryb bezpieczny zapewnia oddzielny podsystem przerwań dla każdego wirtualnego procesora włączonego WTL. Gwarantuje to, że protokół VTL może wysyłać i odbierać przerwania bez zakłóceń z mniej bezpiecznej sieci VTL.
Każdy wirtualny kontroler przerwań ma własny kontroler przerwań, który jest aktywny tylko wtedy, gdy procesor wirtualny jest uruchomiony w tej konkretnej sieci VTL. Jeśli procesor wirtualny przełącza stany VTL, kontroler przerwań aktywny na procesorze jest również przełączany.
Na platformach x64 każda biblioteka VTL ma oddzielne lokalne wystąpienie APIC. Na platformach ARM64 każda wersja VTL ma oddzielną GIC.
Przerwanie skierowane do biblioteki VTL, która jest wyższa niż aktywna VTL, spowoduje natychmiastowe przełączenie VTL. Im wyższa wartość VTL może następnie odebrać przerwanie. Jeśli wyższa VTL nie może odebrać przerwania ze względu na maskę priorytetową (TPR/CR8 na x64, maska priorytetowa GIC na ARM64), przerwanie jest przechowywane jako "oczekujące", a VTL nie przełącza się. Jeśli istnieje wiele list wirtualnych z oczekującymi przerwaniami, najwyższy poziom VTL ma pierwszeństwo (bez powiadomienia do niższej listy VTL).
Gdy przerwanie jest ukierunkowane na niższą bibliotekę VTL, przerwanie nie zostanie dostarczone do czasu następnego przejścia procesora wirtualnego do docelowej biblioteki VTL.
Na platformach x64, init i startup IPI przeznaczone do niższej VTL są porzucane na procesor wirtualny z włączonym wyższym wirtualnym adresem VTL. Ponieważ mechanizmy uruchamiania procesora architektury mogą być blokowane, funkcja hypercall HvCallStartVirtualProcessor powinna służyć do uruchamiania procesorów.
Na platformach ARM64 metody interfejsu PSCI (takie jak CPU_ON) do przenoszenia procesorów w tryb online są podobnie blokowane, gdy włączono wyższą bibliotekę VTL. Funkcja hypercallCallStartVirtualProcessor zapewnia spójny międzyplatformowy mechanizm uruchamiania procesorów.
Maskowanie przerwań i przełączniki VTL
Na platformach x64
Do celów przełączania list VTL, RFLAGS. JEŚLI nie ma wpływu na to, czy bezpieczne przerwanie wyzwala przełącznik VTL. Jeśli RFLAGS. Jeśli zostanie wyczyszczone w celu maskowania przerwań, przerwania w wyższych listach wirtualnych nadal spowodują przełączenie VTL do wyższej listy VTL. Podczas podejmowania decyzji o tym, czy natychmiast przerwać, uwzględniana jest tylko wyższa wartość TPR/CR8.
To zachowanie wpływa również na oczekujące przerwania po powrocie biblioteki VTL. Jeśli RFLAGS. Jeśli bit jest czyszczone w celu maskowania przerwań w danej sieci VTL, a biblioteka VTL zwraca wartość (do niższej wartości VTL), funkcja hypervisor ponownie zwalczy wszelkie oczekujące przerwania. Spowoduje to natychmiastowe wywołanie z powrotem do wyższej biblioteki VTL.
Na platformach ARM64
Podobnie bity maski przerwań PSTATE (DAIF) nie mają wpływu na to, czy bezpieczne przerwanie wyzwala przełącznik VTL. Jeśli przerwania są maskowane za pośrednictwem PSTATE, przerwania ukierunkowane na wyższe listy VTLs nadal będą powodować przełącznik VTL. Uwzględniana jest tylko wyższa maska priorytetowa VTL GIC podczas podejmowania decyzji, czy natychmiast dostarczyć przerwanie.
Asystent powiadomień o przerwaniach wirtualnych
Wyższe listy VTL mogą zarejestrować się w celu otrzymania powiadomienia, jeśli blokują natychmiastowe dostarczanie przerwania do niższej liczby wirtualnych procesorów wirtualnych. Wyższe listy VTLs mogą włączyć wirtualną asystenta powiadamiania o przerwaniu (VINA) za pośrednictwem wirtualnego rejestru HvRegisterVsmVina:
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 Vector : 8;
UINT64 Enabled : 1;
UINT64 AutoReset : 1;
UINT64 AutoEoi : 1;
UINT64 ReservedP : 53;
};
} HV_REGISTER_VSM_VINA;
Każda wersja VTL na każdym vp ma własne wystąpienie VINA, a także własną wersję HvRegisterVsmVina. Obiekt VINA wygeneruje przerwanie wyzwalane przez krawędź do aktualnie aktywnej wyższej biblioteki VTL, gdy przerwanie dla niższej biblioteki VTL jest gotowe do natychmiastowego dostarczenia.
Aby zapobiec powodzi przerwań występujących po włączeniu tego obiektu, obiekt VINA obejmuje pewien ograniczony stan. Po wygenerowaniu przerwania VINA stan obiektu VINA zostanie zmieniony na "Asertywne". Wysłanie końca przerwania do SINT skojarzonego z obiektem VINA nie spowoduje wyczyszczenia stanu "Asertywne". Stan asertywne można wyczyścić tylko na jeden z dwóch sposobów:
- Stan można wyczyścić ręcznie, pisząc do pola VinaAsserted struktury HV_VP_VTL_CONTROL .
- Stan jest automatycznie czyszczone w następnym wpisie do biblioteki VTL, jeśli w rejestrze HvRegisterVsmVina jest włączona opcja "automatyczne resetowanie we wpisie VTL".
Dzięki temu kod działający w bezpiecznym wirtualnymtlu może być powiadamiany o pierwszym przerwaniu odebranym dla niższej wersji wirtualnej. Jeśli bezpieczna VTL chce zostać powiadomiona o dodatkowych przerwaniach, może wyczyścić pole VinaAsserted strony pomocy VP i zostanie powiadomiony o następnym nowym przerwaniu.
Zabezpieczanie przechwytów
Funkcja hypervisor umożliwia wyższą bibliotekę VTL do instalowania przechwytywania zdarzeń, które mają miejsce w kontekście niższej biblioteki VTL. Dzięki temu wyższe listy VTL mają podwyższony poziom kontroli nad niższymi zasobami VTL. Bezpieczne przechwycenia mogą służyć do ochrony zasobów o krytycznym znaczeniu systemu i zapobiegania atakom z niższych list wirtualnych.
Bezpieczny przechwyt jest kolejkowany do wyższej biblioteki VTL i że VTL jest uruchamiany w vp.
Zabezpieczanie typów przechwytywania
| Typ przechwytywania | Przechwytywanie dotyczy |
|---|---|
| Dostęp do pamięci | Próba uzyskania dostępu do ochrony zasad grupy ustanowionych przez wyższą bibliotekę VTL. |
| Kontrola dostępu do rejestru | Próba uzyskania dostępu do zestawu rejestrów kontroli określonych przez wyższą bibliotekę VTL. |
Przechwyty zagnieżdżone
Wiele wirtualnych list wirtualnych może instalować bezpieczne przechwyty dla tego samego zdarzenia w niższej sieci VTL. W związku z tym ustalono hierarchię, aby zdecydować, gdzie zagnieżdżone przechwyty są powiadamiane. Poniższa lista to kolejność powiadamiania o przechwyceniu:
- Niższa VTL
- Wyższa wersja VTL
Obsługa bezpiecznych przechwytów
Po powiadomieniu VTL o bezpiecznym przechwycie należy podjąć działania, tak aby niższa sieć VTL mogła kontynuować. Wyższa VTL może obsługiwać przechwytywanie na wiele sposobów, w tym: wstrzykiwanie wyjątku, emulowanie dostępu lub dostarczanie serwera proxy dostępu do dostępu. W każdym razie, jeśli należy zmodyfikować stan prywatny niższej sieci VTL VP, należy użyć HvCallSetVpRegisters .
Przechwytywanie bezpiecznych rejestrów (tylko x64)
Na platformach x64 wyższy protokół VTL może przechwytywać dostęp do niektórych rejestrów kontroli i msrs. Jest to osiągane przez ustawienie HvX64RegisterCrInterceptControl przy użyciu funkcji hypercallSetVpRegisters HvCallSetVpRegisters . Ustawienie bitu sterującego w HvX64RegisterCrInterceptControl wyzwoli przechwycenie dla każdego dostępu do odpowiedniego rejestru kontrolnego.
Ta funkcja jest specyficzna dla x64, ponieważ przechwytuje rejestry kontrolek x64 (CR0, CR4, XCR0) i x64 MSRs (EFER, LSTAR, STAR itp.). Platformy ARM64 mogą obsługiwać podobne możliwości przechwytywania za pomocą różnych mechanizmów.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 Cr0Write : 1;
UINT64 Cr4Write : 1;
UINT64 XCr0Write : 1;
UINT64 IA32MiscEnableRead : 1;
UINT64 IA32MiscEnableWrite : 1;
UINT64 MsrLstarRead : 1;
UINT64 MsrLstarWrite : 1;
UINT64 MsrStarRead : 1;
UINT64 MsrStarWrite : 1;
UINT64 MsrCstarRead : 1;
UINT64 MsrCstarWrite : 1;
UINT64 ApicBaseMsrRead : 1;
UINT64 ApicBaseMsrWrite : 1;
UINT64 MsrEferRead : 1;
UINT64 MsrEferWrite : 1;
UINT64 GdtrWrite : 1;
UINT64 IdtrWrite : 1;
UINT64 LdtrWrite : 1;
UINT64 TrWrite : 1;
UINT64 MsrSysenterCsWrite : 1;
UINT64 MsrSysenterEipWrite : 1;
UINT64 MsrSysenterEspWrite : 1;
UINT64 MsrSfmaskWrite : 1;
UINT64 MsrTscAuxWrite : 1;
UINT64 MsrSgxLaunchControlWrite : 1;
UINT64 RsvdZ : 39;
};
} HV_REGISTER_CR_INTERCEPT_CONTROL;
Maskuj rejestry
Aby umożliwić bardziej precyzyjną kontrolę, podzbiór rejestrów kontrolnych ma również odpowiednie rejestry maski. Rejestry maski mogą służyć do instalowania przechwytów w podzestawie odpowiednich rejestrów kontrolnych. Jeśli rejestr maski nie jest zdefiniowany, każdy dostęp (zdefiniowany przez HvX64RegisterCrInterceptControl) wyzwoli przechwycenie.
Funkcja hypervisor obsługuje następujące rejestry maski: HvX64RegisterCrInterceptCr0Mask, HvX64RegisterCrInterceptCr4Mask i HvX64RegisterCrInterceptIa32MiscEnableMask.
DmA i urządzenia
Urządzenia mają ten sam poziom uprawnień co VTL0. Po włączeniu programu VSM cała pamięć przydzielona przez urządzenie jest oznaczona jako VTL0. Wszystkie dostępy DMA mają te same uprawnienia co VTL0.