[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 6/6] Make XEN, XENFILT and XENBUS processor group aware
Processor groups have been around for a long time in Windows and contnuing to ignore them becomes ever more painful when trying to pass the HCM multiple processor group device test. This patch, therefore, modifies all the code that uses the non-group-aware kernel calls to use the newer group aware calls. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- include/evtchn_interface.h | 36 ++++- include/shared_info_interface.h | 4 +- include/xen.h | 1 + src/xen/driver.c | 2 + src/xen/system.c | 165 ++++++++++--------- src/xenbus.inf | 1 + src/xenbus/cache.c | 65 +++++--- src/xenbus/driver.c | 2 + src/xenbus/evtchn.c | 342 ++++++++++++++++++++++++++-------------- src/xenbus/evtchn_2l.c | 21 ++- src/xenbus/evtchn_abi.h | 30 ++-- src/xenbus/evtchn_fifo.c | 52 +++--- src/xenbus/fdo.c | 56 ++++--- src/xenbus/fdo.h | 3 +- src/xenbus/pdo.c | 87 +--------- src/xenbus/shared_info.c | 31 ++-- src/xenbus/sync.c | 280 ++++++++++++++++++-------------- src/xenfilt/driver.c | 2 + vs2012/xen/xen.vcxproj | 4 +- vs2012/xenbus/xenbus.vcxproj | 4 +- vs2012/xenfilt/xenfilt.vcxproj | 4 +- vs2013/xen/xen.vcxproj | 4 +- vs2013/xenbus/xenbus.vcxproj | 4 +- vs2013/xenfilt/xenfilt.vcxproj | 4 +- 24 files changed, 690 insertions(+), 514 deletions(-) diff --git a/include/evtchn_interface.h b/include/evtchn_interface.h index 1bc456a..6f8fe42 100644 --- a/include/evtchn_interface.h +++ b/include/evtchn_interface.h @@ -112,18 +112,27 @@ typedef PXENBUS_EVTCHN_CHANNEL ... ); +typedef NTSTATUS +(*XENBUS_EVTCHN_BIND_V2)( + IN PINTERFACE Interface, + IN PXENBUS_EVTCHN_CHANNEL Channel, + IN ULONG Cpu + ); + /*! \typedef XENBUS_EVTCHN_BIND \brief Bind an event channel to a specific CPU \param Interface The interface header \param Channel The channel handle - \param Cpu The CPU that should handle events + \param Group The group number of the CPU that should handle events + \param Number The relative number of the CPU that should handle events */ typedef NTSTATUS (*XENBUS_EVTCHN_BIND)( IN PINTERFACE Interface, IN PXENBUS_EVTCHN_CHANNEL Channel, - IN ULONG Cpu + IN USHORT Group, + IN UCHAR Number ); typedef BOOLEAN @@ -225,7 +234,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V2 { XENBUS_EVTCHN_ACQUIRE EvtchnAcquire; XENBUS_EVTCHN_RELEASE EvtchnRelease; XENBUS_EVTCHN_OPEN EvtchnOpen; - XENBUS_EVTCHN_BIND EvtchnBind; + XENBUS_EVTCHN_BIND_V2 EvtchnBindVersion2; XENBUS_EVTCHN_UNMASK_V1 EvtchnUnmaskVersion1; XENBUS_EVTCHN_SEND EvtchnSend; XENBUS_EVTCHN_TRIGGER EvtchnTrigger; @@ -242,6 +251,23 @@ struct _XENBUS_EVTCHN_INTERFACE_V3 { XENBUS_EVTCHN_ACQUIRE EvtchnAcquire; XENBUS_EVTCHN_RELEASE EvtchnRelease; XENBUS_EVTCHN_OPEN EvtchnOpen; + XENBUS_EVTCHN_BIND_V2 EvtchnBindVersion2; + XENBUS_EVTCHN_UNMASK EvtchnUnmask; + XENBUS_EVTCHN_SEND EvtchnSend; + XENBUS_EVTCHN_TRIGGER EvtchnTrigger; + XENBUS_EVTCHN_GET_PORT EvtchnGetPort; + XENBUS_EVTCHN_CLOSE EvtchnClose; +}; + +/*! \struct _XENBUS_EVTCHN_INTERFACE_V4 + \brief EVTCHN interface version 4 + \ingroup interfaces +*/ +struct _XENBUS_EVTCHN_INTERFACE_V4 { + INTERFACE Interface; + XENBUS_EVTCHN_ACQUIRE EvtchnAcquire; + XENBUS_EVTCHN_RELEASE EvtchnRelease; + XENBUS_EVTCHN_OPEN EvtchnOpen; XENBUS_EVTCHN_BIND EvtchnBind; XENBUS_EVTCHN_UNMASK EvtchnUnmask; XENBUS_EVTCHN_SEND EvtchnSend; @@ -250,7 +276,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V3 { XENBUS_EVTCHN_CLOSE EvtchnClose; }; -typedef struct _XENBUS_EVTCHN_INTERFACE_V3 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE; +typedef struct _XENBUS_EVTCHN_INTERFACE_V4 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE; /*! \def XENBUS_EVTCHN \brief Macro at assist in method invocation @@ -261,7 +287,7 @@ typedef struct _XENBUS_EVTCHN_INTERFACE_V3 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVT #endif // _WINDLL #define XENBUS_EVTCHN_INTERFACE_VERSION_MIN 1 -#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 3 +#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 4 #endif // _XENBUS_EVTCHN_INTERFACE_H diff --git a/include/shared_info_interface.h b/include/shared_info_interface.h index 0e5a0d7..287feab 100644 --- a/include/shared_info_interface.h +++ b/include/shared_info_interface.h @@ -66,7 +66,7 @@ typedef VOID typedef BOOLEAN (*XENBUS_SHARED_INFO_UPCALL_PENDING)( IN PINTERFACE Interface, - IN ULONG Cpu + IN ULONG Index ); typedef BOOLEAN @@ -81,7 +81,7 @@ typedef BOOLEAN typedef BOOLEAN (*XENBUS_SHARED_INFO_EVTCHN_POLL)( IN PINTERFACE Interface, - IN ULONG Cpu, + IN ULONG Index, IN XENBUS_SHARED_INFO_EVENT Event, IN PVOID Argument ); diff --git a/include/xen.h b/include/xen.h index 29e32f9..cf9c2d9 100644 --- a/include/xen.h +++ b/include/xen.h @@ -45,6 +45,7 @@ #include <public/grant_table.h> #include <public/sched.h> #include <public/hvm/params.h> +#include <public/hvm/hvm_info_table.h> // xs_wire.h gates the definition of the xsd_errors enumeration // on whether EINVAL is defined. Unfortunately EINVAL is actually diff --git a/src/xen/driver.c b/src/xen/driver.c index a319541..66a5e80 100644 --- a/src/xen/driver.c +++ b/src/xen/driver.c @@ -32,6 +32,7 @@ #define XEN_API __declspec(dllexport) #include <ntddk.h> +#include <procgrp.h> #include <xen.h> #include "hypercall.h" @@ -126,6 +127,7 @@ DllInitialize( UNREFERENCED_PARAMETER(RegistryPath); ExInitializeDriverRuntime(DrvRtPoolNxOptIn); + WdmlibProcgrpInitialize(); __DbgPrintEnable(); diff --git a/src/xen/system.c b/src/xen/system.c index b21efd8..a602d8b 100644 --- a/src/xen/system.c +++ b/src/xen/system.c @@ -32,6 +32,7 @@ #define XEN_API __declspec(dllexport) #include <ntddk.h> +#include <procgrp.h> #include <ntstrsafe.h> #include <stdlib.h> #include <stdarg.h> @@ -47,19 +48,19 @@ #define XEN_SYSTEM_TAG 'TSYS' -typedef struct _SYSTEM_CPU { - ULONG Index; +typedef struct _SYSTEM_PROCESSOR { CHAR Manufacturer[13]; UCHAR ApicID; UCHAR ProcessorID; -} SYSTEM_CPU, *PSYSTEM_CPU; +} SYSTEM_PROCESSOR, *PSYSTEM_PROCESSOR; typedef struct _SYSTEM_CONTEXT { - LONG References; - PACPI_MADT Madt; - PSYSTEM_CPU Cpu[MAXIMUM_PROCESSORS]; - PVOID PowerStateHandle; - PVOID ProcessorChangeHandle; + LONG References; + PACPI_MADT Madt; + PSYSTEM_PROCESSOR Processor; + ULONG ProcessorCount; + PVOID PowerStateHandle; + PVOID ProcessorChangeHandle; } SYSTEM_CONTEXT, *PSYSTEM_CONTEXT; static SYSTEM_CONTEXT SystemContext; @@ -334,51 +335,51 @@ _IRQL_requires_min_(DISPATCH_LEVEL) _IRQL_requires_(DISPATCH_LEVEL) _IRQL_requires_same_ VOID -SystemCpuInformation( - IN PKDPC Dpc, - IN PVOID _Context, - IN PVOID Argument1, - IN PVOID Argument2 +SystemProcessorInformation( + IN PKDPC Dpc, + IN PVOID _Context, + IN PVOID Argument1, + IN PVOID Argument2 ) { - PSYSTEM_CONTEXT Context = &SystemContext; - PKEVENT Event = _Context; - ULONG Index; - PSYSTEM_CPU Cpu; - ULONG EBX; - ULONG ECX; - ULONG EDX; + PSYSTEM_CONTEXT Context = &SystemContext; + PKEVENT Event = _Context; + ULONG Index; + PROCESSOR_NUMBER ProcNumber; + PSYSTEM_PROCESSOR Processor; + ULONG EBX; + ULONG ECX; + ULONG EDX; UNREFERENCED_PARAMETER(Dpc); UNREFERENCED_PARAMETER(Argument1); UNREFERENCED_PARAMETER(Argument2); - Index = KeGetCurrentProcessorNumber(); - Cpu = Context->Cpu[Index]; + Index = KeGetCurrentProcessorNumberEx(&ProcNumber); + ASSERT3U(Index, <, Context->ProcessorCount); - ASSERT(Cpu != NULL); - ASSERT3U(Cpu->Index, ==, Index); + Processor = &Context->Processor[Index]; - Info("====> (%u)\n", Index); + Info("====> (%u:%u)\n", ProcNumber.Group, ProcNumber.Number); __CpuId(0, NULL, &EBX, &ECX, &EDX); - RtlCopyMemory(&Cpu->Manufacturer[0], &EBX, sizeof (ULONG)); - RtlCopyMemory(&Cpu->Manufacturer[4], &EDX, sizeof (ULONG)); - RtlCopyMemory(&Cpu->Manufacturer[8], &ECX, sizeof (ULONG)); + RtlCopyMemory(&Processor->Manufacturer[0], &EBX, sizeof (ULONG)); + RtlCopyMemory(&Processor->Manufacturer[4], &EDX, sizeof (ULONG)); + RtlCopyMemory(&Processor->Manufacturer[8], &ECX, sizeof (ULONG)); __CpuId(1, NULL, &EBX, NULL, NULL); - Cpu->ApicID = EBX >> 24; - Cpu->ProcessorID = SystemApicIDToProcessorID(Cpu->ApicID); + Processor->ApicID = EBX >> 24; + Processor->ProcessorID = SystemApicIDToProcessorID(Processor->ApicID); - Info("Manufacturer: %s\n", Cpu->Manufacturer); - Info("APIC ID: %02X\n", Cpu->ApicID); - Info("PROCESSOR ID: %02X\n", Cpu->ProcessorID); + Info("Manufacturer: %s\n", Processor->Manufacturer); + Info("APIC ID: %02X\n", Processor->ApicID); + Info("PROCESSOR ID: %02X\n", Processor->ProcessorID); KeSetEvent(Event, IO_NO_INCREMENT, FALSE); - Info("<==== (%u)\n", Index); + Info("<==== (%u:%u)\n", ProcNumber.Group, ProcNumber.Number); } static @@ -391,42 +392,62 @@ SystemProcessorChangeCallback( ) { PSYSTEM_CONTEXT Context = &SystemContext; + PROCESSOR_NUMBER ProcNumber; ULONG Index; + NTSTATUS status; UNREFERENCED_PARAMETER(Argument); Index = Change->NtNumber; - Trace("====> (%u:%s)\n", Index, ProcessorChangeName(Change->State)); + + status = KeGetProcessorNumberFromIndex(Index, &ProcNumber); + ASSERT(NT_SUCCESS(status)); + + Trace("====> (%u:%u:%s)\n", + ProcNumber.Group, + ProcNumber.Number, + ProcessorChangeName(Change->State)); switch (Change->State) { case KeProcessorAddStartNotify: { - PSYSTEM_CPU Cpu; + PSYSTEM_PROCESSOR Processor; + ULONG ProcessorCount; + + if (Index < Context->ProcessorCount) + break; - Cpu = __SystemAllocate(sizeof (SYSTEM_CPU)); + ProcessorCount = Index + 1; + Processor = __SystemAllocate(sizeof (SYSTEM_PROCESSOR) * + ProcessorCount); - if (Cpu == NULL) { + if (Processor == NULL) { *Status = STATUS_NO_MEMORY; break; } - Cpu->Index = Index; - ASSERT3P(Context->Cpu[Index], ==, NULL); - Context->Cpu[Index] = Cpu; + if (Context->ProcessorCount != 0) { + RtlCopyMemory(Processor, + Context->Processor, + sizeof (SYSTEM_PROCESSOR) * + Context->ProcessorCount); + __SystemFree(Context->Processor); + } + + Context->Processor = Processor; + Context->ProcessorCount = ProcessorCount; break; } case KeProcessorAddCompleteNotify: { - PSYSTEM_CPU Cpu = Context->Cpu[Index]; - KEVENT Event; - KDPC Dpc; + KEVENT Event; + KDPC Dpc; - ASSERT(Cpu != NULL); - ASSERT3U(Cpu->Index, ==, Index); + ASSERT3U(Index, <, Context->ProcessorCount); KeInitializeEvent(&Event, NotificationEvent, FALSE); - KeInitializeDpc(&Dpc, SystemCpuInformation, &Event); + KeInitializeDpc(&Dpc, SystemProcessorInformation, &Event); KeSetImportanceDpc(&Dpc, HighImportance); - KeSetTargetProcessorDpc(&Dpc, (CCHAR)Index); + KeSetTargetProcessorDpcEx(&Dpc, &ProcNumber); KeInsertQueueDpc(&Dpc, NULL, NULL); @@ -437,20 +458,15 @@ SystemProcessorChangeCallback( NULL); break; } - case KeProcessorAddFailureNotify: { - PSYSTEM_CPU Cpu = Context->Cpu[Index]; - - ASSERT(Cpu != NULL); - ASSERT3U(Cpu->Index, ==, Index); - - Context->Cpu[Index] = NULL; - __SystemFree(Cpu); - + default: + ASSERT(FALSE); break; } - } - Trace("<==== (%u:%s)\n", Index, ProcessorChangeName(Change->State)); + Trace("<==== (%u:%u:%s)\n", + ProcNumber.Group, + ProcNumber.Number, + ProcessorChangeName(Change->State)); } static NTSTATUS @@ -459,16 +475,19 @@ SystemRegisterProcessorChangeCallback( ) { PSYSTEM_CONTEXT Context = &SystemContext; + PVOID Handle; NTSTATUS status; - Context->ProcessorChangeHandle = KeRegisterProcessorChangeCallback(SystemProcessorChangeCallback, - NULL, - KE_PROCESSOR_CHANGE_ADD_EXISTING); + Handle = KeRegisterProcessorChangeCallback(SystemProcessorChangeCallback, + NULL, + KE_PROCESSOR_CHANGE_ADD_EXISTING); status = STATUS_UNSUCCESSFUL; - if (Context->ProcessorChangeHandle == NULL) + if (Handle == NULL) goto fail1; + Context->ProcessorChangeHandle = Handle; + return STATUS_SUCCESS; fail1: @@ -483,22 +502,12 @@ SystemDeregisterProcessorChangeCallback( ) { PSYSTEM_CONTEXT Context = &SystemContext; - ULONG Index; KeDeregisterProcessorChangeCallback(Context->ProcessorChangeHandle); Context->ProcessorChangeHandle = NULL; - for (Index = 0; Index < MAXIMUM_PROCESSORS; Index++) { - PSYSTEM_CPU Cpu = Context->Cpu[Index]; - - if (Cpu == NULL) - continue; - - Context->Cpu[Index] = NULL; - __SystemFree(Cpu); - } - - ASSERT(IsZeroMemory(Context->Cpu, sizeof (SYSTEM_CPU) * MAXIMUM_PROCESSORS)); + __SystemFree(Context->Processor); + Context->ProcessorCount = 0; } static NTSTATUS @@ -732,11 +741,11 @@ SystemVirtualCpuIndex( ) { PSYSTEM_CONTEXT Context = &SystemContext; - PSYSTEM_CPU Cpu = Context->Cpu[Index]; + PSYSTEM_PROCESSOR Processor = &Context->Processor[Index]; - ASSERT(Cpu != NULL); + ASSERT3U(Index, <, Context->ProcessorCount); - return Cpu->ProcessorID; + return Processor->ProcessorID; } VOID diff --git a/src/xenbus.inf b/src/xenbus.inf index 5377fd0..90dcf64 100644 --- a/src/xenbus.inf +++ b/src/xenbus.inf @@ -96,6 +96,7 @@ HKR,"Interfaces",,0x00000010 HKR,"Interrupt Management",,0x00000010 HKR,"Interrupt Management\MessageSignaledInterruptProperties",,0x00000010 HKR,"Interrupt Management\MessageSignaledInterruptProperties","MSISupported",0x00010001,1 +HKR,"Interrupt Management\GroupPolicy",0x00010001,1 [XenFilt_Service] DisplayName=%XenFiltDesc% diff --git a/src/xenbus/cache.c b/src/xenbus/cache.c index 3620f88..ba7dcdf 100644 --- a/src/xenbus/cache.c +++ b/src/xenbus/cache.c @@ -30,6 +30,7 @@ */ #include <ntddk.h> +#include <procgrp.h> #include <ntstrsafe.h> #include <stdlib.h> @@ -79,8 +80,9 @@ struct _XENBUS_CACHE { PVOID Argument; LIST_ENTRY GetList; PLIST_ENTRY PutList; - LONG Count; - XENBUS_CACHE_MAGAZINE Magazine[MAXIMUM_PROCESSORS]; + LONG ObjectCount; + PXENBUS_CACHE_MAGAZINE Magazine; + ULONG MagazineCount; XENBUS_CACHE_FIST FIST; }; @@ -223,7 +225,7 @@ CacheGetObjectFromList( KIRQL Irql = PASSIVE_LEVEL; NTSTATUS status; - Count = InterlockedDecrement(&Cache->Count); + Count = InterlockedDecrement(&Cache->ObjectCount); status = STATUS_NO_MEMORY; if (Count < 0) @@ -253,7 +255,7 @@ CacheGetObjectFromList( return Object; fail1: - (VOID) InterlockedIncrement(&Cache->Count); + (VOID) InterlockedIncrement(&Cache->ObjectCount); return NULL; } @@ -292,19 +294,18 @@ CachePutObjectToList( KeMemoryBarrier(); - (VOID) InterlockedIncrement(&Cache->Count); + (VOID) InterlockedIncrement(&Cache->ObjectCount); } static PVOID CacheGetObjectFromMagazine( IN PXENBUS_CACHE Cache, - IN ULONG Cpu + IN ULONG Index ) { PXENBUS_CACHE_MAGAZINE Magazine; - ULONG Index; - Magazine = &Cache->Magazine[Cpu]; + Magazine = &Cache->Magazine[Index]; for (Index = 0; Index < XENBUS_CACHE_MAGAZINE_SLOTS; Index++) { PVOID Object; @@ -323,14 +324,13 @@ CacheGetObjectFromMagazine( static BOOLEAN CachePutObjectToMagazine( IN PXENBUS_CACHE Cache, - IN ULONG Cpu, + IN ULONG Index, IN PVOID Object ) { PXENBUS_CACHE_MAGAZINE Magazine; - ULONG Index; - Magazine = &Cache->Magazine[Cpu]; + Magazine = &Cache->Magazine[Index]; for (Index = 0; Index < XENBUS_CACHE_MAGAZINE_SLOTS; Index++) { if (Magazine->Slot[Index] == NULL) { @@ -350,7 +350,7 @@ CacheGet( ) { KIRQL Irql; - ULONG Cpu; + ULONG Index; PVOID Object; UNREFERENCED_PARAMETER(Interface); @@ -370,9 +370,9 @@ CacheGet( } KeRaiseIrql(DISPATCH_LEVEL, &Irql); - Cpu = KeGetCurrentProcessorNumber(); + Index = KeGetCurrentProcessorNumberEx(NULL); - Object = CacheGetObjectFromMagazine(Cache, Cpu); + Object = CacheGetObjectFromMagazine(Cache, Index); if (Object != NULL) goto done; @@ -397,14 +397,14 @@ CachePut( ) { KIRQL Irql; - ULONG Cpu; + ULONG Index; UNREFERENCED_PARAMETER(Interface); KeRaiseIrql(DISPATCH_LEVEL, &Irql); - Cpu = KeGetCurrentProcessorNumber(); + Index = KeGetCurrentProcessorNumberEx(NULL); - if (CachePutObjectToMagazine(Cache, Cpu, Object)) + if (CachePutObjectToMagazine(Cache, Index, Object)) goto done; CachePutObjectToList(Cache, Object, Locked); @@ -418,12 +418,12 @@ CacheFlushMagazines( IN PXENBUS_CACHE Cache ) { - ULONG Cpu; + ULONG Index; - for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) { + for (Index = 0; Index < Cache->MagazineCount; Index++) { PVOID Object; - while ((Object = CacheGetObjectFromMagazine(Cache, Cpu)) != NULL) + while ((Object = CacheGetObjectFromMagazine(Cache, Index)) != NULL) CachePutObjectToList(Cache, Object, TRUE); } } @@ -609,6 +609,13 @@ CacheCreate( if (!NT_SUCCESS(status)) goto fail4; + (*Cache)->MagazineCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); + (*Cache)->Magazine = __CacheAllocate(sizeof (XENBUS_CACHE_MAGAZINE) * (*Cache)->MagazineCount); + + status = STATUS_NO_MEMORY; + if ((*Cache)->Magazine == NULL) + goto fail5; + (*Cache)->Reservation = Reservation; KeAcquireSpinLock(&Context->Lock, &Irql); @@ -619,6 +626,11 @@ CacheCreate( return STATUS_SUCCESS; +fail5: + Error("fail5\n"); + + (*Cache)->MagazineCount = 0; + fail4: Error("fail4\n"); @@ -669,9 +681,14 @@ CacheDestroy( Cache->Reservation = 0; CacheFlushMagazines(Cache); - CacheSpill(Cache, Cache->Count); + CacheSpill(Cache, Cache->ObjectCount); + + ASSERT3U(Cache->ObjectCount, ==, 0); - ASSERT3U(Cache->Count, ==, 0); + ASSERT(IsZeroMemory(Cache->Magazine, sizeof (XENBUS_CACHE_MAGAZINE) * Cache->MagazineCount)); + __CacheFree(Cache->Magazine); + Cache->Magazine = NULL; + Cache->MagazineCount = 0; RtlZeroMemory(&Cache->GetList, sizeof (LIST_ENTRY)); @@ -720,7 +737,7 @@ CacheDebugCallback( &Context->DebugInterface, "- %s: Count = %d (Reservation = %d)\n", Cache->Name, - Cache->Count, + Cache->ObjectCount, Cache->Reservation); } } @@ -776,7 +793,7 @@ CacheMonitor( Cache = CONTAINING_RECORD(ListEntry, XENBUS_CACHE, ListEntry); - Count = Cache->Count; + Count = Cache->ObjectCount; if (Count < Cache->Reservation) CacheFill(Cache, Cache->Reservation - Count); diff --git a/src/xenbus/driver.c b/src/xenbus/driver.c index e74d369..a1115a4 100644 --- a/src/xenbus/driver.c +++ b/src/xenbus/driver.c @@ -30,6 +30,7 @@ */ #include <ntddk.h> +#include <procgrp.h> #include <ntstrsafe.h> #include "registry.h" @@ -500,6 +501,7 @@ DriverEntry( ASSERT3P(__DriverGetDriverObject(), ==, NULL); ExInitializeDriverRuntime(DrvRtPoolNxOptIn); + WdmlibProcgrpInitialize(); __DbgPrintEnable(); diff --git a/src/xenbus/evtchn.c b/src/xenbus/evtchn.c index f44c3cf..889179c 100644 --- a/src/xenbus/evtchn.c +++ b/src/xenbus/evtchn.c @@ -30,6 +30,7 @@ */ #include <ntddk.h> +#include <procgrp.h> #include <stdarg.h> #include <xen.h> @@ -84,17 +85,24 @@ struct _XENBUS_EVTCHN_CHANNEL { XENBUS_EVTCHN_PARAMETERS Parameters; BOOLEAN Mask; ULONG LocalPort; - ULONG Cpu; + PROCESSOR_NUMBER ProcNumber; BOOLEAN Closed; }; +typedef struct _XENBUS_EVTCHN_PROCESSOR { + PXENBUS_INTERRUPT Interrupt; + LIST_ENTRY PendingList; + KDPC Dpc; + BOOLEAN UpcallEnabled; +} XENBUS_EVTCHN_PROCESSOR, *PXENBUS_EVTCHN_PROCESSOR; + struct _XENBUS_EVTCHN_CONTEXT { PXENBUS_FDO Fdo; KSPIN_LOCK Lock; LONG References; - PXENBUS_INTERRUPT LevelSensitiveInterrupt; - PXENBUS_INTERRUPT LatchedInterrupt[MAXIMUM_PROCESSORS]; - KAFFINITY Affinity; + PXENBUS_INTERRUPT Interrupt; + PXENBUS_EVTCHN_PROCESSOR Processor; + ULONG ProcessorCount; XENBUS_SUSPEND_INTERFACE SuspendInterface; PXENBUS_SUSPEND_CALLBACK SuspendCallbackEarly; PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate; @@ -107,8 +115,6 @@ struct _XENBUS_EVTCHN_CONTEXT { BOOLEAN UseEvtchnFifoAbi; PXENBUS_HASH_TABLE Table; LIST_ENTRY List; - LIST_ENTRY PendingList[MAXIMUM_PROCESSORS]; - KDPC Dpc[MAXIMUM_PROCESSORS]; }; #define XENBUS_EVTCHN_TAG 'CTVE' @@ -402,7 +408,7 @@ EvtchnReap( RemoveEntryList(&Channel->ListEntry); RtlZeroMemory(&Channel->ListEntry, sizeof (LIST_ENTRY)); - Channel->Cpu = 0; + RtlZeroMemory(&Channel->ProcNumber, sizeof (PROCESSOR_NUMBER)); ASSERT(IsListEmpty(&Channel->PendingListEntry)); RtlZeroMemory(&Channel->PendingListEntry, sizeof (LIST_ENTRY)); @@ -428,18 +434,22 @@ EvtchnReap( static BOOLEAN EvtchnPollCallback( - IN PVOID Argument, - IN ULONG LocalPort + IN PVOID Argument, + IN ULONG LocalPort ) { - PXENBUS_EVTCHN_CONTEXT Context = Argument; - ULONG Cpu; - PXENBUS_EVTCHN_CHANNEL Channel; - BOOLEAN Pending; - NTSTATUS status; + PXENBUS_EVTCHN_CONTEXT Context = Argument; + ULONG Index; + PXENBUS_EVTCHN_PROCESSOR Processor; + PXENBUS_EVTCHN_CHANNEL Channel; + BOOLEAN Pending; + NTSTATUS status; ASSERT3U(KeGetCurrentIrql(), >=, DISPATCH_LEVEL); - Cpu = KeGetCurrentProcessorNumber(); + Index = KeGetCurrentProcessorNumberEx(NULL); + + ASSERT3U(Index, <, Context->ProcessorCount); + Processor = &Context->Processor[Index]; status = HashTableLookup(Context->Table, LocalPort, @@ -452,7 +462,7 @@ EvtchnPollCallback( Pending = !IsListEmpty(&Channel->PendingListEntry); if (!Pending) - InsertTailList(&Context->PendingList[Cpu], + InsertTailList(&Processor->PendingList, &Channel->PendingListEntry); done: @@ -462,23 +472,27 @@ done: static BOOLEAN EvtchnPoll( IN PXENBUS_EVTCHN_CONTEXT Context, - IN ULONG Cpu, + IN ULONG Index, IN PLIST_ENTRY List ) { + PXENBUS_EVTCHN_PROCESSOR Processor; BOOLEAN DoneSomething; PLIST_ENTRY ListEntry; + ASSERT3U(Index, <, Context->ProcessorCount); + Processor = &Context->Processor[Index]; + (VOID) XENBUS_EVTCHN_ABI(Poll, &Context->EvtchnAbi, - Cpu, + Index, EvtchnPollCallback, Context); DoneSomething = FALSE; - ListEntry = Context->PendingList[Cpu].Flink; - while (ListEntry != &Context->PendingList[Cpu]) { + ListEntry = Processor->PendingList.Flink; + while (ListEntry != &Processor->PendingList) { PLIST_ENTRY Next = ListEntry->Flink; PXENBUS_EVTCHN_CHANNEL Channel; @@ -518,23 +532,25 @@ EvtchnPoll( static VOID EvtchnFlush( IN PXENBUS_EVTCHN_CONTEXT Context, - IN ULONG Cpu + IN ULONG Index ) { + PXENBUS_EVTCHN_PROCESSOR Processor; LIST_ENTRY List; PXENBUS_INTERRUPT Interrupt; KIRQL Irql; - Interrupt = (Context->Affinity != 0) ? // Latched available - Context->LatchedInterrupt[Cpu] : - Context->LevelSensitiveInterrupt; + ASSERT3U(Index, <, Context->ProcessorCount); + Processor = &Context->Processor[Index]; + + Interrupt = (Processor->UpcallEnabled) ? + Processor->Interrupt : + Context->Interrupt; InitializeListHead(&List); Irql = FdoAcquireInterruptLock(Context->Fdo, Interrupt); - - (VOID) EvtchnPoll(Context, Cpu, &List); - + (VOID) EvtchnPoll(Context, Index, &List); FdoReleaseInterruptLock(Context->Fdo, Interrupt, Irql); while (!IsListEmpty(&List)) { @@ -571,21 +587,21 @@ EvtchnDpc( ) { PXENBUS_EVTCHN_CONTEXT Context = _Context; - ULONG Cpu; + ULONG Index; UNREFERENCED_PARAMETER(Dpc); UNREFERENCED_PARAMETER(Argument1); UNREFERENCED_PARAMETER(Argument2); ASSERT3U(KeGetCurrentIrql(), >=, DISPATCH_LEVEL); - Cpu = KeGetCurrentProcessorNumber(); + Index = KeGetCurrentProcessorNumberEx(NULL); KeAcquireSpinLockAtDpcLevel(&Context->Lock); if (Context->References == 0) goto done; - EvtchnFlush(Context, Cpu); + EvtchnFlush(Context, Index); done: KeReleaseSpinLockFromDpcLevel(&Context->Lock); @@ -598,28 +614,34 @@ EvtchnTrigger( ) { PXENBUS_EVTCHN_CONTEXT Context = Interface->Context; - PKDPC Dpc; KIRQL Irql; - ULONG Cpu; + PROCESSOR_NUMBER ProcNumber; + ULONG Index; + PXENBUS_EVTCHN_PROCESSOR Processor; PXENBUS_INTERRUPT Interrupt; BOOLEAN Pending; ASSERT3U(Channel->Magic, ==, XENBUS_EVTCHN_CHANNEL_MAGIC); KeAcquireSpinLock(&Channel->Lock, &Irql); - Cpu = Channel->Cpu; + ProcNumber = Channel->ProcNumber; KeReleaseSpinLock(&Channel->Lock, Irql); - Interrupt = (Context->Affinity != 0) ? // Latched available - Context->LatchedInterrupt[Cpu] : - Context->LevelSensitiveInterrupt; + Index = KeGetProcessorIndexFromNumber(&ProcNumber); + + ASSERT3U(Index, <, Context->ProcessorCount); + Processor = &Context->Processor[Index]; + + Interrupt = (Processor->UpcallEnabled) ? + Processor->Interrupt : + Context->Interrupt; Irql = FdoAcquireInterruptLock(Context->Fdo, Interrupt); Pending = !IsListEmpty(&Channel->PendingListEntry); if (!Pending) - InsertTailList(&Context->PendingList[Cpu], + InsertTailList(&Processor->PendingList, &Channel->PendingListEntry); FdoReleaseInterruptLock(Context->Fdo, Interrupt, Irql); @@ -627,18 +649,21 @@ EvtchnTrigger( if (Pending) return; - Dpc = &Context->Dpc[Cpu]; - KeInsertQueueDpc(Dpc, NULL, NULL); + KeInsertQueueDpc(&Processor->Dpc, NULL, NULL); } static NTSTATUS EvtchnBind( IN PINTERFACE Interface, IN PXENBUS_EVTCHN_CHANNEL Channel, - IN ULONG Cpu + IN USHORT Group, + IN UCHAR Number ) { PXENBUS_EVTCHN_CONTEXT Context = Interface->Context; + PROCESSOR_NUMBER ProcNumber; + ULONG Index; + PXENBUS_EVTCHN_PROCESSOR Processor; ULONG LocalPort; unsigned int vcpu_id; KIRQL Irql; @@ -646,8 +671,16 @@ EvtchnBind( ASSERT3U(Channel->Magic, ==, XENBUS_EVTCHN_CHANNEL_MAGIC); + ProcNumber.Group = Group; + ProcNumber.Number = Number; + + Index = KeGetProcessorIndexFromNumber(&ProcNumber); + + ASSERT3U(Index, <, Context->ProcessorCount); + Processor = &Context->Processor[Index]; + status = STATUS_NOT_SUPPORTED; - if (~Context->Affinity & ((KAFFINITY)1 << Cpu)) + if (!Processor->UpcallEnabled) goto fail1; KeAcquireSpinLock(&Channel->Lock, &Irql); @@ -655,19 +688,20 @@ EvtchnBind( if (!Channel->Active) goto done; - if (Channel->Cpu == Cpu) + if (Channel->ProcNumber.Group == Group && + Channel->ProcNumber.Number == Number) goto done; LocalPort = Channel->LocalPort; - vcpu_id = SystemVirtualCpuIndex(Cpu); + vcpu_id = SystemVirtualCpuIndex(Index); status = EventChannelBindVirtualCpu(LocalPort, vcpu_id); if (!NT_SUCCESS(status)) goto fail2; - Channel->Cpu = Cpu; + Channel->ProcNumber = ProcNumber; - Info("[%u]: CPU %u\n", LocalPort, Cpu); + Info("[%u]: CPU %u:%u\n", LocalPort, Group, Number); done: KeReleaseSpinLock(&Channel->Lock, Irql); @@ -685,6 +719,18 @@ fail1: return status; } +static NTSTATUS +EvtchnBindVersion2( + IN PINTERFACE Interface, + IN PXENBUS_EVTCHN_CHANNEL Channel, + IN ULONG Cpu + ) +{ + ASSERT3U(Cpu, <, MAXIMUM_PROCESSORS); + + return EvtchnBind(Interface, Channel, 0, (CHAR)Cpu); +} + static VOID EvtchnUnmask( IN PINTERFACE Interface, @@ -842,27 +888,26 @@ EvtchnInterruptCallback( ) { PXENBUS_EVTCHN_CONTEXT Context = Argument; - ULONG Cpu; + ULONG Index; BOOLEAN DoneSomething; UNREFERENCED_PARAMETER(InterruptObject); ASSERT3U(KeGetCurrentIrql(), >=, DISPATCH_LEVEL); - Cpu = KeGetCurrentProcessorNumber(); + Index = KeGetCurrentProcessorNumberEx(NULL); DoneSomething = FALSE; while (XENBUS_SHARED_INFO(UpcallPending, &Context->SharedInfoInterface, - Cpu)) - DoneSomething |= EvtchnPoll(Context, Cpu, NULL); + Index)) + DoneSomething |= EvtchnPoll(Context, Index, NULL); return DoneSomething; } static NTSTATUS EvtchnAbiAcquire( - IN PXENBUS_EVTCHN_CONTEXT Context, - OUT PKAFFINITY Affinity + IN PXENBUS_EVTCHN_CONTEXT Context ) { NTSTATUS status; @@ -872,8 +917,7 @@ EvtchnAbiAcquire( &Context->EvtchnAbi); status = XENBUS_EVTCHN_ABI(Acquire, - &Context->EvtchnAbi, - Affinity); + &Context->EvtchnAbi); if (!NT_SUCCESS(status)) goto use_two_level; @@ -886,8 +930,7 @@ use_two_level: &Context->EvtchnAbi); status = XENBUS_EVTCHN_ABI(Acquire, - &Context->EvtchnAbi, - Affinity); + &Context->EvtchnAbi); if (!NT_SUCCESS(status)) goto fail1; @@ -917,32 +960,38 @@ EvtchnInterruptEnable( IN PXENBUS_EVTCHN_CONTEXT Context ) { - LONG Cpu; + ULONG Index; ULONG Line; NTSTATUS status; Trace("====>\n"); - for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) { - unsigned int vcpu_id; - UCHAR Vector; + for (Index = 0; Index < Context->ProcessorCount; Index++) { + PXENBUS_EVTCHN_PROCESSOR Processor; + unsigned int vcpu_id; + UCHAR Vector; + + Processor = &Context->Processor[Index]; - if (Context->LatchedInterrupt[Cpu] == NULL) + if (Processor->Interrupt == NULL) continue; - vcpu_id = SystemVirtualCpuIndex(Cpu); - Vector = FdoGetInterruptVector(Context->Fdo, - Context->LatchedInterrupt[Cpu]); + vcpu_id = SystemVirtualCpuIndex(Index); + Vector = FdoGetInterruptVector(Context->Fdo, Processor->Interrupt); status = HvmSetEvtchnUpcallVector(vcpu_id, Vector); if (NT_SUCCESS(status)) { - Info("CPU %u\n", Cpu); - Context->Affinity |= (KAFFINITY)1 << Cpu; + PROCESSOR_NUMBER ProcNumber; + + status = KeGetProcessorNumberFromIndex(Index, &ProcNumber); + ASSERT(NT_SUCCESS(status)); + + Info("CPU %u:%u\n", ProcNumber.Group, ProcNumber.Number); + Processor->UpcallEnabled = TRUE; } } - Line = FdoGetInterruptLine(Context->Fdo, - Context->LevelSensitiveInterrupt); + Line = FdoGetInterruptLine(Context->Fdo, Context->Interrupt); status = HvmSetParam(HVM_PARAM_CALLBACK_IRQ, Line); ASSERT(NT_SUCCESS(status)); @@ -955,7 +1004,7 @@ EvtchnInterruptDisable( IN PXENBUS_EVTCHN_CONTEXT Context ) { - ULONG Cpu; + ULONG Index; NTSTATUS status; UNREFERENCED_PARAMETER(Context); @@ -965,20 +1014,21 @@ EvtchnInterruptDisable( status = HvmSetParam(HVM_PARAM_CALLBACK_IRQ, 0); ASSERT(NT_SUCCESS(status)); - for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) { - unsigned int vcpu_id; + for (Index = 0; Index < Context->ProcessorCount; Index++) { + PXENBUS_EVTCHN_PROCESSOR Processor; + unsigned int vcpu_id; + + Processor = &Context->Processor[Index]; - if (~Context->Affinity & (KAFFINITY)1 << Cpu) + if (!Processor->UpcallEnabled) continue; - vcpu_id = SystemVirtualCpuIndex(Cpu); + vcpu_id = SystemVirtualCpuIndex(Index); (VOID) HvmSetEvtchnUpcallVector(vcpu_id, 0); - Context->Affinity &= ~((KAFFINITY)1 << Cpu); + Processor->UpcallEnabled = FALSE; } - ASSERT3U(Context->Affinity, ==, 0); - Trace("<====\n"); } @@ -1019,17 +1069,13 @@ EvtchnSuspendCallbackLate( ) { PXENBUS_EVTCHN_CONTEXT Context = Argument; - KAFFINITY Affinity; NTSTATUS status; EvtchnAbiRelease(Context); - status = EvtchnAbiAcquire(Context, &Affinity); + status = EvtchnAbiAcquire(Context); ASSERT(NT_SUCCESS(status)); - // Affinity must be a superset of Context->Affinity - ASSERT3U(Affinity & Context->Affinity, ==, Context->Affinity); - EvtchnInterruptDisable(Context); EvtchnInterruptEnable(Context); } @@ -1127,8 +1173,8 @@ EvtchnAcquire( PXENBUS_EVTCHN_CONTEXT Context = Interface->Context; PXENBUS_FDO Fdo = Context->Fdo; KIRQL Irql; - ULONG Cpu; - KAFFINITY Affinity; + PROCESSOR_NUMBER ProcNumber; + ULONG Index; NTSTATUS status; KeAcquireSpinLock(&Context->Lock, &Irql); @@ -1177,29 +1223,56 @@ EvtchnAcquire( if (!NT_SUCCESS(status)) goto fail6; - status = EvtchnAbiAcquire(Context, &Affinity); + status = EvtchnAbiAcquire(Context); if (!NT_SUCCESS(status)) goto fail7; - Context->LevelSensitiveInterrupt = FdoAllocateInterrupt(Fdo, - LevelSensitive, - 0, - EvtchnInterruptCallback, - Context); + status = KeGetProcessorNumberFromIndex(0, &ProcNumber); + ASSERT(NT_SUCCESS(status)); + + Context->Interrupt = FdoAllocateInterrupt(Fdo, + LevelSensitive, + ProcNumber.Group, + ProcNumber.Number, + EvtchnInterruptCallback, + Context); status = STATUS_UNSUCCESSFUL; - if (Context->LevelSensitiveInterrupt == NULL) + if (Context->Interrupt == NULL) goto fail8; - for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) { - if (~Affinity & (KAFFINITY)1 << Cpu) + Context->ProcessorCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); + Context->Processor = __EvtchnAllocate(sizeof (XENBUS_EVTCHN_PROCESSOR) * Context->ProcessorCount); + + status = STATUS_NO_MEMORY; + if (Context->Processor == NULL) + goto fail9; + + for (Index = 0; Index < Context->ProcessorCount; Index++) { + PXENBUS_EVTCHN_PROCESSOR Processor; + + if (!XENBUS_EVTCHN_ABI(IsProcessorEnabled, + &Context->EvtchnAbi, + Index)) continue; - Context->LatchedInterrupt[Cpu] = FdoAllocateInterrupt(Fdo, - Latched, - Cpu, - EvtchnInterruptCallback, - Context); + status = KeGetProcessorNumberFromIndex(Index, &ProcNumber); + ASSERT(NT_SUCCESS(status)); + + Processor = &Context->Processor[Index]; + + Processor->Interrupt = FdoAllocateInterrupt(Fdo, + Latched, + ProcNumber.Group, + ProcNumber.Number, + EvtchnInterruptCallback, + Context); + ASSERT(Processor->Interrupt != NULL); + + InitializeListHead(&Processor->PendingList); + + KeInitializeDpc(&Processor->Dpc, EvtchnDpc, Context); + KeSetTargetProcessorDpcEx(&Processor->Dpc, &ProcNumber); } EvtchnInterruptEnable(Context); @@ -1211,6 +1284,11 @@ done: return STATUS_SUCCESS; +fail9: + Error("fail9\n"); + + Context->ProcessorCount = 0; + fail8: Error("fail8\n"); @@ -1273,7 +1351,7 @@ EvtchnRelease( PXENBUS_EVTCHN_CONTEXT Context = Interface->Context; PXENBUS_FDO Fdo = Context->Fdo; KIRQL Irql; - ULONG Cpu; + ULONG Index; KeAcquireSpinLock(&Context->Lock, &Irql); @@ -1284,18 +1362,30 @@ EvtchnRelease( EvtchnInterruptDisable(Context); - for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) { - if (Context->LatchedInterrupt[Cpu] == NULL) + for (Index = 0; Index < Context->ProcessorCount; Index++) { + PXENBUS_EVTCHN_PROCESSOR Processor; + + ASSERT(Context->Processor != NULL); + Processor = &Context->Processor[Index]; + + if (Processor->Interrupt == NULL) continue; - EvtchnFlush(Context, Cpu); + EvtchnFlush(Context, Index); + + RtlZeroMemory(&Processor->Dpc, sizeof (KDPC)); + RtlZeroMemory(&Processor->PendingList, sizeof (LIST_ENTRY)); - FdoFreeInterrupt(Fdo, Context->LatchedInterrupt[Cpu]); - Context->LatchedInterrupt[Cpu] = NULL; + FdoFreeInterrupt(Fdo, Processor->Interrupt); + Processor->Interrupt = NULL; } - FdoFreeInterrupt(Fdo, Context->LevelSensitiveInterrupt); - Context->LevelSensitiveInterrupt = NULL; + ASSERT(IsZeroMemory(Context->Processor, sizeof (XENBUS_EVTCHN_PROCESSOR) * Context->ProcessorCount)); + __EvtchnFree(Context->Processor); + Context->ProcessorCount = 0; + + FdoFreeInterrupt(Fdo, Context->Interrupt); + Context->Interrupt = NULL; if (!IsListEmpty(&Context->List)) BUG("OUTSTANDING EVENT CHANNELS"); @@ -1346,7 +1436,7 @@ static struct _XENBUS_EVTCHN_INTERFACE_V2 EvtchnInterfaceVersion2 = { EvtchnAcquire, EvtchnRelease, EvtchnOpen, - EvtchnBind, + EvtchnBindVersion2, EvtchnUnmaskVersion1, EvtchnSend, EvtchnTrigger, @@ -1359,6 +1449,19 @@ static struct _XENBUS_EVTCHN_INTERFACE_V3 EvtchnInterfaceVersion3 = { EvtchnAcquire, EvtchnRelease, EvtchnOpen, + EvtchnBindVersion2, + EvtchnUnmask, + EvtchnSend, + EvtchnTrigger, + EvtchnGetPort, + EvtchnClose +}; + +static struct _XENBUS_EVTCHN_INTERFACE_V4 EvtchnInterfaceVersion4 = { + { sizeof (struct _XENBUS_EVTCHN_INTERFACE_V4), 4, NULL, NULL, NULL }, + EvtchnAcquire, + EvtchnRelease, + EvtchnOpen, EvtchnBind, EvtchnUnmask, EvtchnSend, @@ -1375,7 +1478,6 @@ EvtchnInitialize( { HANDLE ParametersKey; ULONG UseEvtchnFifoAbi; - ULONG Cpu; NTSTATUS status; Trace("====>\n"); @@ -1433,15 +1535,6 @@ EvtchnInitialize( InitializeListHead(&(*Context)->List); KeInitializeSpinLock(&(*Context)->Lock); - for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) { - PKDPC Dpc = &(*Context)->Dpc[Cpu]; - - InitializeListHead(&(*Context)->PendingList[Cpu]); - - KeInitializeDpc(Dpc, EvtchnDpc, *Context); - KeSetTargetProcessorDpc(Dpc, (CCHAR)Cpu); - } - (*Context)->Fdo = Fdo; Trace("<====\n"); @@ -1536,6 +1629,23 @@ EvtchnGetInterface( status = STATUS_SUCCESS; break; } + case 4: { + struct _XENBUS_EVTCHN_INTERFACE_V4 *EvtchnInterface; + + EvtchnInterface = (struct _XENBUS_EVTCHN_INTERFACE_V4 *)Interface; + + status = STATUS_BUFFER_OVERFLOW; + if (Size < sizeof (struct _XENBUS_EVTCHN_INTERFACE_V4)) + break; + + *EvtchnInterface = EvtchnInterfaceVersion4; + + ASSERT3U(Interface->Version, ==, Version); + Interface->Context = Context; + + status = STATUS_SUCCESS; + break; + } default: status = STATUS_NOT_SUPPORTED; break; @@ -1556,10 +1666,8 @@ EvtchnTeardown( Context->Fdo = NULL; - RtlZeroMemory(&Context->Dpc, sizeof (KDPC) * MAXIMUM_PROCESSORS); RtlZeroMemory(&Context->Lock, sizeof (KSPIN_LOCK)); RtlZeroMemory(&Context->List, sizeof (LIST_ENTRY)); - RtlZeroMemory(&Context->PendingList, sizeof (LIST_ENTRY) * MAXIMUM_PROCESSORS); RtlZeroMemory(&Context->SharedInfoInterface, sizeof (XENBUS_SHARED_INFO_INTERFACE)); diff --git a/src/xenbus/evtchn_2l.c b/src/xenbus/evtchn_2l.c index fde520f..249543d 100644 --- a/src/xenbus/evtchn_2l.c +++ b/src/xenbus/evtchn_2l.c @@ -66,9 +66,20 @@ __EvtchnTwoLevelFree( } static BOOLEAN +EvtchnTwoLevelIsProcessorEnabled( + IN PXENBUS_EVTCHN_ABI_CONTEXT _Context, + IN ULONG Index + ) +{ + UNREFERENCED_PARAMETER(_Context); + + return (SystemVirtualCpuIndex(Index) == 0) ? TRUE : FALSE; +} + +static BOOLEAN EvtchnTwoLevelPoll( IN PXENBUS_EVTCHN_ABI_CONTEXT _Context, - IN ULONG Cpu, + IN ULONG Index, IN XENBUS_EVTCHN_ABI_EVENT Event, IN PVOID Argument ) @@ -77,7 +88,7 @@ EvtchnTwoLevelPoll( return XENBUS_SHARED_INFO(EvtchnPoll, &Context->SharedInfoInterface, - Cpu, + Index, Event, Argument); } @@ -148,8 +159,7 @@ EvtchnTwoLevelPortUnmask( static NTSTATUS EvtchnTwoLevelAcquire( - IN PXENBUS_EVTCHN_ABI_CONTEXT _Context, - OUT PKAFFINITY Affinity + IN PXENBUS_EVTCHN_ABI_CONTEXT _Context ) { PXENBUS_EVTCHN_TWO_LEVEL_CONTEXT Context = (PVOID)_Context; @@ -167,8 +177,6 @@ EvtchnTwoLevelAcquire( if (!NT_SUCCESS(status)) goto fail1; - *Affinity = (KAFFINITY)1; - Trace("<====\n"); done: @@ -215,6 +223,7 @@ static XENBUS_EVTCHN_ABI EvtchnAbiTwoLevel = { NULL, EvtchnTwoLevelAcquire, EvtchnTwoLevelRelease, + EvtchnTwoLevelIsProcessorEnabled, EvtchnTwoLevelPoll, EvtchnTwoLevelPortEnable, EvtchnTwoLevelPortDisable, diff --git a/src/xenbus/evtchn_abi.h b/src/xenbus/evtchn_abi.h index 2e1bf43..404f85a 100644 --- a/src/xenbus/evtchn_abi.h +++ b/src/xenbus/evtchn_abi.h @@ -39,8 +39,7 @@ typedef PVOID *PXENBUS_EVTCHN_ABI_CONTEXT; typedef NTSTATUS (*XENBUS_EVTCHN_ABI_ACQUIRE)( - IN PXENBUS_EVTCHN_ABI_CONTEXT Context, - OUT PKAFFINITY Affinity + IN PXENBUS_EVTCHN_ABI_CONTEXT Context ); typedef VOID @@ -49,6 +48,12 @@ typedef VOID ); typedef BOOLEAN +(*XENBUS_EVTCHN_ABI_IS_PROCESSOR_ENABLED)( + IN PXENBUS_EVTCHN_ABI_CONTEXT Context, + IN ULONG Index + ); + +typedef BOOLEAN (*XENBUS_EVTCHN_ABI_EVENT)( IN PVOID Argument, IN ULONG Port @@ -57,7 +62,7 @@ typedef BOOLEAN typedef BOOLEAN (*XENBUS_EVTCHN_ABI_POLL)( IN PXENBUS_EVTCHN_ABI_CONTEXT Context, - IN ULONG Cpu, + IN ULONG Index, IN XENBUS_EVTCHN_ABI_EVENT Event, IN PVOID Argument ); @@ -93,15 +98,16 @@ typedef BOOLEAN ); typedef struct _XENBUS_EVTCHN_ABI { - PXENBUS_EVTCHN_ABI_CONTEXT Context; - XENBUS_EVTCHN_ABI_ACQUIRE EvtchnAbiAcquire; - XENBUS_EVTCHN_ABI_RELEASE EvtchnAbiRelease; - XENBUS_EVTCHN_ABI_POLL EvtchnAbiPoll; - XENBUS_EVTCHN_ABI_PORT_ENABLE EvtchnAbiPortEnable; - XENBUS_EVTCHN_ABI_PORT_DISABLE EvtchnAbiPortDisable; - XENBUS_EVTCHN_ABI_PORT_ACK EvtchnAbiPortAck; - XENBUS_EVTCHN_ABI_PORT_MASK EvtchnAbiPortMask; - XENBUS_EVTCHN_ABI_PORT_UNMASK EvtchnAbiPortUnmask; + PXENBUS_EVTCHN_ABI_CONTEXT Context; + XENBUS_EVTCHN_ABI_ACQUIRE EvtchnAbiAcquire; + XENBUS_EVTCHN_ABI_RELEASE EvtchnAbiRelease; + XENBUS_EVTCHN_ABI_IS_PROCESSOR_ENABLED EvtchnAbiIsProcessorEnabled; + XENBUS_EVTCHN_ABI_POLL EvtchnAbiPoll; + XENBUS_EVTCHN_ABI_PORT_ENABLE EvtchnAbiPortEnable; + XENBUS_EVTCHN_ABI_PORT_DISABLE EvtchnAbiPortDisable; + XENBUS_EVTCHN_ABI_PORT_ACK EvtchnAbiPortAck; + XENBUS_EVTCHN_ABI_PORT_MASK EvtchnAbiPortMask; + XENBUS_EVTCHN_ABI_PORT_UNMASK EvtchnAbiPortUnmask; } XENBUS_EVTCHN_ABI, *PXENBUS_EVTCHN_ABI; #define XENBUS_EVTCHN_ABI(_Method, _Abi, ...) \ diff --git a/src/xenbus/evtchn_fifo.c b/src/xenbus/evtchn_fifo.c index 4268809..5996b82 100644 --- a/src/xenbus/evtchn_fifo.c +++ b/src/xenbus/evtchn_fifo.c @@ -30,6 +30,7 @@ */ #include <ntddk.h> +#include <procgrp.h> #include <stdarg.h> #include <xen.h> @@ -40,16 +41,14 @@ #include "assert.h" #include "util.h" -#define MAX_HVM_VCPUS 128 - typedef struct _XENBUS_EVTCHN_FIFO_CONTEXT { PXENBUS_FDO Fdo; KSPIN_LOCK Lock; LONG References; - PMDL ControlBlockMdl[MAX_HVM_VCPUS]; + PMDL ControlBlockMdl[HVM_MAX_VCPUS]; PMDL *EventPageMdl; ULONG EventPageCount; - ULONG Head[MAX_HVM_VCPUS][EVTCHN_FIFO_MAX_QUEUES]; + ULONG Head[HVM_MAX_VCPUS][EVTCHN_FIFO_MAX_QUEUES]; } XENBUS_EVTCHN_FIFO_CONTEXT, *PXENBUS_EVTCHN_FIFO_CONTEXT; #define EVENT_WORDS_PER_PAGE (PAGE_SIZE / sizeof (event_word_t)) @@ -280,6 +279,18 @@ EvtchnFifoContract( } static BOOLEAN +EvtchnFifoIsProcessorEnabled( + IN PXENBUS_EVTCHN_ABI_CONTEXT _Context, + IN ULONG Index + ) +{ + PXENBUS_EVTCHN_FIFO_CONTEXT Context = (PVOID)_Context; + unsigned int vcpu_id = SystemVirtualCpuIndex(Index); + + return (Context->ControlBlockMdl[vcpu_id] != NULL) ? TRUE : FALSE; +} + +static BOOLEAN EvtchnFifoPollPriority( IN PXENBUS_EVTCHN_FIFO_CONTEXT Context, IN unsigned int vcpu_id, @@ -331,13 +342,13 @@ EvtchnFifoPollPriority( static BOOLEAN EvtchnFifoPoll( IN PXENBUS_EVTCHN_ABI_CONTEXT _Context, - IN ULONG Cpu, + IN ULONG Index, IN XENBUS_EVTCHN_ABI_EVENT Event, IN PVOID Argument ) { PXENBUS_EVTCHN_FIFO_CONTEXT Context = (PVOID)_Context; - unsigned int vcpu_id = SystemVirtualCpuIndex(Cpu); + unsigned int vcpu_id = SystemVirtualCpuIndex(Index); PMDL Mdl; evtchn_fifo_control_block_t *ControlBlock; ULONG Ready; @@ -346,11 +357,14 @@ EvtchnFifoPoll( Mdl = Context->ControlBlockMdl[vcpu_id]; + DoneSomething = FALSE; + if (Mdl == NULL) + goto done; + ControlBlock = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); ASSERT(ControlBlock != NULL); Ready = InterlockedExchange((LONG *)&ControlBlock->ready, 0); - DoneSomething = FALSE; while (_BitScanReverse(&Priority, Ready)) { DoneSomething |= EvtchnFifoPollPriority(Context, @@ -362,6 +376,7 @@ EvtchnFifoPoll( Ready |= InterlockedExchange((LONG *)&ControlBlock->ready, 0); } +done: return DoneSomething; } @@ -502,13 +517,12 @@ EvtchnFifoReset( static NTSTATUS EvtchnFifoAcquire( - IN PXENBUS_EVTCHN_ABI_CONTEXT _Context, - OUT PKAFFINITY Affinity + IN PXENBUS_EVTCHN_ABI_CONTEXT _Context ) { PXENBUS_EVTCHN_FIFO_CONTEXT Context = (PVOID)_Context; KIRQL Irql; - LONG Cpu; + LONG Index; PMDL Mdl; NTSTATUS status; @@ -519,10 +533,8 @@ EvtchnFifoAcquire( Trace("====>\n"); - *Affinity = 0; - Cpu = 0; - - while (Cpu < (LONG)KeQueryActiveProcessorCount(NULL)) { + Index = 0; + while (Index < (LONG)KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS)) { unsigned int vcpu_id; PFN_NUMBER Pfn; PHYSICAL_ADDRESS Address; @@ -533,7 +545,7 @@ EvtchnFifoAcquire( if (Mdl == NULL) goto fail1; - vcpu_id = SystemVirtualCpuIndex(Cpu); + vcpu_id = SystemVirtualCpuIndex(Index); Pfn = MmGetMdlPfnArray(Mdl)[0]; status = EventChannelInitControl(Pfn, vcpu_id); @@ -550,8 +562,7 @@ EvtchnFifoAcquire( Context->ControlBlockMdl[vcpu_id] = Mdl; - *Affinity |= (KAFFINITY)1 << Cpu; - Cpu++; + Index++; } Trace("<====\n"); @@ -569,10 +580,10 @@ fail1: (VOID) EventChannelReset(); - while (--Cpu >= 0) { + while (--Index >= 0) { unsigned int vcpu_id; - vcpu_id = SystemVirtualCpuIndex(Cpu); + vcpu_id = SystemVirtualCpuIndex(Index); Mdl = Context->ControlBlockMdl[vcpu_id]; Context->ControlBlockMdl[vcpu_id] = NULL; @@ -607,7 +618,7 @@ EvtchnFifoRelease( EvtchnFifoContract(Context); - vcpu_id = MAX_HVM_VCPUS; + vcpu_id = HVM_MAX_VCPUS; while (--vcpu_id >= 0) { PMDL Mdl; @@ -630,6 +641,7 @@ static XENBUS_EVTCHN_ABI EvtchnAbiFifo = { NULL, EvtchnFifoAcquire, EvtchnFifoRelease, + EvtchnFifoIsProcessorEnabled, EvtchnFifoPoll, EvtchnFifoPortEnable, EvtchnFifoPortDisable, diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c index b30c4bc..8d8b125 100644 --- a/src/xenbus/fdo.c +++ b/src/xenbus/fdo.c @@ -32,6 +32,7 @@ #define INITGUID 1 #include <ntddk.h> +#include <procgrp.h> #include <wdmguid.h> #include <ntstrsafe.h> #include <stdlib.h> @@ -70,7 +71,7 @@ struct _XENBUS_INTERRUPT { LIST_ENTRY ListEntry; KINTERRUPT_MODE InterruptMode; PKINTERRUPT InterruptObject; - ULONG Cpu; + PROCESSOR_NUMBER ProcNumber; UCHAR Vector; ULONG Line; PKSERVICE_ROUTINE Callback; @@ -1205,12 +1206,15 @@ FdoSuspend( ) { PXENBUS_FDO Fdo = Context; + GROUP_AFFINITY Affinity; PKEVENT Event; Info("====>\n"); // We really want to know what CPU this thread will run on - KeSetSystemAffinityThread((KAFFINITY)1); + Affinity.Group = 0; + Affinity.Mask = (KAFFINITY)1; + KeSetSystemGroupAffinityThread(&Affinity, NULL); Event = ThreadGetEvent(Self); @@ -1521,7 +1525,7 @@ FdoDumpIoResourceDescriptor( else if (Descriptor->Option == (IO_RESOURCE_ALTERNATIVE | IO_RESOURCE_PREFERRED)) Trace("Preferred Alternative\n"); - Trace("ShareDisposition=%s Flags=%04x\n", + Trace("ShareDisposition = %s Flags = %04x\n", ResourceDescriptorShareDispositionName(Descriptor->ShareDisposition), Descriptor->Flags); @@ -1537,11 +1541,12 @@ FdoDumpIoResourceDescriptor( break; case CmResourceTypeInterrupt: - Trace("MinimumVector=%08x MaximumVector=%08x AffinityPolicy=%s PriorityPolicy=%s TargettedProcessors = %p\n", + Trace("MinimumVector = %08x MaximumVector = %08x AffinityPolicy = %s PriorityPolicy = %s Group = %u TargettedProcessors = %p\n", Descriptor->u.Interrupt.MinimumVector, Descriptor->u.Interrupt.MaximumVector, IrqDevicePolicyName(Descriptor->u.Interrupt.AffinityPolicy), IrqPriorityName(Descriptor->u.Interrupt.PriorityPolicy), + Descriptor->u.Interrupt.Group, (PVOID)Descriptor->u.Interrupt.TargetedProcessors); break; @@ -1594,7 +1599,7 @@ FdoFilterResourceRequirements( Old = (PIO_RESOURCE_REQUIREMENTS_LIST)Irp->IoStatus.Information; ASSERT3U(Old->AlternativeLists, ==, 1); - Count = KeQueryActiveProcessorCount(NULL); + Count = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); Size = Old->ListSize + (sizeof (IO_RESOURCE_DESCRIPTOR) * Count); @@ -1618,6 +1623,7 @@ FdoFilterResourceRequirements( Descriptor->Flags |= CM_RESOURCE_INTERRUPT_POLICY_INCLUDED; Descriptor->u.Interrupt.AffinityPolicy = IrqPolicySpecifiedProcessors; + Descriptor->u.Interrupt.Group = 0; Descriptor->u.Interrupt.TargetedProcessors = (KAFFINITY)1; } @@ -1635,7 +1641,13 @@ FdoFilterResourceRequirements( Interrupt.u.Interrupt.PriorityPolicy = IrqPriorityUndefined; for (Index = 0; Index < Count; Index++) { - Interrupt.u.Interrupt.TargetedProcessors = (KAFFINITY)1 << Index; + PROCESSOR_NUMBER ProcNumber; + + status = KeGetProcessorNumberFromIndex(Index, &ProcNumber); + ASSERT(NT_SUCCESS(status)); + + Interrupt.u.Interrupt.Group = ProcNumber.Group; + Interrupt.u.Interrupt.TargetedProcessors = (KAFFINITY)1 << ProcNumber.Number; List->Descriptors[List->Count++] = Interrupt; } @@ -1825,7 +1837,7 @@ FdoConnectInterrupt( { IO_CONNECT_INTERRUPT_PARAMETERS Connect; BOOLEAN Found; - ULONG Cpu; + ULONG Number; NTSTATUS status; Trace("====>\n"); @@ -1845,7 +1857,7 @@ FdoConnectInterrupt( (*Interrupt)->Line = Raw->u.Interrupt.Vector; RtlZeroMemory(&Connect, sizeof (IO_CONNECT_INTERRUPT_PARAMETERS)); - Connect.Version = CONNECT_FULLY_SPECIFIED; + Connect.Version = CONNECT_FULLY_SPECIFIED_GROUP; Connect.FullySpecified.PhysicalDeviceObject = __FdoGetPhysicalDeviceObject(Fdo); Connect.FullySpecified.ShareVector = (BOOLEAN)(Translated->ShareDisposition == CmResourceShareShared); Connect.FullySpecified.InterruptMode = (*Interrupt)->InterruptMode; @@ -1857,11 +1869,13 @@ FdoConnectInterrupt( Connect.FullySpecified.Vector = Translated->u.MessageInterrupt.Translated.Vector; Connect.FullySpecified.Irql = (KIRQL)Translated->u.MessageInterrupt.Translated.Level; Connect.FullySpecified.SynchronizeIrql = (KIRQL)Translated->u.MessageInterrupt.Translated.Level; + Connect.FullySpecified.Group = Translated->u.MessageInterrupt.Translated.Group; Connect.FullySpecified.ProcessorEnableMask = Translated->u.MessageInterrupt.Translated.Affinity; } else { Connect.FullySpecified.Vector = Translated->u.Interrupt.Vector; Connect.FullySpecified.Irql = (KIRQL)Translated->u.Interrupt.Level; Connect.FullySpecified.SynchronizeIrql = (KIRQL)Translated->u.Interrupt.Level; + Connect.FullySpecified.Group = Translated->u.Interrupt.Group; Connect.FullySpecified.ProcessorEnableMask = Translated->u.Interrupt.Affinity; } @@ -1871,22 +1885,25 @@ FdoConnectInterrupt( (*Interrupt)->Vector = (UCHAR)Connect.FullySpecified.Vector; + (*Interrupt)->ProcNumber.Group = Connect.FullySpecified.Group; + #if defined(__i386__) - Found = _BitScanReverse(&Cpu, Connect.FullySpecified.ProcessorEnableMask); + Found = _BitScanReverse(&Number, Connect.FullySpecified.ProcessorEnableMask); #elif defined(__x86_64__) - Found = _BitScanReverse64(&Cpu, Connect.FullySpecified.ProcessorEnableMask); + Found = _BitScanReverse64(&Number, Connect.FullySpecified.ProcessorEnableMask); #else #error 'Unrecognised architecture' #endif ASSERT(Found); - (*Interrupt)->Cpu = Cpu; + (*Interrupt)->ProcNumber.Number = (UCHAR)Number; - Info("%p: %s %s CPU %u VECTOR %02x\n", + Info("%p: %s %s CPU %u:%u VECTOR %02x\n", (*Interrupt)->InterruptObject, ResourceDescriptorShareDispositionName(Translated->ShareDisposition), InterruptModeName((*Interrupt)->InterruptMode), - (*Interrupt)->Cpu, + (*Interrupt)->ProcNumber.Group, + (*Interrupt)->ProcNumber.Number, (*Interrupt)->Vector); Trace("<====\n"); @@ -1917,12 +1934,13 @@ FdoDisconnectInterrupt( Trace("====>\n"); - Info("%p: CPU %u VECTOR %02x\n", + Info("%p: CPU %u:%u VECTOR %02x\n", Interrupt->InterruptObject, - Interrupt->Cpu, + Interrupt->ProcNumber.Group, + Interrupt->ProcNumber.Number, Interrupt->Vector); - Interrupt->Cpu = 0; + RtlZeroMemory(&Interrupt->ProcNumber, sizeof (PROCESSOR_NUMBER)); Interrupt->Vector = 0; RtlZeroMemory(&Disconnect, sizeof (IO_DISCONNECT_INTERRUPT_PARAMETERS)); @@ -1994,7 +2012,8 @@ PXENBUS_INTERRUPT FdoAllocateInterrupt( IN PXENBUS_FDO Fdo, IN KINTERRUPT_MODE InterruptMode, - IN ULONG Cpu, + IN USHORT Group, + IN UCHAR Number, IN KSERVICE_ROUTINE Callback, IN PVOID Argument OPTIONAL ) @@ -2010,7 +2029,8 @@ FdoAllocateInterrupt( if (Interrupt->Callback == NULL && Interrupt->InterruptMode == InterruptMode && - Interrupt->Cpu == Cpu) + Interrupt->ProcNumber.Group == Group && + Interrupt->ProcNumber.Number == Number) goto found; } diff --git a/src/xenbus/fdo.h b/src/xenbus/fdo.h index a07b55f..4b99ba0 100644 --- a/src/xenbus/fdo.h +++ b/src/xenbus/fdo.h @@ -169,7 +169,8 @@ extern PXENBUS_INTERRUPT FdoAllocateInterrupt( IN PXENBUS_FDO Fdo, IN KINTERRUPT_MODE InterruptMode, - IN ULONG Cpu, + IN USHORT Group, + IN UCHAR Number, IN KSERVICE_ROUTINE Callback, IN PVOID Argument OPTIONAL ); diff --git a/src/xenbus/pdo.c b/src/xenbus/pdo.c index 58eeadd..7eb967c 100644 --- a/src/xenbus/pdo.c +++ b/src/xenbus/pdo.c @@ -821,100 +821,14 @@ PdoS3ToS4( Trace("(%s) <====\n", __PdoGetName(Pdo)); } -static VOID -PdoParseResources( - IN PXENBUS_PDO Pdo, - IN PCM_RESOURCE_LIST RawResourceList, - IN PCM_RESOURCE_LIST TranslatedResourceList - ) -{ - PCM_PARTIAL_RESOURCE_LIST RawPartialList; - PCM_PARTIAL_RESOURCE_LIST TranslatedPartialList; - ULONG Index; - - UNREFERENCED_PARAMETER(Pdo); - - ASSERT3U(RawResourceList->Count, ==, 1); - RawPartialList = &RawResourceList->List[0].PartialResourceList; - - ASSERT3U(RawPartialList->Version, ==, 1); - ASSERT3U(RawPartialList->Revision, ==, 1); - - ASSERT3U(TranslatedResourceList->Count, ==, 1); - TranslatedPartialList = &TranslatedResourceList->List[0].PartialResourceList; - - ASSERT3U(TranslatedPartialList->Version, ==, 1); - ASSERT3U(TranslatedPartialList->Revision, ==, 1); - - for (Index = 0; Index < TranslatedPartialList->Count; Index++) { - PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDescriptor; - PCM_PARTIAL_RESOURCE_DESCRIPTOR TranslatedPartialDescriptor; - - RawPartialDescriptor = &RawPartialList->PartialDescriptors[Index]; - TranslatedPartialDescriptor = &TranslatedPartialList->PartialDescriptors[Index]; - - Trace("%s: [%d] %02x:%s\n", - __PdoGetName(Pdo), - Index, - TranslatedPartialDescriptor->Type, - ResourceDescriptorTypeName(TranslatedPartialDescriptor->Type)); - - switch (TranslatedPartialDescriptor->Type) { - case CmResourceTypeMemory: - Trace("RAW: SharedDisposition=%02x Flags=%04x Start = %08x.%08x Length = %08x\n", - RawPartialDescriptor->ShareDisposition, - RawPartialDescriptor->Flags, - RawPartialDescriptor->u.Memory.Start.HighPart, - RawPartialDescriptor->u.Memory.Start.LowPart, - RawPartialDescriptor->u.Memory.Length); - - Trace("TRANSLATED: SharedDisposition=%02x Flags=%04x Start = %08x.%08x Length = %08x\n", - TranslatedPartialDescriptor->ShareDisposition, - TranslatedPartialDescriptor->Flags, - TranslatedPartialDescriptor->u.Memory.Start.HighPart, - TranslatedPartialDescriptor->u.Memory.Start.LowPart, - TranslatedPartialDescriptor->u.Memory.Length); - break; - - case CmResourceTypeInterrupt: - Trace("RAW: SharedDisposition=%02x Flags=%04x Level = %08x Vector = %08x Affinity = %p\n", - RawPartialDescriptor->ShareDisposition, - RawPartialDescriptor->Flags, - RawPartialDescriptor->u.Interrupt.Level, - RawPartialDescriptor->u.Interrupt.Vector, - (PVOID)RawPartialDescriptor->u.Interrupt.Affinity); - - Trace("TRANSLATED: SharedDisposition=%02x Flags=%04x Level = %08x Vector = %08x Affinity = %p\n", - TranslatedPartialDescriptor->ShareDisposition, - TranslatedPartialDescriptor->Flags, - TranslatedPartialDescriptor->u.Interrupt.Level, - TranslatedPartialDescriptor->u.Interrupt.Vector, - (PVOID)TranslatedPartialDescriptor->u.Interrupt.Affinity); - break; - - default: - break; - } - } - - Trace("<====\n"); -} - static NTSTATUS PdoStartDevice( IN PXENBUS_PDO Pdo, IN PIRP Irp ) { - PIO_STACK_LOCATION StackLocation; NTSTATUS status; - StackLocation = IoGetCurrentIrpStackLocation(Irp); - - PdoParseResources(Pdo, - StackLocation->Parameters.StartDevice.AllocatedResources, - StackLocation->Parameters.StartDevice.AllocatedResourcesTranslated); - PdoD3ToD0(Pdo); __PdoSetDevicePnpState(Pdo, Started); @@ -1375,6 +1289,7 @@ PdoQueryResourceRequirements( Interrupt.u.Interrupt.MaximumVector = (ULONG)-1; Interrupt.u.Interrupt.AffinityPolicy = IrqPolicyOneCloseProcessor; Interrupt.u.Interrupt.PriorityPolicy = IrqPriorityUndefined; + Interrupt.u.Interrupt.Group = ALL_PROCESSOR_GROUPS; Size = sizeof (IO_RESOURCE_DESCRIPTOR) * 2; Size += FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors); diff --git a/src/xenbus/shared_info.c b/src/xenbus/shared_info.c index 09d035a..1b71ba1 100644 --- a/src/xenbus/shared_info.c +++ b/src/xenbus/shared_info.c @@ -30,6 +30,7 @@ */ #include <ntddk.h> +#include <procgrp.h> #include <xen.h> #include "shared_info.h" @@ -155,12 +156,12 @@ SharedInfoEvtchnMaskAll( static BOOLEAN SharedInfoUpcallPending( IN PINTERFACE Interface, - IN ULONG Cpu + IN ULONG Index ) { PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; shared_info_t *Shared = Context->Shared; - int vcpu_id = SystemVirtualCpuIndex(Cpu); + int vcpu_id = SystemVirtualCpuIndex(Index); UCHAR Pending; KeMemoryBarrier(); @@ -173,14 +174,14 @@ SharedInfoUpcallPending( static BOOLEAN SharedInfoEvtchnPoll( IN PINTERFACE Interface, - IN ULONG Cpu, + IN ULONG Index, IN XENBUS_SHARED_INFO_EVENT Event, IN PVOID Argument OPTIONAL ) { PXENBUS_SHARED_INFO_CONTEXT Context = Interface->Context; shared_info_t *Shared = Context->Shared; - int vcpu_id = SystemVirtualCpuIndex(Cpu); + int vcpu_id = SystemVirtualCpuIndex(Index); ULONG Port; ULONG_PTR SelectorMask; BOOLEAN DoneSomething; @@ -457,28 +458,36 @@ SharedInfoDebugCallback( if (!Crashing) { shared_info_t *Shared; - ULONG Cpu; + ULONG Index; ULONG Selector; Shared = Context->Shared; KeMemoryBarrier(); - for (Cpu = 0; Cpu < KeQueryActiveProcessorCount(NULL); Cpu++) { - int vcpu_id = SystemVirtualCpuIndex(Cpu); + for (Index = 0; + Index < KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); + Index++) { + PROCESSOR_NUMBER ProcNumber; + int vcpu_id; + + (VOID) KeGetProcessorNumberFromIndex(Index, &ProcNumber); + vcpu_id = SystemVirtualCpuIndex(Index); XENBUS_DEBUG(Printf, &Context->DebugInterface, - "CPU %u: PENDING: %s\n", - Cpu, + "CPU %u:%u: PENDING: %s\n", + ProcNumber.Group, + ProcNumber.Number, Shared->vcpu_info[vcpu_id].evtchn_upcall_pending ? "TRUE" : "FALSE"); XENBUS_DEBUG(Printf, &Context->DebugInterface, - "CPU %u: SELECTOR MASK: %p\n", - Cpu, + "CPU %u:u: SELECTOR MASK: %p\n", + ProcNumber.Group, + ProcNumber.Number, (PVOID)Shared->vcpu_info[vcpu_id].evtchn_pending_sel); } diff --git a/src/xenbus/sync.c b/src/xenbus/sync.c index d4af525..835b46b 100644 --- a/src/xenbus/sync.c +++ b/src/xenbus/sync.c @@ -30,6 +30,7 @@ */ #include <ntddk.h> +#include <procgrp.h> #include <stdarg.h> #include <xen.h> @@ -39,80 +40,83 @@ #include "util.h" // Routines to capture all CPUs in a spinning state with interrupts -// disabled (so that we remain in a known code context) and optionally -// execute a function on each CPU. +// disabled (so that we remain in a known code context). // These routines are used for suspend/resume and live snapshot. // The general sequence of steps is follows: // -// - SyncCaptureAndCall() is called on an arbitrary CPU +// - SyncCapture() is called on an arbitrary CPU. It must be called at +// DISPATCH_LEVEL so it cannot be pre-empted and moved to another CPU. +// It schedules a DPC on each of the other CPUs and spins until all +// CPUs are executing the DPC, which will in-turn spin awaiting +// further instruction. // -// - It raises to DISPATCH_LEVEL to avoid pre-emption and schedules -// a DPC on each of the other CPUs. +// - SyncDisableInterrputs() instructs the DPC routines to all raise +// to HIGH_LEVEL and disable interrupts for its CPU. It then raises +// to HIGH_LEVEL itself, spins waiting for confirmation from each +// DPC that it has disabled interrupts and then disables interrupts +// itself. // -// - It, and the DPC routines, all raise to HIGH_LEVEL, clear a -// a bit corresponding to their CPU in a 'captured' mask, and then -// spin waiting for the mask to become zero (i.e. all CPUs captured). +// NOTE: There is a back-off in trying to disable interrupts. It is +// possible that CPU A is waiting for an IPI to CPU B to +// complete, but CPU B is spinning with interrupts disabled. +// Thus the DPC on CPU A will never make it to HIGH_LEVEL and +// hence never get to disable interrupts. Thus if, while +// spinning with interrupts disabled, one DPC notices that +// another DPC has not made it, it briefly enables interrupts +// and drops back down to DISPATCH_LEVEL before trying again. +// This should allow any pending IPI to complete. // -// NOTE: There is a back-off in this spin. It is possible that CPU A -// is waiting for an IPI to CPU B to complete, but CPU B is -// spinning at HIGH_LEVEL. Thus CPU A will never make it to -// HIGH_LEVEL. Thus if, while spinning at HIGH_LEVEL, we notice -// that another CPU has not made it, we set our bit in the -// 'captured' mask again and briefly drop down to DISPATCH_LEVEL -// before trying again. This should allow any pending IPI to -// complete. +// - SyncEnableInterrupts() instructs the DPC routines to all enable +// interrupts and drop back to DISPATCH_LEVEL before enabling +// interrupts and dropping back to DISPATCH_LEVEL itself. // -// - Once all CPUs are captured, each disables interrupts, executes an -// optional function. All the DPC routined clear a bit corresponding -// to their CPU in a 'completed' mask and then spin waiting for the -// mask to become zero. The requesting CPU also executes the optional -// function bit it then waits for the mask to only contain the bit -// corresponding to its CPU and then returns from -// SyncCaptureAndCall() at HIGH_LEVEL. -// -// - A subsequent call to SyncRelease() will clear the last -// remaining bit (clearly it is necessarily executed on the same CPU -// as SyncCaptureAndCall()) and thus allow all the DPC -// routines to lower back to DISPATCH_LEVEL and complete. -// -// - SyncRelease() also lowers back to DISPATCH_LEVEL and then -// back to the IRQL is was originally entered at. +// - SyncRelease() instructs the DPC routines to exit, thus allowing +// the scheduler to run on the other CPUs again. It spins until all +// DPCs have completed and then returns. + +#pragma data_seg("sync") +__declspec(allocate("sync")) +static UCHAR __Section[PAGE_SIZE]; + +typedef struct _SYNC_PROCESSOR { + KDPC Dpc; + BOOLEAN DisableInterrupts; + BOOLEAN Exit; +} SYNC_PROCESSOR, *PSYNC_PROCESSOR; typedef struct _SYNC_CONTEXT { - KDPC Dpc[MAXIMUM_PROCESSORS]; ULONG Sequence; - LONG CpuCount; + LONG ProcessorCount; LONG CompletionCount; - BOOLEAN DisableInterrupts[MAXIMUM_PROCESSORS]; - BOOLEAN Exit[MAXIMUM_PROCESSORS]; + SYNC_PROCESSOR Processor[1]; } SYNC_CONTEXT, *PSYNC_CONTEXT; -static LONG SyncOwner = MAXIMUM_PROCESSORS; +static PSYNC_CONTEXT SyncContext = (PVOID)__Section; +static LONG SyncOwner = -1; static FORCEINLINE VOID __SyncAcquire( - IN LONG Cpu + IN LONG Index ) { LONG Old; - Old = InterlockedExchange(&SyncOwner, Cpu); - ASSERT3U(Old, ==, MAXIMUM_PROCESSORS); + Old = InterlockedExchange(&SyncOwner, Index); + ASSERT3U(Old, ==, -1); } static FORCEINLINE VOID __SyncRelease( - IN LONG Cpu + IN LONG Index ) { LONG Old; - Old = InterlockedExchange(&SyncOwner, MAXIMUM_PROCESSORS); - ASSERT3U(Old, ==, Cpu); + Old = InterlockedExchange(&SyncOwner, -1); + ASSERT3U(Old, ==, Index); } -static SYNC_CONTEXT SyncContext; KDEFERRED_ROUTINE SyncWorker; @@ -122,53 +126,57 @@ KDEFERRED_ROUTINE SyncWorker; VOID #pragma prefast(suppress:28166) // Function does not restore IRQL SyncWorker( - IN PKDPC Dpc, - IN PVOID Context, - IN PVOID Argument1, - IN PVOID Argument2 + IN PKDPC Dpc, + IN PVOID _Context, + IN PVOID Argument1, + IN PVOID Argument2 ) { - BOOLEAN InterruptsDisabled; - ULONG Cpu; + PSYNC_CONTEXT Context = SyncContext; + BOOLEAN InterruptsDisabled; + ULONG Index; + PSYNC_PROCESSOR Processor; + PROCESSOR_NUMBER ProcNumber; UNREFERENCED_PARAMETER(Dpc); - UNREFERENCED_PARAMETER(Context); + UNREFERENCED_PARAMETER(_Context); UNREFERENCED_PARAMETER(Argument1); UNREFERENCED_PARAMETER(Argument2); InterruptsDisabled = FALSE; - Cpu = KeGetCurrentProcessorNumber(); + Index = KeGetCurrentProcessorNumberEx(&ProcNumber); + Processor = &Context->Processor[Index]; - Trace("====> (%u)\n", Cpu); - InterlockedIncrement(&SyncContext.CompletionCount); + Trace("====> (%u:%u)\n", ProcNumber.Group, ProcNumber.Number); + InterlockedIncrement(&Context->CompletionCount); for (;;) { ULONG Sequence; - if (SyncContext.Exit[Cpu]) + if (Processor->Exit) break; - if (SyncContext.DisableInterrupts[Cpu] == InterruptsDisabled) { + if (Processor->DisableInterrupts == InterruptsDisabled) { _mm_pause(); KeMemoryBarrier(); continue; } - Sequence = SyncContext.Sequence; + Sequence = Context->Sequence; - if (SyncContext.DisableInterrupts[Cpu]) { + if (Processor->DisableInterrupts) { ULONG Attempts; NTSTATUS status; (VOID) KfRaiseIrql(HIGH_LEVEL); status = STATUS_SUCCESS; - InterlockedIncrement(&SyncContext.CompletionCount); + InterlockedIncrement(&Context->CompletionCount); Attempts = 0; - while (SyncContext.Sequence == Sequence && - SyncContext.CompletionCount < SyncContext.CpuCount) { + while (Context->Sequence == Sequence && + Context->CompletionCount < Context->ProcessorCount) { _mm_pause(); KeMemoryBarrier(); @@ -177,14 +185,14 @@ SyncWorker( LONG New; do { - Old = SyncContext.CompletionCount; + Old = Context->CompletionCount; New = Old - 1; - if (Old == SyncContext.CpuCount) + if (Old == Context->ProcessorCount) break; - } while (InterlockedCompareExchange(&SyncContext.CompletionCount, New, Old) != Old); + } while (InterlockedCompareExchange(&Context->CompletionCount, New, Old) != Old); - if (Old < SyncContext.CpuCount) { + if (Old < Context->ProcessorCount) { #pragma prefast(suppress:28138) // Use constant rather than variable KeLowerIrql(DISPATCH_LEVEL); status = STATUS_UNSUCCESSFUL; @@ -207,10 +215,10 @@ SyncWorker( #pragma prefast(suppress:28138) // Use constant rather than variable KeLowerIrql(DISPATCH_LEVEL); - InterlockedIncrement(&SyncContext.CompletionCount); + InterlockedIncrement(&Context->CompletionCount); - while (SyncContext.Sequence == Sequence && - SyncContext.CompletionCount < SyncContext.CpuCount) { + while (Context->Sequence == Sequence && + Context->CompletionCount < Context->ProcessorCount) { _mm_pause(); KeMemoryBarrier(); } @@ -218,8 +226,8 @@ SyncWorker( } } - Trace("<==== (%u)\n", Cpu); - InterlockedIncrement(&SyncContext.CompletionCount); + Trace("<==== (%u:%u)\n", ProcNumber.Group, ProcNumber.Number); + InterlockedIncrement(&Context->CompletionCount); ASSERT(!InterruptsDisabled); } @@ -231,44 +239,55 @@ SyncCapture( VOID ) { - ULONG Cpu; - ULONG Index; + PSYNC_CONTEXT Context = SyncContext; + LONG Index; + PROCESSOR_NUMBER ProcNumber; + USHORT Group; + UCHAR Number; ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); - Cpu = KeGetCurrentProcessorNumber(); - __SyncAcquire(Cpu); + Index = KeGetCurrentProcessorNumberEx(&ProcNumber); + __SyncAcquire(Index); - Trace("====> (%u)\n", Cpu); + Group = ProcNumber.Group; + Number = ProcNumber.Number; - ASSERT(IsZeroMemory(&SyncContext, sizeof (SYNC_CONTEXT))); + Trace("====> (%u:%u)\n", Group, Number); - SyncContext.Sequence++; - SyncContext.CompletionCount = 0; - SyncContext.CpuCount = KeQueryActiveProcessorCount(NULL); + ASSERT(IsZeroMemory(Context, sizeof (SYNC_CONTEXT))); - for (Index = 0; Index < (ULONG)SyncContext.CpuCount; Index++) { - PKDPC Dpc = &SyncContext.Dpc[Index]; + Context->Sequence++; + Context->CompletionCount = 0; - SyncContext.DisableInterrupts[Index] = FALSE; - SyncContext.Exit[Index] = FALSE; + Context->ProcessorCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); - if (Index == Cpu) + for (Index = 0; Index < Context->ProcessorCount; Index++) { + PSYNC_PROCESSOR Processor = &Context->Processor[Index]; + NTSTATUS status; + + ASSERT3U((ULONG_PTR)(Processor + 1), <, (ULONG_PTR)__Section + PAGE_SIZE); + + status = KeGetProcessorNumberFromIndex(Index, &ProcNumber); + ASSERT(NT_SUCCESS(status)); + + if (ProcNumber.Group == Group && + ProcNumber.Number == Number) continue; - KeInitializeDpc(Dpc, SyncWorker, NULL); - KeSetTargetProcessorDpc(Dpc, (CCHAR)Index); - KeInsertQueueDpc(Dpc, NULL, NULL); + KeInitializeDpc(&Processor->Dpc, SyncWorker, NULL); + KeSetTargetProcessorDpcEx(&Processor->Dpc, &ProcNumber); + KeInsertQueueDpc(&Processor->Dpc, NULL, NULL); } - InterlockedIncrement(&SyncContext.CompletionCount); + InterlockedIncrement(&Context->CompletionCount); - while (SyncContext.CompletionCount < SyncContext.CpuCount) { + while (Context->CompletionCount < Context->ProcessorCount) { _mm_pause(); KeMemoryBarrier(); } - Trace("<==== (%u)\n", Cpu); + Trace("<==== (%u:%u)\n", Group, Number); } __drv_requiresIRQL(DISPATCH_LEVEL) @@ -278,26 +297,32 @@ SyncDisableInterrupts( VOID ) { - ULONG Index; - ULONG Attempts; - NTSTATUS status; + PSYNC_CONTEXT Context = SyncContext; + LONG Index; + ULONG Attempts; + NTSTATUS status; Trace("====>\n"); - SyncContext.Sequence++; - SyncContext.CompletionCount = 0; + Context->Sequence++; + Context->CompletionCount = 0; + + for (Index = 0; Index < Context->ProcessorCount; Index++) { + PSYNC_PROCESSOR Processor = &Context->Processor[Index]; - for (Index = 0; Index < (ULONG)SyncContext.CpuCount; Index++) - SyncContext.DisableInterrupts[Index] = TRUE; + Processor->DisableInterrupts = TRUE; + } + + KeMemoryBarrier(); again: (VOID) KfRaiseIrql(HIGH_LEVEL); status = STATUS_SUCCESS; - InterlockedIncrement(&SyncContext.CompletionCount); + InterlockedIncrement(&Context->CompletionCount); Attempts = 0; - while (SyncContext.CompletionCount < SyncContext.CpuCount) { + while (Context->CompletionCount < Context->ProcessorCount) { _mm_pause(); KeMemoryBarrier(); @@ -306,18 +331,18 @@ again: LONG New; do { - Old = SyncContext.CompletionCount; + Old = Context->CompletionCount; New = Old - 1; - if (Old == SyncContext.CpuCount) + if (Old == Context->ProcessorCount) break; - } while (InterlockedCompareExchange(&SyncContext.CompletionCount, New, Old) != Old); + } while (InterlockedCompareExchange(&Context->CompletionCount, New, Old) != Old); - if (Old < SyncContext.CpuCount) { + if (Old < Context->ProcessorCount) { LogPrintf(LOG_LEVEL_WARNING, "SYNC: %d < %d\n", Old, - SyncContext.CpuCount); + Context->ProcessorCount); #pragma prefast(suppress:28138) // Use constant rather than variable KeLowerIrql(DISPATCH_LEVEL); @@ -339,23 +364,29 @@ VOID SyncEnableInterrupts( ) { - KIRQL Irql; - ULONG Index; + PSYNC_CONTEXT Context = SyncContext; + KIRQL Irql; + LONG Index; _enable(); Irql = KeGetCurrentIrql(); ASSERT3U(Irql, ==, HIGH_LEVEL); - SyncContext.Sequence++; - SyncContext.CompletionCount = 0; + Context->Sequence++; + Context->CompletionCount = 0; + + for (Index = 0; Index < Context->ProcessorCount; Index++) { + PSYNC_PROCESSOR Processor = &Context->Processor[Index]; + + Processor->DisableInterrupts = FALSE; + } - for (Index = 0; Index < (ULONG)SyncContext.CpuCount; Index++) - SyncContext.DisableInterrupts[Index] = FALSE; + KeMemoryBarrier(); - InterlockedIncrement(&SyncContext.CompletionCount); + InterlockedIncrement(&Context->CompletionCount); - while (SyncContext.CompletionCount < SyncContext.CpuCount) { + while (Context->CompletionCount < Context->ProcessorCount) { _mm_pause(); KeMemoryBarrier(); } @@ -373,28 +404,33 @@ SyncRelease( VOID ) { - ULONG Cpu; - ULONG Index; + PSYNC_CONTEXT Context = SyncContext; + LONG Index; Trace("====>\n"); - SyncContext.Sequence++; - SyncContext.CompletionCount = 0; + Context->Sequence++; + Context->CompletionCount = 0; + + for (Index = 0; Index < Context->ProcessorCount; Index++) { + PSYNC_PROCESSOR Processor = &Context->Processor[Index]; + + Processor->Exit = TRUE; + } - for (Index = 0; Index < (ULONG)SyncContext.CpuCount; Index++) - SyncContext.Exit[Index] = TRUE; + KeMemoryBarrier(); - InterlockedIncrement(&SyncContext.CompletionCount); + InterlockedIncrement(&Context->CompletionCount); - while (SyncContext.CompletionCount < SyncContext.CpuCount) { + while (Context->CompletionCount < Context->ProcessorCount) { _mm_pause(); KeMemoryBarrier(); } - RtlZeroMemory(&SyncContext, sizeof (SYNC_CONTEXT)); + RtlZeroMemory(Context, sizeof (SYNC_CONTEXT)); - Cpu = KeGetCurrentProcessorNumber(); - __SyncRelease(Cpu); + Index = KeGetCurrentProcessorNumberEx(NULL); + __SyncRelease(Index); Trace("<====\n"); } diff --git a/src/xenfilt/driver.c b/src/xenfilt/driver.c index 420e827..16ed6f7 100644 --- a/src/xenfilt/driver.c +++ b/src/xenfilt/driver.c @@ -30,6 +30,7 @@ */ #include <ntddk.h> +#include <procgrp.h> #include <xen.h> #include "registry.h" @@ -775,6 +776,7 @@ DriverEntry( ASSERT3P(__DriverGetDriverObject(), ==, NULL); ExInitializeDriverRuntime(DrvRtPoolNxOptIn); + WdmlibProcgrpInitialize(); __DbgPrintEnable(); diff --git a/vs2012/xen/xen.vcxproj b/vs2012/xen/xen.vcxproj index 0d92eac..df966af 100644 --- a/vs2012/xen/xen.vcxproj +++ b/vs2012/xen/xen.vcxproj @@ -34,7 +34,7 @@ <Inputs>..\..\include\version.hx</Inputs> </CustomBuildStep> <ClCompile> - <PreprocessorDefinitions>__MODULE__="XEN";POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>__MODULE__="XEN";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <WarningLevel>EnableAllWarnings</WarningLevel> <DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings> <MultiProcessorCompilation>true</MultiProcessorCompilation> @@ -42,7 +42,7 @@ </ClCompile> <Link> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> - <AdditionalDependencies>$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>../../src/xen/xen.def</ModuleDefinitionFile> <EnableCOMDATFolding>false</EnableCOMDATFolding> </Link> diff --git a/vs2012/xenbus/xenbus.vcxproj b/vs2012/xenbus/xenbus.vcxproj index 3319372..ab78a02 100644 --- a/vs2012/xenbus/xenbus.vcxproj +++ b/vs2012/xenbus/xenbus.vcxproj @@ -34,7 +34,7 @@ <Inputs>..\..\src\xenbus.inf</Inputs> </CustomBuildStep> <ClCompile> - <PreprocessorDefinitions>__MODULE__="XENBUS";POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>__MODULE__="XENBUS";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <WarningLevel>EnableAllWarnings</WarningLevel> <DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings> <MultiProcessorCompilation>true</MultiProcessorCompilation> @@ -42,7 +42,7 @@ </ClCompile> <Link> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> - <AdditionalDependencies>$(ProjectDir)..\$(ConfigurationName)\$(Platform)\xen.lib;$(DDK_LIB_PATH)/libcntpr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(ProjectDir)..\$(ConfigurationName)\$(Platform)\xen.lib;$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies> <EnableCOMDATFolding>false</EnableCOMDATFolding> </Link> <Inf> diff --git a/vs2012/xenfilt/xenfilt.vcxproj b/vs2012/xenfilt/xenfilt.vcxproj index 5dbb903..34efda4 100644 --- a/vs2012/xenfilt/xenfilt.vcxproj +++ b/vs2012/xenfilt/xenfilt.vcxproj @@ -26,7 +26,7 @@ </PropertyGroup> <ItemDefinitionGroup> <ClCompile> - <PreprocessorDefinitions>__MODULE__="XENFILT";POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>__MODULE__="XENFILT";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <WarningLevel>EnableAllWarnings</WarningLevel> <DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings> <MultiProcessorCompilation>true</MultiProcessorCompilation> @@ -34,7 +34,7 @@ </ClCompile> <Link> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> - <AdditionalDependencies>$(ProjectDir)..\$(ConfigurationName)\$(Platform)\xen.lib;$(DDK_LIB_PATH)/libcntpr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(ProjectDir)..\$(ConfigurationName)\$(Platform)\xen.lib;$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies> <EnableCOMDATFolding>false</EnableCOMDATFolding> </Link> <Inf> diff --git a/vs2013/xen/xen.vcxproj b/vs2013/xen/xen.vcxproj index a12f060..cd40452 100644 --- a/vs2013/xen/xen.vcxproj +++ b/vs2013/xen/xen.vcxproj @@ -34,7 +34,7 @@ </CustomBuildStep> <ClCompile> <AdditionalIncludeDirectories>$(WindowsSdkDir)\include\km;..\..\include;..\..\include\xen;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>__MODULE__="XEN";POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>__MODULE__="XEN";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <WarningLevel>EnableAllWarnings</WarningLevel> <DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings> <MultiProcessorCompilation>true</MultiProcessorCompilation> @@ -45,7 +45,7 @@ </ResourceCompile> <Link> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> - <AdditionalDependencies>$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>../../src/xen/xen.def</ModuleDefinitionFile> <EnableCOMDATFolding>false</EnableCOMDATFolding> </Link> diff --git a/vs2013/xenbus/xenbus.vcxproj b/vs2013/xenbus/xenbus.vcxproj index eb476a9..ca486c9 100644 --- a/vs2013/xenbus/xenbus.vcxproj +++ b/vs2013/xenbus/xenbus.vcxproj @@ -33,7 +33,7 @@ <Inputs>..\..\src\xenbus.inf</Inputs> </CustomBuildStep> <ClCompile> - <PreprocessorDefinitions>__MODULE__="XENBUS";POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>__MODULE__="XENBUS";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>$(WindowsSdkDir)\include\km;..\..\include;..\..\include\xen;..\..\src\common;</AdditionalIncludeDirectories> <WarningLevel>EnableAllWarnings</WarningLevel> <DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings> @@ -45,7 +45,7 @@ </ResourceCompile> <Link> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> - <AdditionalDependencies>$(ProjectDir)..\$(ConfigurationName)\$(Platform)\xen.lib;$(DDK_LIB_PATH)/libcntpr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(ProjectDir)..\$(ConfigurationName)\$(Platform)\xen.lib;$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies> <EnableCOMDATFolding>false</EnableCOMDATFolding> </Link> <Inf> diff --git a/vs2013/xenfilt/xenfilt.vcxproj b/vs2013/xenfilt/xenfilt.vcxproj index b7759a7..db4a437 100644 --- a/vs2013/xenfilt/xenfilt.vcxproj +++ b/vs2013/xenfilt/xenfilt.vcxproj @@ -25,7 +25,7 @@ </PropertyGroup> <ItemDefinitionGroup> <ClCompile> - <PreprocessorDefinitions>__MODULE__="XENFILT";POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>__MODULE__="XENFILT";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>$(WindowsSdkDir)\include\km;..\..\include;..\..\include\xen;..\..\src\common;</AdditionalIncludeDirectories> <WarningLevel>EnableAllWarnings</WarningLevel> <DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings> @@ -37,7 +37,7 @@ </ResourceCompile> <Link> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> - <AdditionalDependencies>$(ProjectDir)..\$(ConfigurationName)\$(Platform)\xen.lib;$(DDK_LIB_PATH)/libcntpr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(ProjectDir)..\$(ConfigurationName)\$(Platform)\xen.lib;$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies> <EnableCOMDATFolding>false</EnableCOMDATFolding> </Link> <Inf> -- 2.1.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |