|
Upgrading Privileged-Code Applications on OpenVMS Alpha and
OpenVMS I64 Systems
B.17 MMG_STD$IOLOCK, MMG$IOLOCK, MMG_STD$IOLOCK_BUF
The interface for the MMG_STD$IOLOCK routine is:
int mmg_std$iolock (void *buf, int bufsiz, int is_read, PCB *pcb, void **svapte_p)
|
This routine returns a 32-bit address by reference (thesvapte_p parameter)
which, depending on the routine status, may specify the address of the first
PTE or the address of a location in the buffer that must be faulted in.
The new version of this routine must accept a 64-bit buffer address. In addition,
the new version must also return either a 64-bit PTE or buffer address. This
is an incompatible interface change because this return parameter is passed
by reference. Thus, MMG_STD$IOLOCK has been removed and is replaced by the
new MMG_STD$IOLOCK_BUF routine.
The interface for MMG_STD$IOLOCK_BUF is:
int mmg_std$iolock_buf (VOID_PQ const buf, const int bufsiz, const int is_read, PCB *const pcb, PTE_PPQ va_pte_p, VOID **fault_va_p)
|
Table B-14 summarizes the use of
the arguments.
Table B-14 MMG_STD$IOLOCK_BUF Arguments
Argument |
Type |
Access |
Description |
buf |
VOID_PQ |
Input |
64-bit pointer to the buffer that is to be locked. |
bufsiz |
int |
Input |
Size of the buffer in bytes. |
is_read |
int |
Input |
Contains the value 0 if buffer will be only written to the device, 1
if the buffer will be only read from device, 5 if the buffer will be modified
by the device. |
pcb |
PCB * |
Input |
Pointer to the process PCB. |
va_pte_p |
PTE_PPQ |
Output |
Pointer to a 64-bit PTE address that is returned. If the returned value
of the function is successful, then the address returned is the 64-bit
virtual address of the first PTE that maps the buffer. For all other function
return values, the value returned in this parameter is undefined. |
fault_va_p |
VOID_PPQ |
Output |
Pointer to a 64-bit address that is returned. If the returned value
of the function is zero, then the address returned is the 64-bit address
within the buffer that must be faulted in. For all other function return
values, the value returned in this parameter is undefined. |
The returned value of this routine is a system condition value or the value
zero:
|
Success |
A successful VMS condition value indicates that the buffer has been
locked and that the 64-bit virtual address of the first PTE that maps the
buffer has been returned using the va_pte_p parameter. |
|
0 |
This return value means that a page fault is required for a page in
the buffer. The virtual address of the page is returned using the fault_va_p
parameter. Any portion of the buffer that may have been locked before this
condition was detected has been unlocked before returning. |
|
Failure |
Standard VMS condition value that indicates the failure. |
Just like MMG_STD$IOLOCK, the MMG_STD$IOLOCK_BUF routine must be called in
process context at IPL 2 and it acquires and releases the MMG spinlock.
Although the interfaces for the MMG_STD$IOLOCK_BUF and MMG_STD$IOLOCK routines
are similar, there are important differences between these routines that go
beyond the width of the address parameters.
- The 32-bit address that is returned by MMG_STD$IOLOCK in thesvapte_p parameter
is valid regardless of process context. In contrast, the 64-bit address that
is returned by MMG_STD$IOLOCK_BUF in theva_pte_p parameter
may be valid only in the context of the current process. The new routines
IOC_STD$FILL_DIOBM and IOC_STD$CREATE_DIOBM are designed to deal with this
difference.
- The MMG_STD$IOLOCK routine locks into memory the level-3 page tables that
contain the PTEs that map the buffer as well as the buffer pages. In contrast,
MMG_STD$IOLOCK_BUF only locks the buffer pages. It does not lock the level-3
page tables because it would be difficult to unlock them in the absence of
process context where MMG_STD$IOUNLOCK_BUF is called. Moreover, the mechanisms
used by IOC_STD$FILL_DIOBM and IOC_STD$CREATE_DIOBM usually do not require
the locking of the level-3 page tables. Only when the PTE window method is
used by IOC_STD$FILL_DIOBM or IOC_STD$CREATE_DIOBM will these routines need
to lock the level-3 page table pages into memory. When this case applies,
the IOC_STD$RELEASE_DIOBM routine has enough information to unlock the level-3
page tables regardless of process context.
The existing callers of MMG_STD$IOLOCK need to be very aware of the first
of these differences. The second difference is likely to be transparent to
most callers.
Because the routine MMG$IOLOCK is simply a JSB-to-CALL jacket routine around
MMG_STD$IOLOCK, the MMG$IOLOCK routine has also been removed.
B.17.1 CALL_IOLOCK Macro
The CALL_IOLOCK MACRO-32 macro facilitates the use of the MMG_STD$IOLOCK routine
by code that was originally written to use the JSB-interface counterpart MMG$IOLOCK.
The CALL_IOLOCK macro has implicit register inputs and outputs that correspond
to the register inputs and outputs of the JSB-interface for the MMG$IOLOCK
routine.
Because this macro uses registers for its inputs and outputs, it can be altered
to use the full 64-bit values in these registers and it can call the MMG_STD$IOLOCK_BUF
routine instead of MMG_STD$IOLOCK. Nevertheless, the CALL_IOLOCK macro has
been modified to generate a suppressable interface warning at compile-time,
because:
- The full 64-bits of register R1 are now significant on return.
- The returned PTE address is a 64-bit process virtual address.
- Callers of MMG_STD$IOLOCK_BUF are very likely to need to call the new IOC_STD$FILL_DIOBM
or IOC_STD$CREATE_DIOBM routines.
The format of the macro call is:
CALL_IOLOCK [ INTERFACE_WARNING=YES|NO ]
|
By default the interface warning is enabled and generates the following warning
at compile-time:
%AMAC-W-GENWARN, generated WARNING: 0 CALL_IOLOCK interface has changed for 64-bit virtual addressing; set INTERFACE_WARNING=NO to disable messages. %AMAC-W-GENWARN, generated WARNING: 0 CALL_IOLOCK uses the 64-bit buffer address in R0 %AMAC-W-GENWARN, generated WARNING: 0 CALL_IOLOCK returns a 64-bit VA_PTE or fault VA in R1 %AMAC-W-GENWARN, generated WARNING: 0 CALL_IOLOCK does not lock the page table pages %AMAC-W-GENWARN, generated WARNING: 0 A call to IOC_STD$FILL_DIOBM may be required to derive a SVAPTE
|
The compile-time warning serves to identify the existing callers of this macro.
Once the invoking code has been modified, the warning can be suppressed by
specifying INTERFACE_WARNING=NO.
B.18 MMG_STD$UNLOCK, MMG$UNLOCK, MMG_STD$IOUNLOCK_BUF
The interface for the MMG_STD$UNLOCK routine is:
void mmg_std$unlock (int npages, void *svapte)
|
The MMG$UNLOCK routine is simply a JSB-to-CALL jacket routine around MMG_STD$UNLOCK.
Because 32-bit PTE addresses that may point to PTE copies are sufficient for
the needs of the MMG_STD$UNLOCK routine, there is no absolute requirement to
change the interface of these routines. However, it is extremely likely that
all callers of MMG_STD$UNLOCK and MMG$UNLOCK need to use the new DIOBM structure
and need to call the new routine IOC_STD$RELEASE_DIOBM immediately after unlocking
the memory buffer. Therefore, routine MMG_STD$UNLOCK has been renamed to MMG_STD$IOUNLOCK_BUF
and the MMG$UNLOCK routine has been removed in order to make it difficult to
miss the places where this source change is needed.
The interface for MMG_STD$IOUNLOCK_BUF is:
void mmg_std$iounlock_buf (const int npages, PTE_PQ const va_pte);
|
Just like MMG_STD$UNLOCK, the MMG_STD$IOUNLOCK_BUF routine does not depend
on process context. However, the IPL and spinlocks of the caller must allow
this routine to acquire and restore the MMG spinlock.
|