win-pvdrivers

changeset 1055:a127b9bea695

Add xencache - tmem client implementation that does writethrough caching of pagefile writes in ephemeral tmem. Testing only.
author James Harper <james.harper@bendigoit.com.au>
date Sun Jun 02 16:38:50 2013 +1000 (2013-06-02)
parents 471c94d04d8a
children b29ed182391f
files xencache/makefile xencache/makefile.inc xencache/sources xencache/xencache.c xencache/xencache.h xencache/xencache.inx xencache/xencache.rc
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xencache/makefile	Sun Jun 02 16:38:50 2013 +1000
     1.3 @@ -0,0 +1,1 @@
     1.4 +!INCLUDE $(NTMAKEENV)\makefile.def
     1.5 \ No newline at end of file
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xencache/makefile.inc	Sun Jun 02 16:38:50 2013 +1000
     2.3 @@ -0,0 +1,6 @@
     2.4 +_LNG=$(LANGUAGE)
     2.5 +STAMP=stampinf -f $@ -a $(_BUILDARCH) -d * -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR) -v $(GPLPV_VERSION)
     2.6 +
     2.7 +$(OBJ_PATH)\$(O)\$(TARGETNAME).inf: $(TARGETNAME).inx sources ..\common.inc
     2.8 +    copy $(@B).inx $@
     2.9 +    $(STAMP)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xencache/sources	Sun Jun 02 16:38:50 2013 +1000
     3.3 @@ -0,0 +1,7 @@
     3.4 +!INCLUDE ..\common.inc
     3.5 +TARGETNAME=xencache
     3.6 +TARGETTYPE=DRIVER
     3.7 +NTTARGETFILE0=$(NTTARGETFILES) $(OBJ_PATH)\$(O)\$(TARGETNAME).inf
     3.8 +TARGETLIBS=$(TARGETLIBS) ..\xenpci\$(O)\xenpci.lib
     3.9 +TARGETLIBS= $(TARGETLIBS) $(IFSKIT_LIB_PATH)\fltMgr.lib
    3.10 +SOURCES=xencache.rc xencache.c
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xencache/xencache.c	Sun Jun 02 16:38:50 2013 +1000
     4.3 @@ -0,0 +1,414 @@
     4.4 +/*
     4.5 +PV Drivers for Windows Xen HVM Domains
     4.6 +Copyright (C) 2013 James Harper
     4.7 +
     4.8 +This program is free software; you can redistribute it and/or
     4.9 +modify it under the terms of the GNU General Public License
    4.10 +as published by the Free Software Foundation; either version 2
    4.11 +of the License, or (at your option) any later version.
    4.12 +
    4.13 +This program is distributed in the hope that it will be useful,
    4.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.16 +GNU General Public License for more details.
    4.17 +
    4.18 +You should have received a copy of the GNU General Public License
    4.19 +along with this program; if not, write to the Free Software
    4.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    4.21 +*/
    4.22 +
    4.23 +#include "xencache.h"
    4.24 +
    4.25 +#define TMEM_CONTROL               0
    4.26 +#define TMEM_NEW_POOL              1
    4.27 +#define TMEM_DESTROY_POOL          2
    4.28 +#define TMEM_NEW_PAGE              3
    4.29 +#define TMEM_PUT_PAGE              4
    4.30 +#define TMEM_GET_PAGE              5
    4.31 +#define TMEM_FLUSH_PAGE            6
    4.32 +#define TMEM_FLUSH_OBJECT          7
    4.33 +#define TMEM_READ                  8
    4.34 +#define TMEM_WRITE                 9
    4.35 +#define TMEM_XCHG                 10
    4.36 +
    4.37 +/* Bits for HYPERVISOR_tmem_op(TMEM_NEW_POOL) */
    4.38 +#define TMEM_POOL_PERSIST          1
    4.39 +#define TMEM_POOL_SHARED           2
    4.40 +#define TMEM_POOL_PAGESIZE_SHIFT   4
    4.41 +#define TMEM_VERSION_SHIFT        24
    4.42 +
    4.43 +/* flags for tmem_ops.new_pool */
    4.44 +#define TMEM_POOL_PERSIST          1
    4.45 +#define TMEM_POOL_SHARED           2
    4.46 +
    4.47 +PFLT_FILTER filter_handle;
    4.48 +global_context_t global_context;
    4.49 +
    4.50 +DRIVER_INITIALIZE DriverEntry;
    4.51 +
    4.52 +NTSTATUS XenCache_FilterUnload(FLT_FILTER_UNLOAD_FLAGS flags);
    4.53 +NTSTATUS XenCache_InstanceSetup(PCFLT_RELATED_OBJECTS flt_objects, FLT_INSTANCE_SETUP_FLAGS flags, DEVICE_TYPE volume_device_type, FLT_FILESYSTEM_TYPE volume_filesystem_type);
    4.54 +NTSTATUS XenCache_InstanceQueryTeardown(PCFLT_RELATED_OBJECTS flt_objects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS flags);
    4.55 +VOID XenCache_InstanceTeardownStart(PCFLT_RELATED_OBJECTS flt_objects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS reason);
    4.56 +VOID XenCache_InstanceTeardownComplete(PCFLT_RELATED_OBJECTS flt_objects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS reason);
    4.57 +
    4.58 +FLT_PREOP_CALLBACK_STATUS XenCache_Pre_CLOSE(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID *completion_context);
    4.59 +FLT_POSTOP_CALLBACK_STATUS XenCache_Pst_CLOSE(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID completion_context, FLT_POST_OPERATION_FLAGS flags);
    4.60 +FLT_PREOP_CALLBACK_STATUS XenCache_Pre_CLEANUP(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID *completion_context);
    4.61 +FLT_POSTOP_CALLBACK_STATUS XenCache_Pst_CLEANUP(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID completion_context, FLT_POST_OPERATION_FLAGS flags);
    4.62 +FLT_PREOP_CALLBACK_STATUS XenCache_Pre_READ(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID *completion_context);
    4.63 +FLT_PREOP_CALLBACK_STATUS XenCache_Pre_WRITE(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID *completion_context);
    4.64 +
    4.65 +FLT_OPERATION_REGISTRATION filter_callbacks[] = {
    4.66 +  { IRP_MJ_CLOSE, 0, XenCache_Pre_CLOSE, XenCache_Pst_CLOSE },
    4.67 +  { IRP_MJ_CLEANUP, 0, XenCache_Pre_CLEANUP, XenCache_Pst_CLEANUP },
    4.68 +  { IRP_MJ_READ, 0, XenCache_Pre_READ, NULL },
    4.69 +  { IRP_MJ_WRITE, 0, XenCache_Pre_WRITE, NULL },
    4.70 +  { IRP_MJ_OPERATION_END }
    4.71 +};
    4.72 +
    4.73 +FLT_REGISTRATION filter_registration = {
    4.74 +  sizeof(FLT_REGISTRATION),
    4.75 +  FLT_REGISTRATION_VERSION,
    4.76 +  0, // flags
    4.77 +  NULL, // context_callbacks,
    4.78 +  filter_callbacks,
    4.79 +  XenCache_FilterUnload,
    4.80 +  XenCache_InstanceSetup,
    4.81 +  XenCache_InstanceQueryTeardown,
    4.82 +  XenCache_InstanceTeardownStart,
    4.83 +  XenCache_InstanceTeardownComplete,
    4.84 +  NULL, // XenCache_GenerateFileName,
    4.85 +  NULL, // XenCache_NormalizeNameComponentn,
    4.86 +  NULL, // XenCache_NormalizeContextCleanup,
    4.87 +#if FLT_MGR_LONGHORN
    4.88 +  NULL, // XenCache_TransactionNotification,
    4.89 +  NULL, // XenCache_NormalizeNameComponentEx,
    4.90 +#endif
    4.91 +};
    4.92 +
    4.93 +NTSTATUS
    4.94 +DriverEntry(PDRIVER_OBJECT driver_object, PUNICODE_STRING registry_path) {
    4.95 +  NTSTATUS status;
    4.96 +
    4.97 +  UNREFERENCED_PARAMETER(registry_path);
    4.98 +  
    4.99 +  FUNCTION_ENTER();
   4.100 +
   4.101 +  RtlZeroMemory(&global_context, sizeof(global_context_t));
   4.102 +  KeInitializeSpinLock(&global_context.lock);
   4.103 +  
   4.104 +  status = FltRegisterFilter(driver_object, &filter_registration, &filter_handle);
   4.105 +  FUNCTION_MSG("FltRegisterFilter = %08x\n", status);
   4.106 +  
   4.107 +  if (!NT_SUCCESS(status)) {
   4.108 +    FUNCTION_EXIT();
   4.109 +    return status;
   4.110 +  }
   4.111 +  status = FltStartFiltering(filter_handle);
   4.112 +  FUNCTION_MSG("FltStartFiltering = %08x\n", status);
   4.113 +  if (!NT_SUCCESS(status)) {
   4.114 +    FltUnregisterFilter(filter_handle);
   4.115 +  }
   4.116 +  
   4.117 +  FUNCTION_EXIT();
   4.118 +
   4.119 +  return status;
   4.120 +}
   4.121 +
   4.122 +NTSTATUS
   4.123 +XenCache_FilterUnload(FLT_FILTER_UNLOAD_FLAGS flags) {
   4.124 +  UNREFERENCED_PARAMETER(flags);
   4.125 +  FUNCTION_ENTER();
   4.126 +  FltUnregisterFilter(filter_handle);
   4.127 +  RtlZeroMemory(&global_context, sizeof(global_context_t));
   4.128 +  FUNCTION_EXIT();
   4.129 +  return STATUS_SUCCESS;
   4.130 +}
   4.131 +
   4.132 +NTSTATUS
   4.133 +XenCache_InstanceSetup(PCFLT_RELATED_OBJECTS flt_objects, FLT_INSTANCE_SETUP_FLAGS flags, DEVICE_TYPE volume_device_type, FLT_FILESYSTEM_TYPE volume_filesystem_type) {
   4.134 +  FUNCTION_ENTER();
   4.135 +  if (volume_device_type != FILE_DEVICE_DISK_FILE_SYSTEM) {
   4.136 +    FUNCTION_MSG("is not disk\n");
   4.137 +    FUNCTION_EXIT();
   4.138 +    return STATUS_FLT_DO_NOT_ATTACH;
   4.139 +  }
   4.140 +  if (volume_filesystem_type != FLT_FSTYPE_NTFS) {
   4.141 +    FUNCTION_MSG("is not NTFS\n");
   4.142 +    FUNCTION_EXIT();
   4.143 +    return STATUS_FLT_DO_NOT_ATTACH;
   4.144 +  }    
   4.145 +  FUNCTION_MSG("flt_objects = %p\n", flt_objects);
   4.146 +  FUNCTION_MSG("flags = %08x\n", flags);
   4.147 +  FUNCTION_MSG("volume_device_type = %08x\n", volume_device_type);
   4.148 +  FUNCTION_MSG("volume_filesystem_type = %08x\n", volume_filesystem_type);
   4.149 +  FUNCTION_EXIT();
   4.150 +  return STATUS_SUCCESS;
   4.151 +}
   4.152 +
   4.153 +NTSTATUS
   4.154 +XenCache_InstanceQueryTeardown(PCFLT_RELATED_OBJECTS flt_objects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS flags) {
   4.155 +  FUNCTION_ENTER();
   4.156 +  FUNCTION_MSG("flt_objects = %p\n", flt_objects);
   4.157 +  FUNCTION_MSG("flags = %08x\n", flags);
   4.158 +  FUNCTION_EXIT();
   4.159 +  return STATUS_SUCCESS;
   4.160 +}
   4.161 +
   4.162 +VOID
   4.163 +XenCache_InstanceTeardownStart(PCFLT_RELATED_OBJECTS flt_objects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS reason) {
   4.164 +  FUNCTION_ENTER();
   4.165 +  FUNCTION_MSG("flt_objects = %p\n", flt_objects);
   4.166 +  FUNCTION_MSG("reason = %08x\n", reason);
   4.167 +  FUNCTION_EXIT();
   4.168 +}
   4.169 +
   4.170 +VOID
   4.171 +XenCache_InstanceTeardownComplete(PCFLT_RELATED_OBJECTS flt_objects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS reason) {
   4.172 +  FUNCTION_ENTER();
   4.173 +  FUNCTION_MSG("flt_objects = %p\n", flt_objects);
   4.174 +  FUNCTION_MSG("reason = %08x\n", reason);
   4.175 +  FUNCTION_EXIT();
   4.176 +}
   4.177 +
   4.178 +FLT_PREOP_CALLBACK_STATUS
   4.179 +XenCache_Pre_CLOSE(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID *completion_context) {
   4.180 +  UNREFERENCED_PARAMETER(data);
   4.181 +  UNREFERENCED_PARAMETER(flt_objects);
   4.182 +  UNREFERENCED_PARAMETER(completion_context);
   4.183 +  if (FsRtlIsPagingFile(flt_objects->FileObject)) {
   4.184 +    FUNCTION_ENTER();
   4.185 +    FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
   4.186 +    FUNCTION_MSG("FileObject = %p\n", flt_objects->FileObject);
   4.187 +    FUNCTION_MSG("FileName = %S\n", flt_objects->FileObject->FileName.Buffer);
   4.188 +    FUNCTION_MSG("IsPagingFile = %d\n", FsRtlIsPagingFile(flt_objects->FileObject));
   4.189 +    FUNCTION_EXIT();
   4.190 +  }
   4.191 +#if 0
   4.192 +  FUNCTION_ENTER();
   4.193 +  FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
   4.194 +  FUNCTION_MSG("FileObject = %p\n", flt_objects->FileObject);
   4.195 +  FUNCTION_MSG("FileName = %S\n", flt_objects->FileObject->FileName.Buffer);
   4.196 +  FUNCTION_MSG("IsPagingFile = %d\n", FsRtlIsPagingFile(flt_objects->FileObject));
   4.197 +  FUNCTION_EXIT();
   4.198 +#endif
   4.199 +  return FLT_PREOP_SUCCESS_WITH_CALLBACK;
   4.200 +}
   4.201 +
   4.202 +FLT_POSTOP_CALLBACK_STATUS
   4.203 +XenCache_Pst_CLOSE(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID completion_context, FLT_POST_OPERATION_FLAGS flags) {
   4.204 +  UNREFERENCED_PARAMETER(data);
   4.205 +  UNREFERENCED_PARAMETER(flt_objects);
   4.206 +  UNREFERENCED_PARAMETER(completion_context);
   4.207 +  UNREFERENCED_PARAMETER(flags);
   4.208 +  if (FsRtlIsPagingFile(flt_objects->FileObject)) {
   4.209 +    FUNCTION_ENTER();
   4.210 +    FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
   4.211 +    FUNCTION_MSG("FileObject = %p\n", flt_objects->FileObject);
   4.212 +    FUNCTION_MSG("FileName = %S\n", flt_objects->FileObject->FileName.Buffer);
   4.213 +    FUNCTION_MSG("IsPagingFile = %d\n", FsRtlIsPagingFile(flt_objects->FileObject));
   4.214 +    FUNCTION_EXIT();
   4.215 +  }
   4.216 +#if 0
   4.217 +  FUNCTION_ENTER();
   4.218 +  FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
   4.219 +  FUNCTION_MSG("FileObject = %p\n", flt_objects->FileObject);
   4.220 +  FUNCTION_MSG("FileName = %S\n", flt_objects->FileObject->FileName.Buffer);
   4.221 +  FUNCTION_MSG("IsPagingFile = %d\n", FsRtlIsPagingFile(flt_objects->FileObject));
   4.222 +  FUNCTION_EXIT();
   4.223 +#endif
   4.224 +  return FLT_POSTOP_FINISHED_PROCESSING;
   4.225 +}
   4.226 +
   4.227 +FLT_PREOP_CALLBACK_STATUS
   4.228 +XenCache_Pre_CLEANUP(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID *completion_context) {
   4.229 +  UNREFERENCED_PARAMETER(data);
   4.230 +  UNREFERENCED_PARAMETER(flt_objects);
   4.231 +  UNREFERENCED_PARAMETER(completion_context);
   4.232 +  if (FsRtlIsPagingFile(flt_objects->FileObject)) {
   4.233 +    FUNCTION_ENTER();
   4.234 +    FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
   4.235 +    FUNCTION_MSG("FileObject = %p\n", flt_objects->FileObject);
   4.236 +    FUNCTION_MSG("FileName = %S\n", flt_objects->FileObject->FileName.Buffer);
   4.237 +    FUNCTION_MSG("IsPagingFile = %d\n", FsRtlIsPagingFile(flt_objects->FileObject));
   4.238 +    FUNCTION_EXIT();
   4.239 +  }
   4.240 +#if 0
   4.241 +  FUNCTION_ENTER();
   4.242 +  FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
   4.243 +  FUNCTION_MSG("FileObject = %p\n", flt_objects->FileObject);
   4.244 +  FUNCTION_MSG("FileName = %S\n", flt_objects->FileObject->FileName.Buffer);
   4.245 +  FUNCTION_MSG("IsPagingFile = %d\n", FsRtlIsPagingFile(flt_objects->FileObject));
   4.246 +  FUNCTION_EXIT();
   4.247 +#endif
   4.248 +  return FLT_PREOP_SUCCESS_WITH_CALLBACK;
   4.249 +}
   4.250 +
   4.251 +FLT_POSTOP_CALLBACK_STATUS
   4.252 +XenCache_Pst_CLEANUP(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID completion_context, FLT_POST_OPERATION_FLAGS flags) {
   4.253 +  UNREFERENCED_PARAMETER(data);
   4.254 +  UNREFERENCED_PARAMETER(flt_objects);
   4.255 +  UNREFERENCED_PARAMETER(completion_context);
   4.256 +  UNREFERENCED_PARAMETER(flags);
   4.257 +  if (FsRtlIsPagingFile(flt_objects->FileObject)) {
   4.258 +    FUNCTION_ENTER();
   4.259 +    FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
   4.260 +    FUNCTION_MSG("FileObject = %p\n", flt_objects->FileObject);
   4.261 +    FUNCTION_MSG("FileName = %S\n", flt_objects->FileObject->FileName.Buffer);
   4.262 +    FUNCTION_MSG("IsPagingFile = %d\n", FsRtlIsPagingFile(flt_objects->FileObject));
   4.263 +    FUNCTION_EXIT();
   4.264 +  }
   4.265 +  return FLT_POSTOP_FINISHED_PROCESSING;
   4.266 +}
   4.267 +
   4.268 +FLT_PREOP_CALLBACK_STATUS
   4.269 +XenCache_Pre_WRITE(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID *completion_context) {
   4.270 +  pagefile_context_t *context;
   4.271 +  int i;
   4.272 +  KIRQL old_irql;
   4.273 +  ULONG rc;
   4.274 +  struct tmem_op tmem_op;
   4.275 +
   4.276 +  UNREFERENCED_PARAMETER(data);
   4.277 +  UNREFERENCED_PARAMETER(flt_objects);
   4.278 +  UNREFERENCED_PARAMETER(completion_context);
   4.279 +
   4.280 +  if (!FsRtlIsPagingFile(flt_objects->FileObject)) {
   4.281 +    return FLT_PREOP_SUCCESS_NO_CALLBACK;
   4.282 +  }
   4.283 +
   4.284 +  KeAcquireSpinLock(&global_context.lock, &old_irql);
   4.285 +  for (context = global_context.pagefile_head; context; context = context->next) {
   4.286 +    if (context->file_object == flt_objects->FileObject)
   4.287 +      break;
   4.288 +  }
   4.289 +  if (!context) {
   4.290 +    context = ExAllocatePoolWithTag(NonPagedPool, sizeof(pagefile_context_t), XENCACHE_POOL_TAG);
   4.291 +    if (!context) {
   4.292 +      FUNCTION_MSG("Failed to allocate context\n");
   4.293 +      /* should probably detach this instance here */
   4.294 +      KeReleaseSpinLock(&global_context.lock, old_irql);
   4.295 +      FUNCTION_EXIT();
   4.296 +      return FLT_PREOP_SUCCESS_NO_CALLBACK;
   4.297 +    }
   4.298 +    RtlZeroMemory(context, sizeof(pagefile_context_t));
   4.299 +    context->file_object = flt_objects->FileObject;
   4.300 +    context->next = global_context.pagefile_head;
   4.301 +    tmem_op.cmd = TMEM_NEW_POOL;
   4.302 +    tmem_op.pool_id = 0; /* this doesn't actually get used for private */
   4.303 +    tmem_op.u.new.flags = (TMEM_SPEC_VERSION << TMEM_VERSION_SHIFT); /* private, not shared */
   4.304 +    context->pool_id = XnTmemOp(&tmem_op);
   4.305 +    FUNCTION_MSG("pool_id = %d\n", context->pool_id);
   4.306 +    global_context.pagefile_head = context;
   4.307 +  }
   4.308 +  if (!(data->Flags & FLTFL_CALLBACK_DATA_IRP_OPERATION)) {
   4.309 +    KeReleaseSpinLock(&global_context.lock, old_irql);
   4.310 +    return FLT_PREOP_SUCCESS_NO_CALLBACK;
   4.311 +  }
   4.312 +
   4.313 +  for (i = 0; i < (int)data->Iopb->Parameters.Write.Length >> PAGE_SHIFT; i++) {
   4.314 +    ULONG page = (ULONG)(data->Iopb->Parameters.Write.ByteOffset.QuadPart >> PAGE_SHIFT) + i;
   4.315 +    
   4.316 +    tmem_op.cmd = TMEM_PUT_PAGE;
   4.317 +    tmem_op.pool_id = context->pool_id;
   4.318 +    tmem_op.u.gen.oid[0] = 0;
   4.319 +    tmem_op.u.gen.oid[1] = 0;
   4.320 +    tmem_op.u.gen.oid[2] = 0;
   4.321 +    tmem_op.u.gen.index = page;
   4.322 +    tmem_op.u.gen.tmem_offset = 0;
   4.323 +    tmem_op.u.gen.pfn_offset = 0;
   4.324 +    tmem_op.u.gen.len = 0;
   4.325 +    set_xen_guest_handle(tmem_op.u.gen.gmfn, (void *)MmGetMdlPfnArray(data->Iopb->Parameters.Write.MdlAddress)[i]);
   4.326 +    rc = XnTmemOp(&tmem_op);
   4.327 +    if (rc == 1) {
   4.328 +      context->put_success_count++;
   4.329 +    } else if (rc == 0) {
   4.330 +      context->put_fail_count++;
   4.331 +    } else {
   4.332 +      FUNCTION_MSG("TMEM_PUT_PAGE = %d\n", rc);
   4.333 +    }
   4.334 +  }
   4.335 +  KeReleaseSpinLock(&global_context.lock, old_irql);
   4.336 +  if (((context->put_success_count + context->put_fail_count + context->get_success_count + context->get_fail_count) & 0xff) == 0) {
   4.337 +    FUNCTION_MSG("   put_success_count = %I64d\n", context->put_success_count);
   4.338 +    FUNCTION_MSG("   put_fail_count    = %I64d\n", context->put_fail_count);
   4.339 +    FUNCTION_MSG("   get_success_count = %I64d\n", context->get_success_count);
   4.340 +    FUNCTION_MSG("   get_fail_count    = %I64d\n", context->get_fail_count);
   4.341 +  }
   4.342 +  return FLT_PREOP_SUCCESS_NO_CALLBACK;
   4.343 +}
   4.344 +
   4.345 +FLT_PREOP_CALLBACK_STATUS
   4.346 +XenCache_Pre_READ(PFLT_CALLBACK_DATA data, PCFLT_RELATED_OBJECTS flt_objects, PVOID *completion_context) {
   4.347 +  NTSTATUS status;
   4.348 +  pagefile_context_t *context;
   4.349 +  KIRQL old_irql;
   4.350 +  int i;
   4.351 +  ULONG rc;
   4.352 +  struct tmem_op tmem_op;
   4.353 +  
   4.354 +  UNREFERENCED_PARAMETER(data);
   4.355 +  UNREFERENCED_PARAMETER(flt_objects);
   4.356 +  UNREFERENCED_PARAMETER(completion_context);
   4.357 +
   4.358 +  if (!FsRtlIsPagingFile(flt_objects->FileObject)) {
   4.359 +    return FLT_PREOP_SUCCESS_NO_CALLBACK;
   4.360 +  }
   4.361 +  KeAcquireSpinLock(&global_context.lock, &old_irql);
   4.362 +  for (context = global_context.pagefile_head; context; context = context->next) {
   4.363 +    if (context->file_object == flt_objects->FileObject)
   4.364 +      break;
   4.365 +  }
   4.366 +  if (!context) {
   4.367 +    /* no need to create context if op is a READ - either something is wrong or we were just loaded */
   4.368 +    //FUNCTION_MSG("Failed to find context\n");
   4.369 +    KeReleaseSpinLock(&global_context.lock, old_irql);
   4.370 +    return FLT_PREOP_SUCCESS_NO_CALLBACK;
   4.371 +  }    
   4.372 +  if (!(data->Flags & FLTFL_CALLBACK_DATA_IRP_OPERATION)) {
   4.373 +    KeReleaseSpinLock(&global_context.lock, old_irql);
   4.374 +    return FLT_PREOP_SUCCESS_NO_CALLBACK;
   4.375 +  }
   4.376 +
   4.377 +  status = FLT_PREOP_COMPLETE;
   4.378 +  for (i = 0; i < (int)data->Iopb->Parameters.Read.Length / 4096; i++) {
   4.379 +    ULONG page = (ULONG)(data->Iopb->Parameters.Read.ByteOffset.QuadPart >> PAGE_SHIFT) + i;
   4.380 +    
   4.381 +    tmem_op.cmd = TMEM_GET_PAGE;
   4.382 +    tmem_op.pool_id = context->pool_id;
   4.383 +    tmem_op.u.gen.oid[0] = 0;
   4.384 +    tmem_op.u.gen.oid[1] = 0;
   4.385 +    tmem_op.u.gen.oid[2] = 0;
   4.386 +    tmem_op.u.gen.index = page;
   4.387 +    tmem_op.u.gen.tmem_offset = 0;
   4.388 +    tmem_op.u.gen.pfn_offset = 0;
   4.389 +    tmem_op.u.gen.len = 0;
   4.390 +    set_xen_guest_handle(tmem_op.u.gen.gmfn, (void *)MmGetMdlPfnArray(data->Iopb->Parameters.Read.MdlAddress)[i]);
   4.391 +    rc = XnTmemOp(&tmem_op);
   4.392 +    if (rc == 1) {
   4.393 +      context->get_success_count++;
   4.394 +    } else if (rc == 0) {
   4.395 +      status = FLT_PREOP_SUCCESS_NO_CALLBACK;
   4.396 +      context->get_fail_count++;
   4.397 +    } else {
   4.398 +      FUNCTION_MSG("TMEM_GET_PAGE = %d\n", rc);
   4.399 +      status = FLT_PREOP_SUCCESS_NO_CALLBACK;
   4.400 +      context->get_fail_count++;
   4.401 +    }
   4.402 +  }
   4.403 +  
   4.404 +  if (((context->put_success_count + context->put_fail_count + context->get_success_count + context->get_fail_count) & 0xff) == 0) {
   4.405 +    FUNCTION_MSG("   put_success_count = %I64d\n", context->put_success_count);
   4.406 +    FUNCTION_MSG("   put_fail_count    = %I64d\n", context->put_fail_count);
   4.407 +    FUNCTION_MSG("   get_success_count = %I64d\n", context->get_success_count);
   4.408 +    FUNCTION_MSG("   get_fail_count    = %I64d\n", context->get_fail_count);
   4.409 +  }
   4.410 +  KeReleaseSpinLock(&global_context.lock, old_irql);
   4.411 +
   4.412 +  if (status == FLT_PREOP_COMPLETE) {
   4.413 +    data->IoStatus.Status = STATUS_SUCCESS;
   4.414 +    data->IoStatus.Information = data->Iopb->Parameters.Read.Length;
   4.415 +  }
   4.416 +  return status;
   4.417 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xencache/xencache.h	Sun Jun 02 16:38:50 2013 +1000
     5.3 @@ -0,0 +1,56 @@
     5.4 +/*
     5.5 +PV Drivers for Windows Xen HVM Domains
     5.6 +Copyright (C) 2013 James Harper
     5.7 +
     5.8 +This program is free software; you can redistribute it and/or
     5.9 +modify it under the terms of the GNU General Public License
    5.10 +as published by the Free Software Foundation; either version 2
    5.11 +of the License, or (at your option) any later version.
    5.12 +
    5.13 +This program is distributed in the hope that it will be useful,
    5.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.16 +GNU General Public License for more details.
    5.17 +
    5.18 +You should have received a copy of the GNU General Public License
    5.19 +along with this program; if not, write to the Free Software
    5.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    5.21 +*/
    5.22 +
    5.23 +#pragma warning(disable: 4127)
    5.24 +
    5.25 +#pragma warning(disable : 4200) // zero-sized array
    5.26 +
    5.27 +#if !defined(_XENCACHE_H_)
    5.28 +#define _XENCACHE_H_
    5.29 +
    5.30 +#define __DRIVER_NAME "XenCache"
    5.31 +
    5.32 +#define XENCACHE_POOL_TAG (ULONG)'XenC'
    5.33 +
    5.34 +#include <fltkernel.h>
    5.35 +#define NTSTRSAFE_LIB
    5.36 +#include <ntstrsafe.h>
    5.37 +#include <xen_windows.h>
    5.38 +
    5.39 +typedef struct _pagefile_context_t pagefile_context_t;
    5.40 +typedef struct _global_context_t global_context_t;
    5.41 +
    5.42 +struct _global_context_t {
    5.43 +  KSPIN_LOCK lock;
    5.44 +  pagefile_context_t *pagefile_head;
    5.45 +};
    5.46 +  
    5.47 +struct _pagefile_context_t {
    5.48 +  pagefile_context_t *next;
    5.49 +  global_context_t *global;
    5.50 +  PFILE_OBJECT file_object;
    5.51 +  ULONG pool_id;
    5.52 +
    5.53 +  ULONGLONG put_success_count;
    5.54 +  ULONGLONG put_fail_count;
    5.55 +  ULONGLONG get_success_count;
    5.56 +  ULONGLONG get_fail_count;
    5.57 +};
    5.58 +
    5.59 +#endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xencache/xencache.inx	Sun Jun 02 16:38:50 2013 +1000
     6.3 @@ -0,0 +1,53 @@
     6.4 +[Version]
     6.5 +Signature="$WINDOWS NT$"
     6.6 +Class=ActivityMonitor
     6.7 +ClassGuid={b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}
     6.8 +Provider=%XenGplPv%
     6.9 +CatalogFile="xencache.cat"
    6.10 +
    6.11 +[DestinationDirs]
    6.12 +DefaultDestDir = 12
    6.13 +
    6.14 +[DefaultInstall]
    6.15 +OptionDesc=%XenCache.SVCDESC%
    6.16 +CopyFiles=XenCache.CopyFiles
    6.17 +
    6.18 +[DefaultInstall.Services]
    6.19 +AddService=XenCache,,XenCache_Service
    6.20 +
    6.21 +[DefaultUninstall]
    6.22 +DelFiles=XenCache.CopyFiles
    6.23 +
    6.24 +[DefaultUninstall.Services]
    6.25 +DelService=XenCache,0x200
    6.26 +
    6.27 +[XenCache_Service]
    6.28 +DisplayName    = %XenCache.SVCDESC%                            
    6.29 +ServiceBinary  = %12%\xencache.sys
    6.30 +Dependencies   = FltMgr
    6.31 +ServiceType    = 2
    6.32 +StartType      = 3
    6.33 +ErrorControl   = 1
    6.34 +LoadOrderGroup = "FSFilter Top"
    6.35 +AddReg = XenCache_Service.AddReg
    6.36 +
    6.37 +[XenCache_Service.AddReg]
    6.38 +HKR,,"DebugFlags",0x00010001 ,0x0
    6.39 +HKR,"Instances","DefaultInstance",0x00000000,XenCache
    6.40 +HKR,"Instances\XenCache","Altitude",0x00000000,123456
    6.41 +HKR,"Instances\XenCache","Flags",0x00010001,0
    6.42 +
    6.43 +[XenCache.CopyFiles]
    6.44 +xencache.sys
    6.45 +
    6.46 +[SourceDisksFiles]
    6.47 +xencache.sys=1
    6.48 +
    6.49 +[SourceDisksNames]
    6.50 +1 = %DISK_NAME%
    6.51 +
    6.52 +[Strings]
    6.53 +XenGplPv = "Xen GPL PV Driver Developers"
    6.54 +XenCache.SVCDESC = "Xen Cache Device Driver"
    6.55 +XenCache.DRVDESC = "Xen Cache Device Driver"
    6.56 +DISK_NAME = "Xen Cache Device Driver Install Disk"
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/xencache/xencache.rc	Sun Jun 02 16:38:50 2013 +1000
     7.3 @@ -0,0 +1,28 @@
     7.4 +#include <windows.h>
     7.5 +#include <ntverp.h>
     7.6 +#include "gplpv_version.h"
     7.7 +
     7.8 +#define VER_FILETYPE                VFT_DRV
     7.9 +#define VER_FILESUBTYPE             VFT2_DRV_SYSTEM
    7.10 +#ifdef DEBUG
    7.11 +  #define VER_FILEDESCRIPTION_STR     "GPLPV XenCache Driver"
    7.12 +#else
    7.13 +  #define VER_FILEDESCRIPTION_STR     "GPLPV XenCache Driver (Checked Build)"
    7.14 +#endif
    7.15 +#define VER_INTERNALNAME_STR        "xencache.sys"
    7.16 +#define VER_ORIGINALFILENAME_STR    "xencache.sys"
    7.17 +
    7.18 +#undef VER_PRODUCTVERSION
    7.19 +#define VER_PRODUCTVERSION          VER_FILEVERSION
    7.20 +#undef VER_PRODUCTVERSION_STR
    7.21 +#define VER_PRODUCTVERSION_STR      VER_FILEVERSION_STR
    7.22 +#define VER_LEGALCOPYRIGHT_STR      "Copyright (C) 2013 James Harper" 
    7.23 +
    7.24 +#ifdef VER_COMPANYNAME_STR
    7.25 +#undef VER_COMPANYNAME_STR
    7.26 +#define VER_COMPANYNAME_STR         "James Harper"
    7.27 +#endif
    7.28 +#undef VER_PRODUCTNAME_STR
    7.29 +#define VER_PRODUCTNAME_STR         "PV Drivers for Windows"
    7.30 +
    7.31 +#include "common.ver"