  | 
		
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.
 
  
  
		 |