diff -ruN ../win-pvdrivers.hg/xenpci/evtchn.c xenpci/evtchn.c --- ../win-pvdrivers.hg/xenpci/evtchn.c 2011-02-26 20:43:12.000000000 +0800 +++ xenpci/evtchn.c 2011-02-26 20:44:33.000000000 +0800 @@ -154,50 +154,38 @@ switch (ev_action->type) { case EVT_ACTION_TYPE_NORMAL: - //KdPrint((__DRIVER_NAME " EVT_ACTION_TYPE_NORMAL port = %d\n", port)); + //KdPrint((__DRIVER_NAME " EVT_ACTION_TYPE_NORMAL\n")); ev_action->ServiceRoutine(ev_action->ServiceContext); break; case EVT_ACTION_TYPE_IRQ: - //KdPrint((__DRIVER_NAME " EVT_ACTION_TYPE_IRQ port = %d\n", port)); + //KdPrint((__DRIVER_NAME " EVT_ACTION_TYPE_IRQ\n")); synch_set_bit(evt_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[pcpu][evt_word]); deferred = TRUE; break; case EVT_ACTION_TYPE_DPC: - //KdPrint((__DRIVER_NAME " EVT_ACTION_TYPE_DPC port = %d\n", port)); + //KdPrint((__DRIVER_NAME " EVT_ACTION_TYPE_DPC\n")); KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL); break; case EVT_ACTION_TYPE_SUSPEND: KdPrint((__DRIVER_NAME " EVT_ACTION_TYPE_SUSPEND\n")); for (i = 0; i < ARRAY_SIZE(xpdd->evtchn_pending_pvt[pcpu]); i++) { - if (!(xpdd->ev_actions[i].flags & EVT_ACTION_FLAGS_NO_SUSPEND)) + if (xpdd->ev_actions[i].type == EVT_ACTION_TYPE_IRQ) { - switch(xpdd->ev_actions[i].type) - { - case EVT_ACTION_TYPE_IRQ: - { - int suspend_bit = i & (BITS_PER_LONG - 1); - int suspend_word = i >> BITS_PER_LONG_SHIFT; - synch_set_bit(suspend_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[pcpu][suspend_word]); - } - break; - case EVT_ACTION_TYPE_NORMAL: - if (xpdd->ev_actions[i].ServiceRoutine) - { - xpdd->ev_actions[i].ServiceRoutine(xpdd->ev_actions[i].ServiceContext); - } - break; - case EVT_ACTION_TYPE_DPC: - KeInsertQueueDpc(&xpdd->ev_actions[i].Dpc, NULL, NULL); - break; - } + int suspend_bit = i & (BITS_PER_LONG - 1); + int suspend_word = i >> BITS_PER_LONG_SHIFT; + synch_set_bit(suspend_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[pcpu][suspend_word]); + } + else if (xpdd->ev_actions[i].type == EVT_ACTION_TYPE_NORMAL && xpdd->ev_actions[i].ServiceRoutine) + { + xpdd->ev_actions[i].ServiceRoutine(xpdd->ev_actions[i].ServiceContext); } } KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL); deferred = TRUE; break; default: - KdPrint((__DRIVER_NAME " Unhandled Event!!! port=%d\n", port)); + KdPrint((__DRIVER_NAME " Unhandled Event!!!\n")); break; } } @@ -235,7 +223,7 @@ } NTSTATUS -EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags) +EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext) { PXENPCI_DEVICE_DATA xpdd = Context; ev_action_t *action = &xpdd->ev_actions[Port]; @@ -251,7 +239,6 @@ xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine; xpdd->ev_actions[Port].ServiceContext = ServiceContext; xpdd->ev_actions[Port].xpdd = xpdd; - xpdd->ev_actions[Port].flags = flags; KeMemoryBarrier(); xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_NORMAL; @@ -263,7 +250,7 @@ } NTSTATUS -EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags) +EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext) { PXENPCI_DEVICE_DATA xpdd = Context; ev_action_t *action = &xpdd->ev_actions[Port]; @@ -279,7 +266,6 @@ xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine; xpdd->ev_actions[Port].ServiceContext = ServiceContext; xpdd->ev_actions[Port].xpdd = xpdd; - xpdd->ev_actions[Port].flags = flags; KeMemoryBarrier(); // make sure that the new service routine is only called once the context is set up InterlockedExchange((volatile LONG *)&action->type, EVT_ACTION_TYPE_DPC); @@ -291,7 +277,7 @@ } NTSTATUS -EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description, ULONG flags) +EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description) { PXENPCI_DEVICE_DATA xpdd = Context; ev_action_t *action = &xpdd->ev_actions[Port]; @@ -309,8 +295,7 @@ KeMemoryBarrier(); xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_IRQ; RtlStringCbCopyA(xpdd->ev_actions[Port].description, 128, description); - xpdd->ev_actions[Port].flags = flags; - + EvtChn_Unmask(Context, Port); FUNCTION_EXIT(); @@ -461,7 +446,7 @@ KeInitializeEvent(&xpdd->pdo_suspend_event, SynchronizationEvent, FALSE); xpdd->pdo_event_channel = EvtChn_AllocIpi(xpdd, 0); - EvtChn_BindDpc(xpdd, xpdd->pdo_event_channel, EvtChn_PdoEventChannelDpc, xpdd, EVT_ACTION_FLAGS_DEFAULT); + EvtChn_BindDpc(xpdd, xpdd->pdo_event_channel, EvtChn_PdoEventChannelDpc, xpdd); xpdd->ev_actions[xpdd->pdo_event_channel].type = EVT_ACTION_TYPE_SUSPEND; /* override dpc type */ KdPrint((__DRIVER_NAME " pdo_event_channel = %d\n", xpdd->pdo_event_channel)); diff -ruN ../win-pvdrivers.hg/xenpci/getphyinfo.c xenpci/getphyinfo.c --- ../win-pvdrivers.hg/xenpci/getphyinfo.c 1970-01-01 08:00:00.000000000 +0800 +++ xenpci/getphyinfo.c 2011-02-26 20:44:33.000000000 +0800 @@ -0,0 +1,348 @@ +#include "getphyinfo.h" +#include + +//copy from the "xenpci.h" +#define XENPCI_POOL_TAG (ULONG) 'XenP' + +typedef struct _SYSTEM_PERFORMANCE_INFORMATION{ + LARGE_INTEGER IdleTime; + LARGE_INTEGER ReadTransferCount; + LARGE_INTEGER WriteTransferCount; + LARGE_INTEGER OtherTransferCount; + ULONG ReadOperationCount; + ULONG WriteOperationCount; + ULONG OtherOperationCount; + ULONG AvailablePages; + ULONG TotalCommittedPages; + ULONG TotalCommitLimit; + ULONG PeakCommitment; + ULONG PageFaults; + ULONG WriteCopyFaults; + ULONG TransitionFaults; + ULONG Reserved1; + ULONG DemandZeroFaults; + ULONG PagesRead; + ULONG PageReadIos; + ULONG Reserved2[2]; + ULONG PagefilePagesWritten; + ULONG PagefilePageWriteIos; + ULONG MappedFilePagesWritten; + ULONG MappedFilePageWriteIos; + ULONG PagedPoolUsage; + ULONG NonPagedPoolUsage; + ULONG PagedPoolAllocs; + ULONG PagedPoolFrees; + ULONG NonPagedPoolAllocs; + ULONG NonPagedPoolFrees; + ULONG TotalFreeSystemPtes; + ULONG SystemCodePage; + ULONG TotalSystemDriverPages; + ULONG TotalSystemCodePages; + ULONG SmallNonPagedLookasideListAllocateHits; + ULONG SmallPagedLookasideListAllocateHits; + ULONG Reserved3; + ULONG MmSystemCachePage; + ULONG PagedPoolPage; + ULONG SystemDriverPage; + ULONG FastReadNoWait; + ULONG FastReadWait; + ULONG FastReadResourceMiss; + ULONG FastReadNotPossible; + ULONG FastMdlReadNoWait; + ULONG FastMdlReadWait; + ULONG FastMdlReadResourceMiss; + ULONG FastMdlReadNotPossible; + ULONG MapDataNoWait; + ULONG MapDataWait; + ULONG MapDataNoWaitMiss; + ULONG MapDataWaitMiss; + ULONG PinMappedDataCount; + ULONG PinReadNoWait; + ULONG PinReadWait; + ULONG PinReadNoWaitMiss; + ULONG PinReadWaitMiss; + ULONG CopyReadNoWait; + ULONG CopyReadWait; + ULONG CopyReadNoWaitMiss; + ULONG CopyReadWaitMiss; + ULONG MdlReadNoWait; + ULONG MdlReadWait; + ULONG MdlReadNoWaitMiss; + ULONG MdlReadWaitMiss; + ULONG ReadAheadIos; + ULONG LazyWriteIos; + ULONG LazyWritePages; + ULONG DataFlushes; + ULONG DataPages; + ULONG ContextSwitches; + ULONG FirstLevelTbFills; + ULONG SecondLevelTbFills; + ULONG SystemCalls; + } SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION; + +typedef struct _SYSTEM_BASIC_INFORMATION{ + ULONG Unknown; + ULONG MaximumIncrement; + ULONG PageSize; + ULONG NumberOfPhysicalPages; + ULONG LowestPhysicalPage; + ULONG HighestPhysicalPage; + ULONG AllocationGranularity; + ULONG_PTR LowestUserAddress; + ULONG_PTR HighestUserAddress; + ULONG_PTR ActiveProcessors; + CCHAR NumberProcessors; + }SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION; + + +typedef enum _SYSTEM_INFORMATION_CLASS { + SystemBasicInformation, // 0 Y N + SystemProcessorInformation, // 1 Y N + SystemPerformanceInformation, // 2 Y N + SystemTimeOfDayInformation, // 3 Y N + SystemNotImplemented1, // 4 Y N + SystemProcessesAndThreadsInformation, // 5 Y N + SystemCallCounts, // 6 Y N + SystemConfigurationInformation, // 7 Y N + SystemProcessorTimes, // 8 Y N + SystemGlobalFlag, // 9 Y Y + SystemNotImplemented2, // 10 Y N + SystemModuleInformation, // 11 Y N + SystemLockInformation, // 12 Y N + SystemNotImplemented3, // 13 Y N + SystemNotImplemented4, // 14 Y N + SystemNotImplemented5, // 15 Y N + SystemHandleInformation, // 16 Y N + SystemObjectInformation, // 17 Y N + SystemPagefileInformation, // 18 Y N + SystemInstructionEmulationCounts, // 19 Y N + SystemInvalidInfoClass1, // 20 + SystemCacheInformation, // 21 Y Y + SystemPoolTagInformation, // 22 Y N + SystemProcessorStatistics, // 23 Y N + SystemDpcInformation, // 24 Y Y + SystemNotImplemented6, // 25 Y N + SystemLoadImage, // 26 N Y + SystemUnloadImage, // 27 N Y + SystemTimeAdjustment, // 28 Y Y + SystemNotImplemented7, // 29 Y N + SystemNotImplemented8, // 30 Y N + SystemNotImplemented9, // 31 Y N + SystemCrashDumpInformation, // 32 Y N + SystemExceptionInformation, // 33 Y N + SystemCrashDumpStateInformation, // 34 Y Y/N + SystemKernelDebuggerInformation, // 35 Y N + SystemContextSwitchInformation, // 36 Y N + SystemRegistryQuotaInformation, // 37 Y Y + SystemLoadAndCallImage, // 38 N Y + SystemPrioritySeparation, // 39 N Y + SystemNotImplemented10, // 40 Y N + SystemNotImplemented11, // 41 Y N + SystemInvalidInfoClass2, // 42 + SystemInvalidInfoClass3, // 43 + SystemTimeZoneInformation, // 44 Y N + SystemLookasideInformation, // 45 Y N + SystemSetTimeSlipEvent, // 46 N Y + SystemCreateSession, // 47 N Y + SystemDeleteSession, // 48 N Y + SystemInvalidInfoClass4, // 49 + SystemRangeStartInformation, // 50 Y N + SystemVerifierInformation, // 51 Y Y + SystemAddVerifier, // 52 N Y + SystemSessionProcessesInformation // 53 Y N +} SYSTEM_INFORMATION_CLASS; + + + +typedef enum { + StateInitialized, + StateReady, + StateRunning, + StateStandby, + StateTerminated, + StateWait, + StateTransition, + StateUnknown +} THREAD_STATE; + +typedef struct _SYSTEM_THREADS { + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER CreateTime; + ULONG WaitTime; + PVOID StartAddress; + CLIENT_ID ClientId; + KPRIORITY Priority; + KPRIORITY BasePriority; + ULONG ContextSwitchCount; + THREAD_STATE State; + KWAIT_REASON WaitReason; +} SYSTEM_THREADS, *PSYSTEM_THREADS; + +#if defined(_WIN64) + +/* + the struct has been changed to avoid error! +*/ +typedef struct _VM_COUNTERSEX { + ULONGLONG PeakVirtualSize; // used to be ULONG + ULONGLONG VirtualSize; // used to be ULONG + ULONG PageFaultCount; // used to be ULONG + ULONGLONG PeakWorkingSetSize; // used to be ULONG + ULONGLONG WorkingSetSize; // used to be ULONG + ULONGLONG QuotaPeakPagedPoolUsage; // used to be ULONG + ULONGLONG QuotaPagedPoolUsage; // used to be ULONG + ULONGLONG QuotaPeakNonPagedPoolUsage; // used to be ULONG + ULONGLONG QuotaNonPagedPoolUsage; // used to be ULONG + ULONGLONG PagefileUsage; // used to be ULONG + ULONGLONG PeakPagefileUsage; // used to be ULONG + ULONGLONG PrivateByte; // add by pengfei.zhangpf +} VM_COUNTERSEX, *PVM_COUNTERSEX; + +typedef struct _SYSTEM_PROCESSES { + ULONG NextEntryDelta; + ULONG ThreadCount; + ULONG Reserved1[6]; + LARGE_INTEGER CreateTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; + UNICODE_STRING ProcessName; + KPRIORITY BasePriority; + ULONGLONG ProcessId; // used to be ULONG + ULONGLONG InheritedFromProcessId; // used to be ULONG + ULONGLONG HandleCount; // used to be ULONG + ULONG Reserved2[2]; + VM_COUNTERSEX VmCounters; + IO_COUNTERS IoCounters; + SYSTEM_THREADS Threads[1]; +} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES; + +#else +typedef struct _VM_COUNTERSEX { + ULONG PeakVirtualSize; + ULONG VirtualSize; + ULONG PageFaultCount; + ULONG PeakWorkingSetSize; + ULONG WorkingSetSize; + ULONG QuotaPeakPagedPoolUsage; + ULONG QuotaPagedPoolUsage; + ULONG QuotaPeakNonPagedPoolUsage; + ULONG QuotaNonPagedPoolUsage; + ULONG PagefileUsage; + ULONG PeakPagefileUsage; + ULONG PrivateByte; // add by pengfei.zhangpf +} VM_COUNTERSEX, *PVM_COUNTERSEX; + +typedef struct _SYSTEM_PROCESSES { + ULONG NextEntryDelta; + ULONG ThreadCount; + ULONG Reserved1[6]; + LARGE_INTEGER CreateTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; + UNICODE_STRING ProcessName; + KPRIORITY BasePriority; + ULONG ProcessId; + ULONG InheritedFromProcessId; + ULONG HandleCount; + ULONG Reserved2[2]; + VM_COUNTERSEX VmCounters; + IO_COUNTERS IoCounters; + SYSTEM_THREADS Threads[1]; +} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES; +#endif + +#define DEF_BUF_SIZE 65536 + +NTSYSAPI + NTSTATUS + NTAPI + NtQuerySystemInformation( + IN SYSTEM_INFORMATION_CLASS SystemInformationClass, + OUT PVOID SystemInformation, + IN ULONG SystemInformationLength, + OUT PULONG ReturnLength OPTIONAL ); + +NTSTATUS NTAPI +PvGlobalMemoryStatus(PVOID pBuffer) +{ + LPMEMORYSTATUS pBufferXsMem; + SYSTEM_BASIC_INFORMATION BaseCachedSysInfo; + SYSTEM_PERFORMANCE_INFORMATION PerformanceInfo; + ULONG uSizeSysInfo; + ULONGLONG totalCommitSize; + NTSTATUS status; + PVOID pBufferSysMem; + PSYSTEM_PROCESSES pInfo; + + pBufferXsMem = (LPMEMORYSTATUS)pBuffer; + + status = NtQuerySystemInformation(SystemBasicInformation, + &BaseCachedSysInfo, + sizeof(BaseCachedSysInfo), + NULL); + if (!NT_SUCCESS(status)) + return status; + + /* Query performance information */ + status = NtQuerySystemInformation(SystemPerformanceInformation, + &PerformanceInfo, + sizeof(PerformanceInfo), + NULL); + if (!NT_SUCCESS(status)) + return status; + + pBufferXsMem->totalPhys = BaseCachedSysInfo.NumberOfPhysicalPages * BaseCachedSysInfo.PageSize; + + /* Now save available physical memory */ + pBufferXsMem->MemFree = (PerformanceInfo.AvailablePages * BaseCachedSysInfo.PageSize) >> 10; + + uSizeSysInfo = DEF_BUF_SIZE; + + do{ + pBufferSysMem = ExAllocatePoolWithTag(NonPagedPool, uSizeSysInfo, XENPCI_POOL_TAG); + if(pBufferSysMem == NULL) + return status; + + status = NtQuerySystemInformation(SystemProcessesAndThreadsInformation, pBufferSysMem, uSizeSysInfo, NULL); + + if (!NT_SUCCESS(status)) + { + if (status == STATUS_INFO_LENGTH_MISMATCH) + { + uSizeSysInfo += DEF_BUF_SIZE ; + ExFreePoolWithTag(pBufferSysMem, XENPCI_POOL_TAG); + continue; + } + else + { + ExFreePoolWithTag(pBufferSysMem, XENPCI_POOL_TAG); + return STATUS_SEVERITY_ERROR; + } + } + else + break; + + }while(!NT_SUCCESS(status));/* Query process information */ + + KdPrint(("xenpci""cbffer:------%d\n", uSizeSysInfo)); + pInfo = (PSYSTEM_PROCESSES)pBufferSysMem; + totalCommitSize = 0; + + for (;;) { + + if (pInfo -> ProcessId != 0) + totalCommitSize += (pInfo->VmCounters).PagefileUsage; + + if (pInfo->NextEntryDelta == 0) + break; + + pInfo = (PSYSTEM_PROCESSES)(((PUCHAR)pInfo) + pInfo->NextEntryDelta); + } + + pBufferXsMem->Committed_AS =(totalCommitSize >>10); + ExFreePoolWithTag(pBufferSysMem, XENPCI_POOL_TAG); + + return 0; +} + diff -ruN ../win-pvdrivers.hg/xenpci/getphyinfo.h xenpci/getphyinfo.h --- ../win-pvdrivers.hg/xenpci/getphyinfo.h 1970-01-01 08:00:00.000000000 +0800 +++ xenpci/getphyinfo.h 2011-02-26 20:44:33.000000000 +0800 @@ -0,0 +1,28 @@ +#if !defined(_GETPHYINFO_H_) +#define _GETPHYINFO_H_ + +#define DDKAPI +#include +#include +#define NTSTRSAFE_LIB +#include +#include + +/* + if meminfo changed value less than BOUND_VALUE, no xenstore updated + default 5M +*/ +#define BOUND_VALUE 5120 +#define CHANGED(x,y) (((x)>(y)+BOUND_VALUE)||((y)>(x)+BOUND_VALUE)) + +typedef struct _MEMORYSTATUS { + ULONG totalPhys; + ULONG MemCur; + ULONG MemFree; + ULONGLONG Committed_AS; +} MEMORYSTATUS, *LPMEMORYSTATUS; + +NTSTATUS NTAPI +PvGlobalMemoryStatus(PVOID pBuffer); + +#endif diff -ruN ../win-pvdrivers.hg/xenpci/gnttbl.c xenpci/gnttbl.c --- ../win-pvdrivers.hg/xenpci/gnttbl.c 2011-02-26 20:43:12.000000000 +0800 +++ xenpci/gnttbl.c 2011-02-26 20:44:33.000000000 +0800 @@ -27,12 +27,12 @@ UNREFERENCED_PARAMETER(tag); #if DBG - if (xpdd->gnttbl_tag[ref] != tag) - KdPrint((__DRIVER_NAME " Grant Entry %d for %.4s doesn't match %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttbl_tag[ref])); - ASSERT(xpdd->gnttbl_tag[ref] == tag); - xpdd->gnttbl_tag[ref] = 0; + if (xpdd->gnttab_tag[ref] != tag) + KdPrint((__DRIVER_NAME " Grant Entry %d for %.4s doesn't match %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttab_tag[ref])); + ASSERT(xpdd->gnttab_tag[ref] == tag); + xpdd->gnttab_tag[ref] = 0; #endif - stack_push(xpdd->gnttbl_ss, (PVOID)ref); + stack_push(xpdd->gnttab_ss, (PVOID)ref); } grant_ref_t @@ -44,17 +44,17 @@ UNREFERENCED_PARAMETER(tag); - if (!stack_pop(xpdd->gnttbl_ss, &ptr_ref)) + if (!stack_pop(xpdd->gnttab_ss, &ptr_ref)) { KdPrint((__DRIVER_NAME " No free grant refs\n")); return INVALID_GRANT_REF; } ref = (grant_ref_t)(ULONG_PTR)ptr_ref; #if DBG - if (xpdd->gnttbl_tag[ref]) - KdPrint((__DRIVER_NAME " Grant Entry %d for %.4s in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttbl_tag[ref])); - ASSERT(!xpdd->gnttbl_tag[ref]); - xpdd->gnttbl_tag[ref] = tag; + if (xpdd->gnttab_tag[ref]) + KdPrint((__DRIVER_NAME " Grant Entry %d for %.4s in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttab_tag[ref])); + ASSERT(!xpdd->gnttab_tag[ref]); + xpdd->gnttab_tag[ref] = tag; #endif return ref; @@ -67,19 +67,17 @@ struct xen_add_to_physmap xatp; unsigned int i = end_idx; - FUNCTION_ENTER(); /* Loop backwards, so that the first hypercall has the largest index, ensuring that the table will grow only once. */ do { xatp.domid = DOMID_SELF; xatp.idx = i; xatp.space = XENMAPSPACE_grant_table; - xatp.gpfn = (xen_pfn_t)MmGetMdlPfnArray(xpdd->gnttbl_mdl)[i]; + xatp.gpfn = (xen_pfn_t)(xpdd->gnttab_table_physical.QuadPart >> PAGE_SHIFT) + i; if (HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp)) { - KdPrint((__DRIVER_NAME " *** ERROR MAPPING FRAME %d ***\n", i)); + KdPrint((__DRIVER_NAME " ***ERROR MAPPING FRAME***\n")); } } while (i-- > start_idx); - FUNCTION_EXIT(); return 0; } @@ -102,24 +100,24 @@ if (ref == INVALID_GRANT_REF) return ref; - ASSERT(xpdd->gnttbl_tag[ref] == tag); + ASSERT(xpdd->gnttab_tag[ref] == tag); - xpdd->gnttbl_table[ref].frame = frame; - xpdd->gnttbl_table[ref].domid = domid; + xpdd->gnttab_table[ref].frame = frame; + xpdd->gnttab_table[ref].domid = domid; - if (xpdd->gnttbl_table[ref].flags) + if (xpdd->gnttab_table[ref].flags) { #if DBG - KdPrint((__DRIVER_NAME " Grant Entry %d for %.4s still in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttbl_tag[ref])); + KdPrint((__DRIVER_NAME " Grant Entry %d for %.4s still in use by %.4s\n", ref, (PUCHAR)&tag, (PUCHAR)&xpdd->gnttab_tag[ref])); #else KdPrint((__DRIVER_NAME " Grant Entry %d for %.4s still in use\n", ref, (PUCHAR)&tag)); #endif } - ASSERT(!xpdd->gnttbl_table[ref].flags); + ASSERT(!xpdd->gnttab_table[ref].flags); KeMemoryBarrier(); readonly *= GTF_readonly; - xpdd->gnttbl_table[ref].flags = GTF_permit_access | (uint16_t)readonly; + xpdd->gnttab_table[ref].flags = GTF_permit_access | (uint16_t)readonly; return ref; } @@ -135,9 +133,9 @@ unsigned short flags, nflags; ASSERT(ref != INVALID_GRANT_REF); - ASSERT(xpdd->gnttbl_tag[ref] == tag); + ASSERT(xpdd->gnttab_tag[ref] == tag); - nflags = xpdd->gnttbl_table[ref].flags; + nflags = xpdd->gnttab_table[ref].flags; do { if ((flags = nflags) & (GTF_reading|GTF_writing)) { @@ -145,7 +143,7 @@ return FALSE; } } while ((nflags = InterlockedCompareExchange16( - (volatile SHORT *)&xpdd->gnttbl_table[ref].flags, 0, flags)) != flags); + (volatile SHORT *)&xpdd->gnttab_table[ref].flags, 0, flags)) != flags); if (!keepref) GntTbl_PutRef(Context, ref, tag); @@ -185,48 +183,28 @@ grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t))); KdPrint((__DRIVER_NAME " grant_entries = %d\n", grant_entries)); #if DBG - xpdd->gnttbl_tag = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(ULONG), XENPCI_POOL_TAG); - RtlZeroMemory(xpdd->gnttbl_tag, grant_entries * sizeof(ULONG)); - xpdd->gnttbl_tag_copy = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(ULONG), XENPCI_POOL_TAG); + xpdd->gnttab_tag = ExAllocatePoolWithTag(NonPagedPool, grant_entries * sizeof(ULONG), XENPCI_POOL_TAG); + RtlZeroMemory(xpdd->gnttab_tag, grant_entries * sizeof(ULONG)); #endif - xpdd->gnttbl_table_copy = ExAllocatePoolWithTag(NonPagedPool, xpdd->grant_frames * PAGE_SIZE, XENPCI_POOL_TAG); - ASSERT(xpdd->gnttbl_table_copy); // lazy - xpdd->gnttbl_table = ExAllocatePoolWithTag(NonPagedPool, xpdd->grant_frames * PAGE_SIZE, XENPCI_POOL_TAG); - ASSERT(xpdd->gnttbl_table); // lazy - /* dom0 crashes if we allocate the wrong amount of memory here! */ - xpdd->gnttbl_mdl = IoAllocateMdl(xpdd->gnttbl_table, xpdd->grant_frames * PAGE_SIZE, FALSE, FALSE, NULL); - ASSERT(xpdd->gnttbl_mdl); // lazy - MmBuildMdlForNonPagedPool(xpdd->gnttbl_mdl); - - /* make some holes for the grant pages to fill in */ - for (i = 0; i < (int)xpdd->grant_frames; i++) - { - struct xen_memory_reservation reservation; - xen_pfn_t pfn; - ULONG ret; - - reservation.address_bits = 0; - reservation.extent_order = 0; - reservation.domid = DOMID_SELF; - reservation.nr_extents = 1; - #pragma warning(disable: 4127) /* conditional expression is constant */ - pfn = (xen_pfn_t)MmGetMdlPfnArray(xpdd->gnttbl_mdl)[i]; - KdPrint((__DRIVER_NAME " pfn = %x\n", (ULONG)pfn)); - set_xen_guest_handle(reservation.extent_start, &pfn); - - KdPrint((__DRIVER_NAME " Calling HYPERVISOR_memory_op - pfn = %x\n", (ULONG)pfn)); - ret = HYPERVISOR_memory_op(xpdd, XENMEM_decrease_reservation, &reservation); - KdPrint((__DRIVER_NAME " decreased %d pages for grant table frame %d\n", ret, i)); + xpdd->gnttab_table_copy = ExAllocatePoolWithTag(NonPagedPool, xpdd->grant_frames * PAGE_SIZE, XENPCI_POOL_TAG); + ASSERT(xpdd->gnttab_table_copy); // lazy + xpdd->gnttab_table_physical = XenPci_AllocMMIO(xpdd, PAGE_SIZE * xpdd->grant_frames); + xpdd->gnttab_table = MmMapIoSpace(xpdd->gnttab_table_physical, PAGE_SIZE * xpdd->grant_frames, MmNonCached); + if (!xpdd->gnttab_table) + { + KdPrint((__DRIVER_NAME " Error Mapping Grant Table Shared Memory\n")); + // this should be a show stopper... + return; } - stack_new(&xpdd->gnttbl_ss, grant_entries); + stack_new(&xpdd->gnttab_ss, grant_entries); for (i = NR_RESERVED_ENTRIES; i < grant_entries; i++) - stack_push(xpdd->gnttbl_ss, (PVOID)i); + stack_push(xpdd->gnttab_ss, (PVOID)i); GntTbl_Map(xpdd, 0, xpdd->grant_frames - 1); - RtlZeroMemory(xpdd->gnttbl_table, PAGE_SIZE * xpdd->grant_frames); + RtlZeroMemory(xpdd->gnttab_table, PAGE_SIZE * xpdd->grant_frames); FUNCTION_EXIT(); } @@ -234,54 +212,7 @@ VOID GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd) { - #if DBG - int grant_entries; - #endif - int i; - - FUNCTION_ENTER(); - - /* copy some grant refs and switch to an alternate freelist, but only on hiber */ - if (KeGetCurrentIrql() <= DISPATCH_LEVEL) - { - KdPrint((__DRIVER_NAME " backing up grant ref stack\n")); - for (i = 0; i < HIBER_GREF_COUNT; i++) - { - xpdd->hiber_grefs[i] = INVALID_GRANT_REF; - } - for (i = 0; i < HIBER_GREF_COUNT; i++) - { - if ((xpdd->hiber_grefs[i] = GntTbl_GetRef(xpdd, (ULONG)'HIBR')) == INVALID_GRANT_REF) - break; - } - KdPrint((__DRIVER_NAME " %d grant refs reserved\n", i)); - xpdd->gnttbl_ss_copy = xpdd->gnttbl_ss; - stack_new(&xpdd->gnttbl_ss, HIBER_GREF_COUNT); - } - else - { - xpdd->gnttbl_ss_copy = NULL; - } - - memcpy(xpdd->gnttbl_table_copy, xpdd->gnttbl_table, xpdd->grant_frames * PAGE_SIZE); - #if DBG - /* even though gnttbl_tag is actually preserved, it is used by the dump driver so must be restored to exactly the same state as it was on suspend */ - grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t))); - memcpy(xpdd->gnttbl_tag_copy, xpdd->gnttbl_tag, grant_entries * sizeof(ULONG)); - #endif - - /* put the grant entries on the new freelist, after copying the tables above */ - if (KeGetCurrentIrql() <= DISPATCH_LEVEL) - { - for (i = 0; i < HIBER_GREF_COUNT; i++) - { - if (xpdd->hiber_grefs[i] == INVALID_GRANT_REF) - break; - GntTbl_PutRef(xpdd, xpdd->hiber_grefs[i], (ULONG)'HIBR'); - } - } - - FUNCTION_EXIT(); + memcpy(xpdd->gnttab_table_copy, xpdd->gnttab_table, xpdd->grant_frames * PAGE_SIZE); } VOID @@ -289,58 +220,15 @@ { ULONG new_grant_frames; ULONG result; - int i; - #if DBG - int grant_entries; - #endif - + FUNCTION_ENTER(); - - for (i = 0; i < (int)xpdd->grant_frames; i++) - { - struct xen_memory_reservation reservation; - xen_pfn_t pfn; - ULONG ret; - - reservation.address_bits = 0; - reservation.extent_order = 0; - reservation.domid = DOMID_SELF; - reservation.nr_extents = 1; - #pragma warning(disable: 4127) /* conditional expression is constant */ - pfn = (xen_pfn_t)MmGetMdlPfnArray(xpdd->gnttbl_mdl)[i]; - KdPrint((__DRIVER_NAME " pfn = %x\n", (ULONG)pfn)); - set_xen_guest_handle(reservation.extent_start, &pfn); - - KdPrint((__DRIVER_NAME " Calling HYPERVISOR_memory_op - pfn = %x\n", (ULONG)pfn)); - ret = HYPERVISOR_memory_op(xpdd, XENMEM_decrease_reservation, &reservation); - KdPrint((__DRIVER_NAME " decreased %d pages for grant table frame %d\n", ret, i)); - } - + new_grant_frames = GntTbl_QueryMaxFrames(xpdd); KdPrint((__DRIVER_NAME " new_grant_frames = %d\n", new_grant_frames)); ASSERT(new_grant_frames >= xpdd->grant_frames); // lazy result = GntTbl_Map(xpdd, 0, xpdd->grant_frames - 1); KdPrint((__DRIVER_NAME " GntTbl_Map result = %d\n", result)); - memcpy(xpdd->gnttbl_table, xpdd->gnttbl_table_copy, xpdd->grant_frames * PAGE_SIZE); - #if DBG - grant_entries = min(NR_GRANT_ENTRIES, (xpdd->grant_frames * PAGE_SIZE / sizeof(grant_entry_t))); - memcpy(xpdd->gnttbl_tag, xpdd->gnttbl_tag_copy, grant_entries * sizeof(ULONG)); - #endif - - /* switch back and put the hiber grants back again */ - if (xpdd->gnttbl_ss_copy) - { - KdPrint((__DRIVER_NAME " restoring grant ref stack\n")); - stack_delete(xpdd->gnttbl_ss, NULL, NULL); - xpdd->gnttbl_ss = xpdd->gnttbl_ss_copy; - for (i = 0; i < HIBER_GREF_COUNT; i++) - { - if (xpdd->hiber_grefs[i] == INVALID_GRANT_REF) - break; - GntTbl_PutRef(xpdd, xpdd->hiber_grefs[i], (ULONG)'HIBR'); - } - xpdd->gnttbl_ss_copy = NULL; - } - + memcpy(xpdd->gnttab_table, xpdd->gnttab_table_copy, xpdd->grant_frames * PAGE_SIZE); + FUNCTION_EXIT(); } diff -ruN ../win-pvdrivers.hg/xenpci/hypercall.h xenpci/hypercall.h --- ../win-pvdrivers.hg/xenpci/hypercall.h 2011-02-26 20:43:12.000000000 +0800 +++ xenpci/hypercall.h 2011-02-26 20:44:33.000000000 +0800 @@ -55,6 +55,7 @@ a.domid = DOMID_SELF; a.index = hvm_param; a.value = value; + //a.value = via; retval = HYPERVISOR_hvm_op(xpdd, HVMOP_set_param, &a); KdPrint((__DRIVER_NAME " HYPERVISOR_hvm_op retval = %d\n", retval)); FUNCTION_EXIT(); diff -ruN ../win-pvdrivers.hg/xenpci/memoryinfothread.c xenpci/memoryinfothread.c --- ../win-pvdrivers.hg/xenpci/memoryinfothread.c 1970-01-01 08:00:00.000000000 +0800 +++ xenpci/memoryinfothread.c 2011-02-26 20:44:33.000000000 +0800 @@ -0,0 +1,48 @@ +#include "xenpci.h" +#include "xenpod.h" +#include "xenpci_sleep.h" +#include "getphyinfo.h" +#define BALLOON_MEMINFO_PATH "memory/meminfo" + +VOID PvMemoryInfoThreadProc(PVOID StartContext) +{ + PXENPCI_DEVICE_DATA xpdd = StartContext; + MEMORYSTATUS oldLpBuffer,lpBuffer; + ULONG changed ,first; + DWORD status; + FUNCTION_ENTER(); + first = 1; + oldLpBuffer.MemCur=0; + oldLpBuffer.MemFree=0; + oldLpBuffer.Committed_AS=0; + + for (;;) + { + status = PvGlobalMemoryStatus(&lpBuffer); + + /*if error, write status to xenstore for debug*/ + if (!NT_SUCCESS(status)){ + XenBus_Printf(xpdd, XBT_NIL, BALLOON_MEMINFO_PATH, + "Error:0x%x", status); + continue; + } + + lpBuffer.MemCur = xpdd->current_memory << 10; + changed = + first| + CHANGED(lpBuffer.MemCur, oldLpBuffer.MemCur)| + CHANGED(lpBuffer.MemFree, oldLpBuffer.MemFree)| + CHANGED(lpBuffer.Committed_AS, oldLpBuffer.Committed_AS); + + if(changed){ + XenBus_Printf(xpdd, XBT_NIL, BALLOON_MEMINFO_PATH, + "Current:%u,Free:%u,Commit:%u", + lpBuffer.MemCur, lpBuffer.MemFree, lpBuffer.Committed_AS); + oldLpBuffer = lpBuffer; + } + + first = 0; + PvWaitMicroSecond(1000 * 1000);/* 1 second*/ + } + //FUNCTION_EXIT(); +} diff -ruN ../win-pvdrivers.hg/xenpci/pv.diff xenpci/pv.diff --- ../win-pvdrivers.hg/xenpci/pv.diff 1970-01-01 08:00:00.000000000 +0800 +++ xenpci/pv.diff 2011-02-26 20:45:54.000000000 +0800 @@ -0,0 +1,258 @@ +diff -r b63f69bf9cf5 xenpci/sources +--- a/xenpci/sources Sat Oct 16 23:25:32 2010 +1100 ++++ b/xenpci/sources Sat Feb 26 20:45:54 2011 +0800 +@@ -19,4 +19,4 @@ + SOURCES=xenpci.rc xenpci.c xenpci_fdo.c xenpci_pdo.c evtchn.c \ + gnttbl.c xenbus.c memory.c xenpci_device_interface.c \ + xenbus_device_interface.c xenpci_highsync.c xenpci_patch_kernel.c \ +- xenpci_dbgprint.c ++ xenpci_dbgprint.c getphyinfo.c xenpci_sleep.c memoryinfothread.c +diff -r b63f69bf9cf5 xenpci/xenpci.h +--- a/xenpci/xenpci.h Sat Oct 16 23:25:32 2010 +1100 ++++ b/xenpci/xenpci.h Sat Feb 26 20:45:54 2011 +0800 +@@ -171,6 +171,12 @@ + struct xenstore_domain_interface *xen_store_interface; + + #define BALLOON_UNITS (1024 * 1024) /* 1MB */ ++ ++ /*meminfo thread*/ ++ PKTHREAD memory_thread; ++ KEVENT memory_event; ++ ++ BOOLEAN memory_shutdown; + PKTHREAD balloon_thread; + KEVENT balloon_event; + BOOLEAN balloon_shutdown; +diff -r b63f69bf9cf5 xenpci/xenpci_fdo.c +--- a/xenpci/xenpci_fdo.c Sat Oct 16 23:25:32 2010 +1100 ++++ b/xenpci/xenpci_fdo.c Sat Feb 26 20:45:54 2011 +0800 +@@ -1,4 +1,4 @@ +-/* ++ /* + PV Drivers for Windows Xen HVM Domains + Copyright (C) 2007 James Harper + +@@ -20,10 +20,14 @@ + #include "xenpci.h" + #include + #include ++#include "getphyinfo.h" ++#include "xenpod.h" ++#include "xenpci_sleep.h" + + #define SYSRQ_PATH "control/sysrq" + #define SHUTDOWN_PATH "control/shutdown" +-#define BALLOON_PATH "memory/target" ++#define BALLOON_TARGET_PATH "memory/target" ++#define BALLOON_WORKTIME_PATH "memory/worktime" + + /* Not really necessary but keeps PREfast happy */ + static EVT_WDF_WORKITEM XenPci_SuspendResume; +@@ -31,6 +35,8 @@ + static KSTART_ROUTINE XenPci_BalloonThreadProc; + #endif + ++extern KSTART_ROUTINE PvMemoryInfoThreadProc; ++ + static VOID + XenPci_MapHalThenPatchKernel(PXENPCI_DEVICE_DATA xpdd) + { +@@ -238,6 +244,11 @@ + ULONG ret; + int pfn_count; + ++#ifdef BALLOON_PATH_WORK_TIME ++ ULONG workbegintime; ++ ULONG workendtime; ++#endif ++ + FUNCTION_ENTER(); + + for(;;) +@@ -267,6 +278,11 @@ + KdPrint((__DRIVER_NAME " No change to memory\n")); + continue; + } ++ ++#ifdef BALLOON_PATH_WORK_TIME ++ PvGetTickCount(&workbegintime); ++#endif ++ + else if (xpdd->current_memory < new_target) + { + KdPrint((__DRIVER_NAME " Trying to take %d MB from Xen\n", new_target - xpdd->current_memory)); +@@ -277,6 +293,12 @@ + + pfn_count = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(mdl), MmGetMdlByteCount(mdl)); + pfns = ExAllocatePoolWithTag(NonPagedPool, pfn_count * sizeof(xen_pfn_t), XENPCI_POOL_TAG); ++ if(pfns == NULL){ ++ mdl->Next = head; ++ head = mdl; ++ break; ++ } ++ + /* sizeof(xen_pfn_t) may not be the same as PPFN_NUMBER */ + for (i = 0; i < pfn_count; i++) + pfns[i] = (xen_pfn_t)(MmGetMdlPfnArray(mdl)[i]); +@@ -289,10 +311,24 @@ + + KdPrint((__DRIVER_NAME " Calling HYPERVISOR_memory_op(XENMEM_populate_physmap) - pfn_count = %d\n", pfn_count)); + ret = HYPERVISOR_memory_op(xpdd, XENMEM_populate_physmap, &reservation); +- ExFreePoolWithTag(pfns, XENPCI_POOL_TAG); ++ + KdPrint((__DRIVER_NAME " populated %d pages\n", ret)); + /* TODO: what do we do if less than the required number of pages were populated??? can this happen??? */ ++ /* fixed! */ ++ if(ret < (ULONG)pfn_count){ ++ if(ret > 0){ ++ /* We hit the Xen hard limit: reprobe. */ ++ reservation.nr_extents = ret; ++ ret = HYPERVISOR_memory_op(xpdd, XENMEM_decrease_reservation, &reservation); ++ KdPrint((__DRIVER_NAME " decreased %d pages\n", ret)); ++ } ++ mdl->Next = head; ++ head = mdl; ++ ExFreePoolWithTag(pfns, XENPCI_POOL_TAG); ++ break; ++ } + ++ ExFreePoolWithTag(pfns, XENPCI_POOL_TAG); + MmFreePagesFromMdl(mdl); + ExFreePool(mdl); + xpdd->current_memory++; +@@ -334,6 +370,12 @@ + break; + } + pfns = ExAllocatePoolWithTag(NonPagedPool, pfn_count * sizeof(xen_pfn_t), XENPCI_POOL_TAG); ++ if(pfns == NULL){ ++ MmFreePagesFromMdl(mdl); ++ ExFreePool(mdl); ++ break; ++ } ++ + /* sizeof(xen_pfn_t) may not be the same as PPFN_NUMBER */ + for (i = 0; i < pfn_count; i++) + pfns[i] = (xen_pfn_t)(MmGetMdlPfnArray(mdl)[i]); +@@ -361,6 +403,11 @@ + } + } + } ++#ifdef BALLOON_PATH_WORK_TIME ++ PvGetTickCount(&workendtime); ++ XenBus_Printf(xpdd, XBT_NIL, BALLOON_PATH_WORK_TIME, "%u", workendtime - workbegintime); ++#endif ++ + } + //FUNCTION_EXIT(); + } +@@ -380,7 +427,7 @@ + + XenBus_StartTransaction(xpdd, &xbt); + +- XenBus_Read(xpdd, XBT_NIL, BALLOON_PATH, &value); ++ XenBus_Read(xpdd, XBT_NIL, BALLOON_TARGET_PATH, &value); + + if (value == NULL) + { +@@ -404,6 +451,7 @@ + FUNCTION_EXIT(); + } + ++ + static VOID + XenPci_Suspend0(PVOID context) + { +@@ -646,9 +694,9 @@ + xpdd->platform_mmio_flags = translated_descriptor->Flags; + break; + case CmResourceTypeInterrupt: +- xpdd->irq_level = (KIRQL)translated_descriptor->u.Interrupt.Level; +- xpdd->irq_vector = translated_descriptor->u.Interrupt.Vector; +- xpdd->irq_affinity = translated_descriptor->u.Interrupt.Affinity; ++ xpdd->irq_level = (KIRQL)translated_descriptor->u.Interrupt.Level; ++ xpdd->irq_vector = translated_descriptor->u.Interrupt.Vector; ++ xpdd->irq_affinity = translated_descriptor->u.Interrupt.Affinity; + xpdd->irq_mode = (translated_descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)?Latched:LevelSensitive; + xpdd->irq_number = raw_descriptor->u.Interrupt.Vector; + KdPrint((__DRIVER_NAME " irq_number = %03x\n", raw_descriptor->u.Interrupt.Vector)); +@@ -777,12 +825,15 @@ + NTSTATUS status = STATUS_SUCCESS; + PXENPCI_DEVICE_DATA xpdd = GetXpdd(device); + PCHAR response; +- char *value; + domid_t domid = DOMID_SELF; + ULONG ret; ++ ULONG totalram_bias; + xen_ulong_t *max_ram_page; + HANDLE thread_handle; +- ++ HANDLE memory_info_thread_handle; ++ XEN_POD_TARGET_T pod_target; ++ pod_target.domid = DOMID_SELF; ++ + UNREFERENCED_PARAMETER(previous_state); + + FUNCTION_ENTER(); +@@ -808,14 +859,21 @@ + + if (!xpdd->initial_memory) + { +- XenBus_Read(xpdd, XBT_NIL, BALLOON_PATH, &value); +- if (atoi(value) > 0) +- { +- xpdd->initial_memory = atoi(value) >> 10; /* convert to MB */ +- xpdd->current_memory = xpdd->initial_memory; +- xpdd->target_memory = xpdd->initial_memory; ++ MEMORYSTATUS lpBuffer; ++ PvGlobalMemoryStatus(&lpBuffer); ++ xpdd->initial_memory = (ULONG)(lpBuffer.totalPhys >> 10); /*convert to MB*/ ++ xpdd->current_memory = xpdd->initial_memory; ++ ++ ++ ret = HYPERVISOR_memory_op(xpdd, XENMEM_get_pod_target, &pod_target); ++ ++ totalram_bias = HYPERVISOR_memory_op(xpdd, ret != -ENOSYS && ret != 1 ++ ? XENMEM_maximum_reservation : XENMEM_current_reservation, ++ &pod_target.domid); ++ if ((ULONG)totalram_bias != -ENOSYS) { ++ xpdd->initial_memory = totalram_bias >> (20 - PAGE_SHIFT); ++ xpdd->current_memory = xpdd->initial_memory + 1; /*lase line convert to MB may lost some KB, just add 1M*/ + } +- KdPrint((__DRIVER_NAME " Initial Memory Value = %d (%s)\n", xpdd->initial_memory, value)); + KeInitializeEvent(&xpdd->balloon_event, SynchronizationEvent, FALSE); + xpdd->balloon_shutdown = FALSE; + status = PsCreateSystemThread(&thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, XenPci_BalloonThreadProc, xpdd); +@@ -826,8 +884,18 @@ + } + status = ObReferenceObjectByHandle(thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->balloon_thread, NULL); + ZwClose(thread_handle); ++ ++ /* start pci meminfo thread */ ++ status = PsCreateSystemThread(&memory_info_thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, PvMemoryInfoThreadProc, xpdd); ++ if (!NT_SUCCESS(status)) ++ { ++ KdPrint((__DRIVER_NAME " Could not start memory thread\n")); ++ return status; ++ } ++ status = ObReferenceObjectByHandle(memory_info_thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->memory_thread, NULL); ++ ZwClose(memory_info_thread_handle); + } +- response = XenBus_AddWatch(xpdd, XBT_NIL, BALLOON_PATH, XenPci_BalloonHandler, device); ++ response = XenBus_AddWatch(xpdd, XBT_NIL, BALLOON_TARGET_PATH, XenPci_BalloonHandler, device); + } + else + { +diff -r b63f69bf9cf5 xenpci/xenpci_pdo.c +--- a/xenpci/xenpci_pdo.c Sat Oct 16 23:25:32 2010 +1100 ++++ b/xenpci/xenpci_pdo.c Sat Feb 26 20:45:54 2011 +0800 +@@ -502,7 +502,9 @@ + { + /* it's possible that the workitems are blocked because the pagefile isn't available. Lets just re-read the backend value for now */ + XenPci_UpdateBackendState(device); +- remaining -= thiswait; ++ ++ // this code is commented because it can cause the VM waitting forever ++ //remaining -= thiswait; + if (remaining == 0) + { + KdPrint((__DRIVER_NAME " Timed out waiting for %d!\n", backend_state_response)); diff -ruN ../win-pvdrivers.hg/xenpci/sources xenpci/sources --- ../win-pvdrivers.hg/xenpci/sources 2011-02-26 20:43:12.000000000 +0800 +++ xenpci/sources 2011-02-26 20:44:33.000000000 +0800 @@ -19,4 +19,4 @@ SOURCES=xenpci.rc xenpci.c xenpci_fdo.c xenpci_pdo.c evtchn.c \ gnttbl.c xenbus.c memory.c xenpci_device_interface.c \ xenbus_device_interface.c xenpci_highsync.c xenpci_patch_kernel.c \ - xenpci_dbgprint.c + xenpci_dbgprint.c getphyinfo.c xenpci_sleep.c memoryinfothread.c diff -ruN ../win-pvdrivers.hg/xenpci/xenbus.c xenpci/xenbus.c --- ../win-pvdrivers.hg/xenpci/xenbus.c 2011-02-26 20:43:12.000000000 +0800 +++ xenpci/xenbus.c 2011-02-26 20:44:33.000000000 +0800 @@ -275,23 +275,21 @@ WDF_WORKITEM_CONFIG workitem_config; WDF_OBJECT_ATTRIBUTES workitem_attributes; WDFWORKITEM workitem; - ULONG rsp_prod; //FUNCTION_ENTER(); KeAcquireSpinLockAtDpcLevel(&xpdd->xb_ring_spinlock); - /* snapshot rsp_prod so it doesn't change while we are looking at it */ - while ((rsp_prod = xpdd->xen_store_interface->rsp_prod) != xpdd->xen_store_interface->rsp_cons) + while (xpdd->xen_store_interface->rsp_prod != xpdd->xen_store_interface->rsp_cons) { - KeMemoryBarrier(); /* make sure the data in the ring is valid */ if (!xpdd->xb_msg) { - if (rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(xsd_sockmsg_t)) + if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(xsd_sockmsg_t)) { //KdPrint((__DRIVER_NAME " +++ Message incomplete (not even a full header)\n")); break; } + KeMemoryBarrier(); memcpy_from_ring(xpdd->xen_store_interface->rsp, &msg, MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons), sizeof(xsd_sockmsg_t)); xpdd->xb_msg = ExAllocatePoolWithTag(NonPagedPool, sizeof(xsd_sockmsg_t) + msg.len, XENPCI_POOL_TAG); @@ -300,7 +298,8 @@ xpdd->xen_store_interface->rsp_cons += sizeof(xsd_sockmsg_t); } - msg_len = min(rsp_prod - xpdd->xen_store_interface->rsp_cons, sizeof(xsd_sockmsg_t) + xpdd->xb_msg->len - xpdd->xb_msg_offset); + msg_len = min(xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons, sizeof(xsd_sockmsg_t) + xpdd->xb_msg->len - xpdd->xb_msg_offset); + KeMemoryBarrier(); /* make sure the data in the ring is valid */ ASSERT(xpdd->xb_msg_offset + msg_len <= sizeof(xsd_sockmsg_t) + xpdd->xb_msg->len); memcpy_from_ring(xpdd->xen_store_interface->rsp, (PUCHAR)xpdd->xb_msg + xpdd->xb_msg_offset, @@ -359,7 +358,7 @@ pa_xen_store_interface.QuadPart = (ULONGLONG)xen_store_mfn << PAGE_SHIFT; xpdd->xen_store_interface = MmMapIoSpace(pa_xen_store_interface, PAGE_SIZE, MmNonCached); - EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd, EVT_ACTION_FLAGS_NO_SUSPEND); + EvtChn_BindDpc(xpdd, xpdd->xen_store_evtchn, XenBus_Dpc, xpdd); return STATUS_SUCCESS; } @@ -572,11 +571,10 @@ { if (xpdd->XenBus_WatchEntries[i].Active) { - KdPrint((__DRIVER_NAME " Adding watch for path = %s\n", xpdd->XenBus_WatchEntries[i].Path)); + //KdPrint((__DRIVER_NAME " Adding watch for path = %s\n", xpdd->XenBus_WatchEntries[i].Path)); XenBus_SendAddWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i); } } - FUNCTION_EXIT(); return STATUS_SUCCESS; @@ -667,7 +665,7 @@ if (i == MAX_WATCH_ENTRIES) { ExReleaseFastMutex(&xpdd->xb_watch_mutex); - KdPrint((__DRIVER_NAME " Watch not set for %s - can't remove\n", Path)); + KdPrint((__DRIVER_NAME " Watch not set - can't remove\n")); return NULL; } diff -ruN ../win-pvdrivers.hg/xenpci/xenpci.c xenpci/xenpci.c --- ../win-pvdrivers.hg/xenpci/xenpci.c 2011-02-26 20:43:12.000000000 +0800 +++ xenpci/xenpci.c 2011-02-26 20:44:33.000000000 +0800 @@ -487,10 +487,10 @@ WdfRegistryClose(sgo_key); return; /* something is very wrong */ } - if (dummy_group_index == 1 && wdf_load_group_index != -1 && + if (dummy_group_index == 1 && (wdf_load_group_index == -1 || (dummy_group_index < wdf_load_group_index && wdf_load_group_index < xenpci_group_index - && xenpci_group_index < boot_bus_extender_index)) + && xenpci_group_index < boot_bus_extender_index))) { FUNCTION_EXIT(); return; /* our work here is done */ @@ -505,7 +505,7 @@ WdfCollectionAdd(new_load_order, tmp_wdf_string); WdfObjectDelete(tmp_wdf_string); } - if (i == 1) + if (i == 1 && wdf_load_group_index != -1) { WDFSTRING tmp_wdf_string; WdfStringCreate(&wdf_load_group_name, WDF_NO_OBJECT_ATTRIBUTES, &tmp_wdf_string); diff -ruN ../win-pvdrivers.hg/xenpci/xenpci_fdo.c xenpci/xenpci_fdo.c --- ../win-pvdrivers.hg/xenpci/xenpci_fdo.c 2011-02-26 20:43:12.000000000 +0800 +++ xenpci/xenpci_fdo.c 2011-02-26 20:44:33.000000000 +0800 @@ -1,4 +1,4 @@ -/* + /* PV Drivers for Windows Xen HVM Domains Copyright (C) 2007 James Harper @@ -20,10 +20,14 @@ #include "xenpci.h" #include #include +#include "getphyinfo.h" +#include "xenpod.h" +#include "xenpci_sleep.h" #define SYSRQ_PATH "control/sysrq" #define SHUTDOWN_PATH "control/shutdown" -#define BALLOON_PATH "memory/target" +#define BALLOON_TARGET_PATH "memory/target" +#define BALLOON_WORKTIME_PATH "memory/worktime" /* Not really necessary but keeps PREfast happy */ static EVT_WDF_WORKITEM XenPci_SuspendResume; @@ -31,6 +35,8 @@ static KSTART_ROUTINE XenPci_BalloonThreadProc; #endif +extern KSTART_ROUTINE PvMemoryInfoThreadProc; + static VOID XenPci_MapHalThenPatchKernel(PXENPCI_DEVICE_DATA xpdd) { @@ -238,6 +244,11 @@ ULONG ret; int pfn_count; +#ifdef BALLOON_PATH_WORK_TIME + ULONG workbegintime; + ULONG workendtime; +#endif + FUNCTION_ENTER(); for(;;) @@ -267,6 +278,11 @@ KdPrint((__DRIVER_NAME " No change to memory\n")); continue; } + +#ifdef BALLOON_PATH_WORK_TIME + PvGetTickCount(&workbegintime); +#endif + else if (xpdd->current_memory < new_target) { KdPrint((__DRIVER_NAME " Trying to take %d MB from Xen\n", new_target - xpdd->current_memory)); @@ -277,6 +293,12 @@ pfn_count = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(mdl), MmGetMdlByteCount(mdl)); pfns = ExAllocatePoolWithTag(NonPagedPool, pfn_count * sizeof(xen_pfn_t), XENPCI_POOL_TAG); + if(pfns == NULL){ + mdl->Next = head; + head = mdl; + break; + } + /* sizeof(xen_pfn_t) may not be the same as PPFN_NUMBER */ for (i = 0; i < pfn_count; i++) pfns[i] = (xen_pfn_t)(MmGetMdlPfnArray(mdl)[i]); @@ -289,10 +311,24 @@ KdPrint((__DRIVER_NAME " Calling HYPERVISOR_memory_op(XENMEM_populate_physmap) - pfn_count = %d\n", pfn_count)); ret = HYPERVISOR_memory_op(xpdd, XENMEM_populate_physmap, &reservation); - ExFreePoolWithTag(pfns, XENPCI_POOL_TAG); + KdPrint((__DRIVER_NAME " populated %d pages\n", ret)); /* TODO: what do we do if less than the required number of pages were populated??? can this happen??? */ + /* fixed! */ + if(ret < (ULONG)pfn_count){ + if(ret > 0){ + /* We hit the Xen hard limit: reprobe. */ + reservation.nr_extents = ret; + ret = HYPERVISOR_memory_op(xpdd, XENMEM_decrease_reservation, &reservation); + KdPrint((__DRIVER_NAME " decreased %d pages\n", ret)); + } + mdl->Next = head; + head = mdl; + ExFreePoolWithTag(pfns, XENPCI_POOL_TAG); + break; + } + ExFreePoolWithTag(pfns, XENPCI_POOL_TAG); MmFreePagesFromMdl(mdl); ExFreePool(mdl); xpdd->current_memory++; @@ -334,6 +370,12 @@ break; } pfns = ExAllocatePoolWithTag(NonPagedPool, pfn_count * sizeof(xen_pfn_t), XENPCI_POOL_TAG); + if(pfns == NULL){ + MmFreePagesFromMdl(mdl); + ExFreePool(mdl); + break; + } + /* sizeof(xen_pfn_t) may not be the same as PPFN_NUMBER */ for (i = 0; i < pfn_count; i++) pfns[i] = (xen_pfn_t)(MmGetMdlPfnArray(mdl)[i]); @@ -361,6 +403,11 @@ } } } +#ifdef BALLOON_PATH_WORK_TIME + PvGetTickCount(&workendtime); + XenBus_Printf(xpdd, XBT_NIL, BALLOON_PATH_WORK_TIME, "%u", workendtime - workbegintime); +#endif + } //FUNCTION_EXIT(); } @@ -380,7 +427,7 @@ XenBus_StartTransaction(xpdd, &xbt); - XenBus_Read(xpdd, XBT_NIL, BALLOON_PATH, &value); + XenBus_Read(xpdd, XBT_NIL, BALLOON_TARGET_PATH, &value); if (value == NULL) { @@ -404,39 +451,18 @@ FUNCTION_EXIT(); } + static VOID XenPci_Suspend0(PVOID context) { PXENPCI_DEVICE_DATA xpdd = context; ULONG cancelled; - ULONGLONG sysenter_cs, sysenter_esp, sysenter_eip; FUNCTION_ENTER(); GntTbl_Suspend(xpdd); - - sysenter_cs = __readmsr(0x174); - sysenter_esp = __readmsr(0x175); - sysenter_eip = __readmsr(0x176); cancelled = hvm_shutdown(xpdd, SHUTDOWN_suspend); - - if (__readmsr(0x174) != sysenter_cs) - { - KdPrint((__DRIVER_NAME " sysenter_cs not restored. Fixing.\n")); - __writemsr(0x174, sysenter_cs); - } - if (__readmsr(0x175) != sysenter_esp) - { - KdPrint((__DRIVER_NAME " sysenter_esp not restored. Fixing.\n")); - __writemsr(0x175, sysenter_esp); - } - if (__readmsr(0x176) != sysenter_eip) - { - KdPrint((__DRIVER_NAME " sysenter_eip not restored. Fixing.\n")); - __writemsr(0x176, sysenter_eip); - } - KdPrint((__DRIVER_NAME " back from suspend, cancelled = %d\n", cancelled)); if (qemu_hide_flags_value) @@ -476,7 +502,7 @@ KdPrint((__DRIVER_NAME " suspend event channel = %d\n", xpdd->suspend_evtchn)); RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/suspend/event-channel"); XenBus_Printf(xpdd, XBT_NIL, path, "%d", xpdd->suspend_evtchn); - EvtChn_BindDpc(xpdd, xpdd->suspend_evtchn, XenPci_SuspendEvtDpc, xpdd->wdf_device, EVT_ACTION_FLAGS_NO_SUSPEND); + EvtChn_BindDpc(xpdd, xpdd->suspend_evtchn, XenPci_SuspendEvtDpc, xpdd->wdf_device); return STATUS_SUCCESS; } @@ -507,6 +533,7 @@ KdPrint((__DRIVER_NAME " Suspending child\n")); XenPci_Pdo_Suspend(child_device); } + KdPrint((__DRIVER_NAME " WdfChildListRetrieveNextDevice = %08x, STATUS_NO_MORE_ENTRIES = %08x\n", status, STATUS_NO_MORE_ENTRIES)); WdfChildListEndIteration(child_list, &child_iterator); XenBus_Suspend(xpdd); @@ -524,6 +551,7 @@ KdPrint((__DRIVER_NAME " Resuming child\n")); XenPci_Pdo_Resume(child_device); } + KdPrint((__DRIVER_NAME " WdfChildListRetrieveNextDevice = %08x, STATUS_NO_MORE_ENTRIES = %08x\n", status, STATUS_NO_MORE_ENTRIES)); WdfChildListEndIteration(child_list, &child_iterator); xpdd->suspend_state = SUSPEND_STATE_NONE; @@ -666,9 +694,9 @@ xpdd->platform_mmio_flags = translated_descriptor->Flags; break; case CmResourceTypeInterrupt: - xpdd->irq_level = (KIRQL)translated_descriptor->u.Interrupt.Level; - xpdd->irq_vector = translated_descriptor->u.Interrupt.Vector; - xpdd->irq_affinity = translated_descriptor->u.Interrupt.Affinity; + xpdd->irq_level = (KIRQL)translated_descriptor->u.Interrupt.Level; + xpdd->irq_vector = translated_descriptor->u.Interrupt.Vector; + xpdd->irq_affinity = translated_descriptor->u.Interrupt.Affinity; xpdd->irq_mode = (translated_descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)?Latched:LevelSensitive; xpdd->irq_number = raw_descriptor->u.Interrupt.Vector; KdPrint((__DRIVER_NAME " irq_number = %03x\n", raw_descriptor->u.Interrupt.Vector)); @@ -710,6 +738,8 @@ { NTSTATUS status = STATUS_SUCCESS; PXENPCI_DEVICE_DATA xpdd = GetXpdd(device); + ULONG i; + ULONG ret; FUNCTION_ENTER(); @@ -756,6 +786,24 @@ GntTbl_Init(xpdd); EvtChn_Init(xpdd); + for (i = 0; i < NR_GRANT_FRAMES + 1; i++) + { + struct xen_memory_reservation reservation; + xen_pfn_t pfn; + PMDL mdl = AllocatePage(); + pfn = (xen_pfn_t)(MmGetMdlPfnArray(mdl)[0]); + reservation.address_bits = 0; + reservation.extent_order = 0; + reservation.domid = DOMID_SELF; + reservation.nr_extents = 1; + #pragma warning(disable: 4127) /* conditional expression is constant */ + set_xen_guest_handle(reservation.extent_start, &pfn); + + //KdPrint((__DRIVER_NAME " Calling HYPERVISOR_memory_op - pfn = %x\n", (ULONG)pfn)); + ret = HYPERVISOR_memory_op(xpdd, XENMEM_decrease_reservation, &reservation); + //KdPrint((__DRIVER_NAME " decreased %d pages\n", ret)); + } + // use the memory_op(unsigned int op, void *arg) hypercall to adjust memory // use XENMEM_increase_reservation and XENMEM_decrease_reservation } @@ -777,12 +825,15 @@ NTSTATUS status = STATUS_SUCCESS; PXENPCI_DEVICE_DATA xpdd = GetXpdd(device); PCHAR response; - char *value; domid_t domid = DOMID_SELF; ULONG ret; + ULONG totalram_bias; xen_ulong_t *max_ram_page; HANDLE thread_handle; - + HANDLE memory_info_thread_handle; + XEN_POD_TARGET_T pod_target; + pod_target.domid = DOMID_SELF; + UNREFERENCED_PARAMETER(previous_state); FUNCTION_ENTER(); @@ -808,14 +859,21 @@ if (!xpdd->initial_memory) { - XenBus_Read(xpdd, XBT_NIL, BALLOON_PATH, &value); - if (atoi(value) > 0) - { - xpdd->initial_memory = atoi(value) >> 10; /* convert to MB */ - xpdd->current_memory = xpdd->initial_memory; - xpdd->target_memory = xpdd->initial_memory; + MEMORYSTATUS lpBuffer; + PvGlobalMemoryStatus(&lpBuffer); + xpdd->initial_memory = (ULONG)(lpBuffer.totalPhys >> 10); /*convert to MB*/ + xpdd->current_memory = xpdd->initial_memory; + + + ret = HYPERVISOR_memory_op(xpdd, XENMEM_get_pod_target, &pod_target); + + totalram_bias = HYPERVISOR_memory_op(xpdd, ret != -ENOSYS && ret != 1 + ? XENMEM_maximum_reservation : XENMEM_current_reservation, + &pod_target.domid); + if ((ULONG)totalram_bias != -ENOSYS) { + xpdd->initial_memory = totalram_bias >> (20 - PAGE_SHIFT); + xpdd->current_memory = xpdd->initial_memory + 1; /*lase line convert to MB may lost some KB, just add 1M*/ } - KdPrint((__DRIVER_NAME " Initial Memory Value = %d (%s)\n", xpdd->initial_memory, value)); KeInitializeEvent(&xpdd->balloon_event, SynchronizationEvent, FALSE); xpdd->balloon_shutdown = FALSE; status = PsCreateSystemThread(&thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, XenPci_BalloonThreadProc, xpdd); @@ -826,8 +884,18 @@ } status = ObReferenceObjectByHandle(thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->balloon_thread, NULL); ZwClose(thread_handle); + + /* start pci meminfo thread */ + status = PsCreateSystemThread(&memory_info_thread_handle, THREAD_ALL_ACCESS, NULL, NULL, NULL, PvMemoryInfoThreadProc, xpdd); + if (!NT_SUCCESS(status)) + { + KdPrint((__DRIVER_NAME " Could not start memory thread\n")); + return status; + } + status = ObReferenceObjectByHandle(memory_info_thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &xpdd->memory_thread, NULL); + ZwClose(memory_info_thread_handle); } - response = XenBus_AddWatch(xpdd, XBT_NIL, BALLOON_PATH, XenPci_BalloonHandler, device); + response = XenBus_AddWatch(xpdd, XBT_NIL, BALLOON_TARGET_PATH, XenPci_BalloonHandler, device); } else { @@ -940,9 +1008,7 @@ } else { - EvtChn_Suspend(xpdd); GntTbl_Suspend(xpdd); - } FUNCTION_EXIT(); diff -ruN ../win-pvdrivers.hg/xenpci/xenpci.h xenpci/xenpci.h --- ../win-pvdrivers.hg/xenpci/xenpci.h 2011-02-26 20:43:12.000000000 +0800 +++ xenpci/xenpci.h 2011-02-26 20:44:33.000000000 +0800 @@ -69,10 +69,6 @@ #define EVT_ACTION_TYPE_SUSPEND 4 #define EVT_ACTION_TYPE_NEW 5 /* setup of event is in progress */ -#define EVT_ACTION_FLAGS_DEFAULT 0 /* no special flags */ -#define EVT_ACTION_FLAGS_NO_SUSPEND 1 /* should not be fired on EVT_ACTION_TYPE_SUSPEND event */ - - #define XEN_PV_PRODUCT_NUMBER 0x0002 #define XEN_PV_PRODUCT_BUILD 0x00000001 @@ -83,7 +79,6 @@ PVOID ServiceContext; CHAR description[128]; ULONG type; /* EVT_ACTION_TYPE_* */ - ULONG flags; /* EVT_ACTION_FLAGS_* */ KDPC Dpc; ULONG port; ULONG vector; @@ -122,9 +117,6 @@ #define SUSPEND_STATE_HIGH_IRQL 2 /* all processors are at high IRQL and spinning */ #define SUSPEND_STATE_RESUMING 3 /* we are the other side of the suspend and things are starting to get back to normal */ -/* we take some grant refs out and put them aside so that we dont get corrupted by hibernate */ -#define HIBER_GREF_COUNT 128 - typedef struct { WDFDEVICE wdf_device; @@ -159,16 +151,16 @@ evtchn_port_t xen_store_evtchn; /* grant related */ - struct stack_state *gnttbl_ss; - struct stack_state *gnttbl_ss_copy; - grant_ref_t hiber_grefs[HIBER_GREF_COUNT]; - PMDL gnttbl_mdl; - grant_entry_t *gnttbl_table; - grant_entry_t *gnttbl_table_copy; + struct stack_state *gnttab_ss; + grant_entry_t *gnttab_table; + grant_entry_t *gnttab_table_copy; #if DBG - PULONG gnttbl_tag; - PULONG gnttbl_tag_copy; + PULONG gnttab_tag; #endif + PHYSICAL_ADDRESS gnttab_table_physical; + //grant_ref_t *gnttab_list; + //int gnttab_list_free; + //KSPIN_LOCK grant_lock; ULONG grant_frames; ev_action_t ev_actions[NR_EVENTS]; @@ -179,6 +171,12 @@ struct xenstore_domain_interface *xen_store_interface; #define BALLOON_UNITS (1024 * 1024) /* 1MB */ + + /*meminfo thread*/ + PKTHREAD memory_thread; + KEVENT memory_event; + + BOOLEAN memory_shutdown; PKTHREAD balloon_thread; KEVENT balloon_event; BOOLEAN balloon_shutdown; @@ -263,6 +261,8 @@ XENPCI_STATE_MAP_ELEMENT xb_post_connect_map[5]; XENPCI_STATE_MAP_ELEMENT xb_shutdown_map[5]; + + BOOLEAN hiber_usage_kludge; } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA; @@ -469,11 +469,11 @@ NTSTATUS EvtChn_Unmask(PVOID Context, evtchn_port_t Port); NTSTATUS -EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags); +EvtChn_Bind(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext); NTSTATUS -EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, ULONG flags); +EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PXEN_EVTCHN_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext); NTSTATUS -EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description, ULONG flags); +EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description); evtchn_port_t EvtChn_AllocIpi(PVOID context, ULONG vcpu); NTSTATUS diff -ruN ../win-pvdrivers.hg/xenpci/xenpci_pdo.c xenpci/xenpci_pdo.c --- ../win-pvdrivers.hg/xenpci/xenpci_pdo.c 2011-02-26 20:43:12.000000000 +0800 +++ xenpci/xenpci_pdo.c 2011-02-26 20:44:33.000000000 +0800 @@ -251,7 +251,7 @@ PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device); PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo); - return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT); + return EvtChn_Bind(xpdd, Port, ServiceRoutine, ServiceContext); } static NTSTATUS @@ -261,7 +261,7 @@ PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device); PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo); - return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext, EVT_ACTION_FLAGS_DEFAULT); + return EvtChn_BindDpc(xpdd, Port, ServiceRoutine, ServiceContext); } static NTSTATUS @@ -502,7 +502,9 @@ { /* it's possible that the workitems are blocked because the pagefile isn't available. Lets just re-read the backend value for now */ XenPci_UpdateBackendState(device); - remaining -= thiswait; + + // this code is commented because it can cause the VM waitting forever + //remaining -= thiswait; if (remaining == 0) { KdPrint((__DRIVER_NAME " Timed out waiting for %d!\n", backend_state_response)); @@ -581,8 +583,8 @@ EvtChn_Close(xpdd, PtrToUlong(value)); break; case XEN_INIT_TYPE_GRANT_ENTRIES: - for (i = 0; i < PtrToUlong(value); i++) - GntTbl_EndAccess(xpdd, ((grant_ref_t *)value2)[i], FALSE, PtrToUlong(setting)); + for (i = 0; i < PtrToUlong(setting); i++) + GntTbl_EndAccess(xpdd, ((grant_ref_t *)value)[i], FALSE, (ULONG)'XPDO'); break; } } @@ -671,6 +673,7 @@ in_ptr = src; while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END) { +//KdPrint((__DRIVER_NAME " in_ptr = %p, type = %d\n", in_ptr, type)); ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, type, setting, value, value2); switch (type) @@ -697,7 +700,6 @@ ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, ring, NULL); // add the grant entry too so it gets freed automatically __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, XEN_INIT_TYPE_GRANT_ENTRIES); - __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, (ULONG)'XPDO'); __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, 1); __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref); } @@ -726,17 +728,17 @@ ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel), NULL); if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ) { - EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector, path, EVT_ACTION_FLAGS_DEFAULT); + EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector, path); } else if (type == XEN_INIT_TYPE_EVENT_CHANNEL_DPC) { #pragma warning(suppress:4055) - EvtChn_BindDpc(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2, EVT_ACTION_FLAGS_DEFAULT); + EvtChn_BindDpc(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2); } else { #pragma warning(suppress:4055) - EvtChn_Bind(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2, EVT_ACTION_FLAGS_DEFAULT); + EvtChn_Bind(xpdd, event_channel, (PXEN_EVTCHN_SERVICE_ROUTINE)value, value2); } } else @@ -830,13 +832,11 @@ //KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value))); __ADD_XEN_INIT_UCHAR(&out_ptr, type); __ADD_XEN_INIT_UCHAR(&xppdd->assigned_resources_ptr, type); - __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(setting)); - __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(setting)); __ADD_XEN_INIT_ULONG(&out_ptr, PtrToUlong(value)); __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, PtrToUlong(value)); for (i = 0; i < PtrToUlong(value); i++) { - gref = GntTbl_GetRef(xpdd, PtrToUlong(setting)); + gref = GntTbl_GetRef(xpdd, 'XPDO'); __ADD_XEN_INIT_ULONG(&out_ptr, gref); __ADD_XEN_INIT_ULONG(&xppdd->assigned_resources_ptr, gref); } @@ -1109,14 +1109,13 @@ { } -#if 0 if (previous_state == WdfPowerDevicePrepareForHibernation || previous_state == WdfPowerDeviceD3 || previous_state == WdfPowerDeviceD3Final) { xppdd->requested_resources_ptr = xppdd->requested_resources_start; xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG); } + XenConfig_InitConfigPage(device); -#endif status = XenPci_GetBackendAndAddWatch(device); if (!NT_SUCCESS(status)) @@ -1125,31 +1124,7 @@ FUNCTION_EXIT_STATUS(status); return status; } - - if (previous_state == WdfPowerDeviceD3 || previous_state == WdfPowerDeviceD3Final) - { - xppdd->requested_resources_ptr = xppdd->requested_resources_start; - xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG); - XenConfig_InitConfigPage(device); - status = XenPci_XenConfigDevice(device); - } - else if (previous_state == WdfPowerDevicePrepareForHibernation) - { - PVOID src, dst; - - ADD_XEN_INIT_REQ(&xppdd->requested_resources_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL); - src = xppdd->requested_resources_start; - xppdd->requested_resources_ptr = xppdd->requested_resources_start = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);; - xppdd->assigned_resources_ptr = xppdd->assigned_resources_start; - - dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached); - - status = XenPci_XenConfigDeviceSpecifyBuffers(device, src, dst); - - MmUnmapIoSpace(dst, xppdd->config_page_length); - ExFreePoolWithTag(src, XENPCI_POOL_TAG); - } - + status = XenPci_XenConfigDevice(device); if (!NT_SUCCESS(status)) { RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path); @@ -1451,7 +1426,7 @@ KdPrint((__DRIVER_NAME " WdfDeviceAddQueryInterface failed - %08x\n", status)); return status; } - + RtlStringCbCopyA(xppdd->path, ARRAY_SIZE(xppdd->path), identification->path); RtlStringCbCopyA(xppdd->device, ARRAY_SIZE(xppdd->device), identification->device); xppdd->index = identification->index; @@ -1501,7 +1476,6 @@ PVOID setting; PVOID value; PVOID value2; - int i; KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (%s)\n", xppdd->path)); @@ -1523,25 +1497,18 @@ { switch (type) { - case XEN_INIT_TYPE_RING: /* frontend ring */ - FreePages(value); - break; case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */ case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel bound to dpc */ case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */ EvtChn_Unbind(xpdd, PtrToUlong(value)); EvtChn_Close(xpdd, PtrToUlong(value)); break; - case XEN_INIT_TYPE_GRANT_ENTRIES: - for (i = 0; i < (int)PtrToUlong(value); i++) - GntTbl_EndAccess(xpdd, ((grant_ref_t *)value2)[i], FALSE, PtrToUlong(setting)); - break; } } } RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path); - XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, device); + XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateHandler, xppdd); } else { @@ -1586,9 +1553,9 @@ src = xppdd->requested_resources_start; xppdd->requested_resources_ptr = xppdd->requested_resources_start = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);; xppdd->assigned_resources_ptr = xppdd->assigned_resources_start; - + dst = MmMapIoSpace(xppdd->config_page_phys, xppdd->config_page_length, MmNonCached); - + status = XenPci_XenConfigDeviceSpecifyBuffers(device, src, dst); MmUnmapIoSpace(dst, xppdd->config_page_length); diff -ruN ../win-pvdrivers.hg/xenpci/xenpci_sleep.c xenpci/xenpci_sleep.c --- ../win-pvdrivers.hg/xenpci/xenpci_sleep.c 1970-01-01 08:00:00.000000000 +0800 +++ xenpci/xenpci_sleep.c 2011-02-26 20:44:33.000000000 +0800 @@ -0,0 +1,23 @@ +#include "xenpci_sleep.h" + +VOID PvWaitMicroSecond(ULONG ulMircoSecond) +{ + KTIMER kTimer; + LARGE_INTEGER timeout; + KeInitializeTimer(&kTimer); + timeout = RtlConvertLongToLargeInteger(ulMircoSecond * -10); + + KeSetTimer(&kTimer, timeout, NULL); + KeWaitForSingleObject(&kTimer, Executive, KernelMode, FALSE, NULL); +} + +void PvGetTickCount(PULONG msec) +{ + LARGE_INTEGER tick_count; + ULONG myinc = KeQueryTimeIncrement(); + KeQueryTickCount(&tick_count); + tick_count.QuadPart *= myinc; + tick_count.QuadPart /= 10000; + *msec = tick_count.LowPart; +} + diff -ruN ../win-pvdrivers.hg/xenpci/xenpci_sleep.h xenpci/xenpci_sleep.h --- ../win-pvdrivers.hg/xenpci/xenpci_sleep.h 1970-01-01 08:00:00.000000000 +0800 +++ xenpci/xenpci_sleep.h 2011-02-26 20:44:33.000000000 +0800 @@ -0,0 +1,14 @@ +#if !defined(_XENPCISLEEP_H_) +#define _XENPCISLEEP_H_ + +#define DDKAPI +#include +#include +#define NTSTRSAFE_LIB +#include +#include + +VOID PvWaitMicroSecond(ULONG ulMircoSecond); +VOID PvGetTickCount(PULONG msec); + +#endif diff -ruN ../win-pvdrivers.hg/xenpci/xenpod.h xenpci/xenpod.h --- ../win-pvdrivers.hg/xenpci/xenpod.h 1970-01-01 08:00:00.000000000 +0800 +++ xenpci/xenpod.h 2011-02-26 20:44:33.000000000 +0800 @@ -0,0 +1,14 @@ +#if !defined(_XENPOD_H_) +#define _XENPOD_H_ + +#define XENMEM_get_pod_target 17 + +typedef struct { + ULONG target_pages; + ULONG tot_pages; + ULONG pod_cache_pages; + ULONG pod_entries; + domid_t domid; +} XEN_POD_TARGET_T; + +#endif