xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* re:RE: blue screen in windows balloon driver
@ 2011-02-26 13:01 MaoXiaoyun
  2011-02-27 11:25 ` James Harper
  0 siblings, 1 reply; 27+ messages in thread
From: MaoXiaoyun @ 2011-02-26 13:01 UTC (permalink / raw)
  To: xen devel; +Cc: george.dunlap, james.harper


[-- Attachment #1.1: Type: text/plain, Size: 2392 bytes --]


Thanks James.
 
I think it is GPLPV. The driver is from http://xenbits.xen.org/ext/win-pvdrivers.hg
But, I have done some other things
 
1) Add pod support 
2) enable a meminfo thread, periodically write VM meminfo into xenstore 
    We use info of Current Memory, Free memory, and Committed memory, retrived through NativeAPI
3) our code is based from changeset 823, attached is the diff of my current code with changset of 853.
 
Maybe I need add my code to 853, and test again.
Thanks.
 
>From: James Harper [mailto:james.harper@bendigoit.com.au] 
>To: xiaoyun.maoxy; xen-devel@lists.xensource.com
>cc: george.dunlap@eu.citrix.com
>Subject: RE: blue screen in windows balloon driver
>
>> Hi:
>>      We've confronted the windows 2003 Blue screen when using balloon
>> driver.
>
>>      The blue screen has the information of "NO_PAGES_AVAILABLE", and
>>      Technical information:
>>      ***STOP: 0x0000004D (0x0002A8FB,0x0002A8FB,0x00000000,0x00000000)
>
>>      In fact we are doing the stress test on 24 windows2003 HVM on a
>>      24G, 16core host.
>>      In dom0, there is a daemon process (balloond) will give memory
>>      back  to the VM who acclaim memory.
>>      The balloond will ensure every VM at least has 512M memory.
>>      Each VM is started with memory=512 maxmem=2048
>>      Inside each of the VM, there is two processes eat memory, each
        of which will eat 1G memory.
>>      And the page file size configured on C:\ is init size 1536M, max
>>      size 3072M, which I think even
>>      If balloond process not give back the memory back to VM, the VM
>       can has 512M+3072M = 3.5G virtual
>>      memory.
>> 
>>      Am I right?, if so , since our eat memory process only consume
>>      2G  memory, how could "NO_PAGES_AVAILABLE" happen?
>>      Also, since we enable VM writes its memory status into xenstore,
>>      when blue screen, it has only has 972KB memory.
>>      Any comments? Many thanks.
>> 
> 
>
>You've put myself (I wrote GPLPV) and George Dunlap (from Citrix) in the
>CC list but you don't say if you are using GPLPV drivers or Citrix PV
>drivers. If you are using GPLPV drivers let me know and I'll get some
>more information about the problem from you. If you aren't using GPLPV
>drivers then I don't think I can be of much assistance...
>
>Thanks
>
>James
> 		 	   		  

[-- Attachment #1.2: Type: text/html, Size: 3715 bytes --]

[-- Attachment #2: changset823.diff --]
[-- Type: application/octet-stream, Size: 72585 bytes --]

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 <WinError.h>
+
+//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 <ntddk.h>
+#include <wdm.h>
+#define NTSTRSAFE_LIB
+#include <ntstrsafe.h>
+#include <stdlib.h>
+
+/*
+   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 <stdlib.h>
+ #include <aux_klib.h>
++#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 <stdlib.h>
 #include <aux_klib.h>
+#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 <ntddk.h>
+#include <wdm.h>
+#define NTSTRSAFE_LIB
+#include <ntstrsafe.h>
+#include <stdlib.h>
+
+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

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2011-03-14  5:19 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-26 13:01 re:RE: blue screen in windows balloon driver MaoXiaoyun
2011-02-27 11:25 ` James Harper
2011-02-28  4:33   ` MaoXiaoyun
     [not found]     ` <BLU157-w3689F78415A43CC5997DD7DADE0@phx.gbl>
2011-02-28  8:29       ` MaoXiaoyun
2011-02-28 11:45         ` James Harper
2011-02-28 23:45         ` James Harper
2011-03-01  2:37           ` MaoXiaoyun
2011-03-01  5:01             ` James Harper
2011-03-01  5:28               ` MaoXiaoyun
     [not found]                 ` <AEC6C66638C05B468B556EA548C1A77D01C55AC7@trantor>
     [not found]                   ` <BLU157-w655070D9CFE092D78C011DDAC10@phx.gbl>
     [not found]                     ` <AEC6C66638C05B468B556EA548C1A77D01C55ACA@trantor>
2011-03-01 12:34                       ` MaoXiaoyun
2011-03-01 12:35                         ` James Harper
2011-03-01 12:48                           ` James Harper
2011-03-02  3:01                             ` MaoXiaoyun
2011-03-02  6:07                               ` James Harper
2011-03-02  6:44                                 ` MaoXiaoyun
2011-03-02  6:28                               ` James Harper
2011-03-02  9:23                                 ` MaoXiaoyun
2011-03-02 11:37                                   ` James Harper
     [not found]                                 ` <BLU157-w3311FE380E5D57DD810827DAC00@phx.gbl>
     [not found]                                   ` <AEC6C66638C05B468B556EA548C1A77D01C55B44@trantor>
     [not found]                                     ` <BLU157-w564C179CAAF26EC5D7559DAC00@phx.gbl>
     [not found]                                       ` <AEC6C66638C05B468B556EA548C, , , , , , 1A77D01, C, 5, 5, B, 4, 6@trantor>
     [not found]                                         ` <BLU157-w446CEE35E592FE12EF0180DAC30@phx.gbl>
     [not found]                                           ` <AEC6C66638C05B468B556EA548C1A77D01C55B88@trantor>
     [not found]                                             ` <BLU157-w5382FC5FCC26C6EE8EC18BDAC30@phx.gbl>
     [not found]                                               ` <AEC6C66638C05B468B556EA548C1A77D01C55BB3@trantor>
     [not found]                                                 ` <BLU157-w62FFC7240FD65345A0B3A8DAC30@phx.gbl>
     [not found]                                                   ` <AEC6C66638C05B468B556EA548C1A77D01C55BB7@trantor>
     [not found]                                                     ` <BLU157-w30368B861A4BFFF8A8DB9DDAC30@phx.gbl>
     [not found]                                                       ` <AEC6C66638C05B468B556EA548C1A77D01C55BBA@trantor>
     [not found]                                                         ` <BLU157-w28F0FE7DA9D129E9003136DAC30@phx.gbl>
     [not found]                                                           ` <AEC6C66638C05B468B556EA548C1A77D01C55BBD@trantor>
     [not found]                                                             ` <BLU157-w826F2EDB9C1A7077BA524DAC30@phx.gbl>
     [not found]                                                               ` <019001cbdd41$1ccfbc20$566f3460$@harper@bendigoit.com.au>
2011-03-14  2:24                                                                 ` MaoXiaoyun
2011-03-14  2:57                                                                   ` MaoXiaoyun
2011-03-14  3:52                                                                   ` James Harper
2011-03-14  5:08                                                                   ` James Harper
2011-03-14  5:19                                                                     ` MaoXiaoyun
2011-03-01  7:14               ` MaoXiaoyun
2011-03-01  9:36                 ` James Harper
     [not found]                 ` <AEC6C66638C05B468B556EA548C1A77D01C55AC5@trantor>
2011-03-01  9:51                   ` MaoXiaoyun
2011-03-01  9:54                     ` James Harper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).