Page Locking and Mapping

A virtual device cannot access swappable pages while processing hardware interrupts because doing so may trigger a page fault. A virtual device can avoid page faults by committing pages as fixed, or by temporarily locking pages when necessary — for example, during a device input or output operation. Locking a page forces it to remain physically present at a fixed address until it is unlocked.

You can lock a range of pages by using the _LinPageLock service. The pages remain locked until they are unlocked using the _LinPageUnLock service. The system maintains a lock count for each page. Thus, you can lock a page more than once. You must unlock a page once for each time it is locked unless you specify the PL_TOTALUNLOCK flag to bring the lock count to zero. (But don't use the PL_TOTALUNLOCK flag. It is mentioned here only for completeness.)

You can specify the PAGELOCKEDIFDP flag with the _LinPageLock service, in which case the pages are locked only if the pager uses MS-DOS or BIOS functions to perform file operations. You should use this flag for pages that need to be touched while a virtual device owns the critical section. Because MS-DOS is not reentrant, it cannot be called while the critical section is owned. For the same reason, VxD_PAGEABLE_CODE_SEG and VxD_PAGEABLE_DATA_SEG segments are automatically locked when MS-DOS is used for paging.

Warning

You cannot call memory manager services while any virtual machine holds the critical section, unless you ensure that MS-DOS is not used for paging. For more information about critical sections, see Synchronization.

If a virtual device must access a range of pages in the private arena regardless of the current memory context, it must map the pages to a range linear addresses outside the private arena. To do so, use the _LinPageLock service with the PAGEMAPGLOBAL flag. When you unlock the pages using the _LinPageUnlock service, you must specify the same flag to undo the mapping. You must also pass the global alias as the page to unlock rather than the original private page. Failure to observe either of these two rules will leak critical system memory and eventually crash the machine.

You can use the _PageLock and _PageUnLock services to lock a range of pages. However, these services are more difficult to use than the _LinPageLock and _LinPageUnLock services, and offer no performance advantage. Also, you cannot map pages into shared memory by using the _PageLock service. The _PageLock and _PageUnLock services exist primarily for compatibility with Windows 3.1 virtual devices.

Do not attempt to lock uncommitted pages. You can verify that all pages in a given range are committed by using the _PageCheckLinRange service. Locking pages that were committed as fixed has no effect, but consumes just as much time as locking swappable pages.

In addition to the services described here, the VMM provides services for mapping pages into VMs. For more information about such services, see V86 Address Space Mapping and Allocation. For information about services that convert selector:offset addresses to linear addresses, see Selector Management.

See also _LinPageLock, _LinPageUnLock, _PageLock, _PageUnLock, _PageCheckLinRange