Document revision date: 30 March 2001

## OpenVMS Alpha Guide to Upgrading Privileged-Code Applications

Previous | Contents | Index

## B.15 IOC_STD$VA_TO_PA

Routine IOC_STD$VA_TO_PA is a new routine that is used to derive a 64-bit physical memory address for a 64-bit virtual address. The virtual address is interpreted in the context of the current process and may be in either process-private or system space.

It is the caller's responsibility to ensure that the virtual address is a legal address and that the memory page containing the specified virtual address is locked into memory prior to calling this routine. The IOC_STD$VA_TO_PA routine may declare a bugcheck if either of these conditions have not been met.

The interface for IOC_STD$VA_TO_PA is:

    VOID_PQ ioc_std$va_to_pa (VOID_PQ va, VOID_PPQ pa_p)

The returned value of this routine is the 64-bit physical address. Table B-12 summarizes the use of the arguments.

Table B-12 IOC_STD$VA_TO_PA Arguments
Argument | Type | Access | Description
--- | --- | --- | ---
va | VOID_PQ | Input | A 64-bit virtual address.
pa_p | VOID_PPQ | Output | Pointer to a 64-bit physical address that is returned. This parameter is optional and may either be omitted entirely or specified as zero. The physical address is also returned as the value of the routine.

Currently, the physical address for a process virtual address can be derived by calling MMG_STD$SVAPTECHK followed by IOC$SVAPTE_TO_PA. However, as described in Section 2.2.3, the MMG_STD$SVAPTECHK routine no longer accepts a P0/P1 address. The new IOC_STD$VA_TO_PA routine provides a direct way of computing the physical address from a process virtual address.

## B.16 MMG_STD$GET_PTE_FOR_VA

Routine MMG_STD$GET_PTE_FOR_VA is a new routine that is being added for use in the Remote SDA SYSAP within SYS$SCS.

Routine MMG_STD$GET_PTE_FOR_VA attempts to obtain the Level-3 PTE containing a PFN that maps the specified virtual address for a specified process. If the requested PTE cannot be accessed either because the virtual address is not mapped or a needed page table page is not currently in physical memory, an error status is returned. Additionally, if the Level-3 PTE does not contain a useable PFN, an error status is returned.

A successful return status from this routine means that the PFN field of the returned PTE contains the physical page number for the input virtual address. Note that there are page states where the PTE contains a useable PFN but the PTE$V_VALID bit is clear. Therefore, the PTE$V_VALID bit in the returned PTE might be clear. Note also, that this routine returns a PTE from the Global Page Table when the slave PTE has reverted to GPTX format and the master PTE in the GPT still contains a PFN.

This routine is somewhat similar to MMG_STD$CALC_VAPTE except that it does not assume that the virtual address is valid or that the necessary page tables are resident in memory. Because this routine does not assume the virtual address is valid, it uses the reserved system space window to traverse the specified process' page tables in a top-down fashion. It uses this method for all process-private virtual addresses even if the specified process happens to be the current process on this CPU. This allows this routine to locate the Level-3 PTE even if some of the intervening page table pages are in transition. However, for shared system space virtual addresses this routine uses the currently active page tables instead of the reserved system window to locate the corresponding Level-3 PTE. This is possible because shared system space page table pages are not pageable and have PTE$V_VALID set if they are mapped.

This routine acquires and restores the MMG spinlock. This routine declares a bugcheck if the reserved system space window is already in use. This routine releases and invalidates the window before returning.

The interface for MMG_STD$GET_PTE_FOR_VA is:

    int mmg_std$get_pte_for_va (VOID_PQ const va, PHD *const phd, PTE_PQ pte_p)

Table B-13 summarizes the use of the arguments.

Table B-13 MMG_STD$GET_PTE_FOR_VA Arguments
Argument | Type | Access | Description
--- | --- | --- | ---
va | VOID_PQ | Input | A 64-bit virtual address.
phd | PHD * | Input | Pointer to the PHD for the desired process address space. If zero, the current process on the current CPU is assumed. This parameter is not used, and may be zero, if the virtual address is in shared system space.
pte_p | PTE_PQ | Output | Address of Level-3 PTE value that is returned. A PTE value is returned only if the routine returns a successful condition value.

The returned value of this routine is a system condition value:

| SS$_NORMAL | The PTE that maps the specified virtual address in the address space of the specified process contains a physical page number and was successfully returned.
| SS$_ACCVIO | The PTE that maps the specified virtual address in the address space of the specified process could not be obtained, that is, the specified virtual address is not mapped or one of the necessary page table pages is not currently resident, or the level-3 PTE did not contain a physical page number.

## 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 (the `svapte_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.

1. The 32-bit address that is returned by MMG_STD$IOLOCK in the `svapte_p` parameter is valid regardless of process context. In contrast, the 64-bit address that is returned by MMG_STD$IOLOCK_BUF in the `va_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.
2. 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.

### B.18.1 CALL_UNLOCK Macro

The CALL_UNLOCK MACRO-32 macro facilitates the use of the MMG_STD$UNLOCK routine by code that was originally written to use the JSB-interface counterpart MMG$UNLOCK. The CALL_UNLOCK macro has implicit register inputs that correspond to the register inputs and outputs of the JSB-interface for the MMG$UNLOCK routine.

This macro has been modified to use the full 64-bits of the R3 input which contains the PTE address. The macro calls the new MMG_STD$IOUNLOCK_BUF routine instead of MMG_STD$UNLOCK. In addition, the CALL_UNLOCK macro has been modified to generate a suppressable interface warning at compile-time. The format of the macro call is:

    CALL_UNLOCK    [ 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_UNLOCK interface has changed for 64-bit
    virtual addressing; set INTERFACE_WARNING=NO to disable messages.
    %AMAC-W-GENWARN, generated WARNING: 0 CALL_UNLOCK uses the 64-bit PTE address in R3
    %AMAC-W-GENWARN, generated WARNING: 0 CALL_UNLOCK does not unlock the page table
    pages
    %AMAC-W-GENWARN, generated WARNING: 0 A call to IOC_STD$RELEASE_DIOBM may be
    required to derive a SVAPTE

## B.19 MMG_STD$SVAPTECHK, MMG$SVAPTECHK

The current versions of the MMG_STD$SVAPTECHK and MMG$SVAPTECHK routines compute a 32-bit `svapte` for either a process or system space address. As of OpenVMS Alpha Version 7.0, these routines are be restricted to an S0/S1 system space address and no longer accept an address in P0/P1 space. The MMG_STD$SVAPTECHK and MMG$SVAPTECHK routines check the full 64 bits of the input address and declare a bugcheck for an input address that is not in S0/S1 space. For S0/S1 input addresses, these routines return a 32-bit system virtual address of the PTE through the SPT window.

In releases prior to OpenVMS Alpha Version 7.0, the interface for this routine was:

    void mmg_std$svaptechk (void *va, PCB *pcb, PHD *phd, void **svapte_p);

The new interface for this routine is:

    void mmg_std$svaptechk (VOID_PQ va, PCB *pcb, PHD *phd, PTE **svapte_p);

The majority of callers of this routine use it with an S0/S1 address and do not need to change.

## Appendix C
Kernel Threads Routines and Macros

This appendix describes the new routines and macros available implementing for kernel threads.

In addition to a few new routines to convert a PID to a KTB address, the EXE$NAM_TO_PCB routine is modified to return the KTB address in R2, which previously was a scratch register. The new routines and macros all assume the caller is executing in kernel mode.

## EXE$CVT_IPID_TO_KTB Routine

> Converts an internal PID to a KTB address.

### Format

> EXE$CVT_IPID_TO_KTB ipid ,ktb ,pcb

### RETURNS

> OpenVMS usage | cond_value
> type | longword (unsigned)
> access | write only
> mechanism | by value

> Status indicating the success or failure of the operation.

### Arguments

> #### ipid

> OpenVMS usage | process_id
> type | longword (unsigned)
> access | read
> mechanism | by value

> This argument provides the internal PID to be converted.

> #### ktb

> OpenVMS usage | address
> type | quadword
> access | write
> mechanism | by reference

> This argument provides the KTB address.

> #### pcb

> OpenVMS usage | address
> type | quadword
> access | write
> mechanism | by reference

> This argument provides the PCB address.

### Description

> The EXE$CVT_IPID_TO_KTB routine converts an internal PID to a KTB address.

### Return Values

> SS$_NONEXPR | The process does not exist.
> SS$_NOSUCHTHREAD | The process exists but the thread does not.

## EXE$CVT_EPID_TO_KTB Routine

> Converts an external PID to a KTB address.

### Format

> EXE$CVT_EPID_TO_KTB epid ,ktb ,pcb

### RETURNS

> OpenVMS usage | cond_value
> type | longword (unsigned)
> access | write only
> mechanism | by value

> Status indicating the success or failure of the operation.

### Arguments

> #### epid

> OpenVMS usage | process_id
> type | longword (unsigned)
> access | read
> mechanism | by value

> This argument provides the external PID to be converted.

> #### ktb

> OpenVMS usage | address
> type | quadword
> access | write
> mechanism | by reference

> This argument provides the KTB address.

> #### pcb

> OpenVMS usage | address
> type | quadword
> access | write
> mechanism | by reference

> This argument provides the PCB address.

### Description

> The EXE$CVT_EPID_TO_KTB routine converts an external PID to a KTB address.

### Return Values

> SS$_NONEXPR | The process does not exist.
> SS$_NOSUCHTHREAD | The process exists but the thread does not.

Previous | Next | Contents | Index

| privacy and legal statement |
6466PRO_010.HTML