[ Bottom of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]

Technical Reference: Kernel and Subsystems, Volume 1

saveretval64 Kernel Service

Purpose

The saveretval64 kernel service allows a 64-bit value to be returned from a 32-bit kernel extension function to a 64-bit process.

Syntax

#include <sys/remap.h>

unsigned long long saveretval64 (unsigned long long retval);
unsigned long long retval;

Parameters

retval Specifies the 64-bit value to be returned as a pointer, long, unsigned long, long long, or unsigned long long to a 64-bit process.

Description

In 64-bit programs, pointers and longs are 64-bit types, and a long long fits in a single general purpose register. In the 32-bit kernel, the only 64-bit type is a long long, which occupies two general purpose registers. In order to return a 64-bit value to a 64-bit process, the saveretval64 kernel service is called, which saves the low-order word of the return value. The system call then returns the high-order word. The system call handler combines the two halves of the return value before returning control to the 64-bit application program.

Return Values

The retval parameter is returned. If the current process is a 32-bit process, the panic kernel service is called.



Examples

  1. Suppose a system call returns a 64-bit pointer. The system call could be written as follows:
    #include <sys/user.h>       /* For IS64U() */
    #include <sys/types.h>       /* For __ptr64 and __64BIT_KERNEL */
    #include <sys/remap.h>
    
    void *
    my_syscall(int arg)
    {
           __ptr64 retval = my_syscall_implementation(arg);
    
    #ifndef __64BIT_KERNEL
           if (IS64U)
           {
                  /* Return value must be shifted to return high-order word */
                  return (void *)(saveretval64(retval)>>32); 
           }
    #endif
           return retval;
    }
  2. If the system call returns a long long (signed or unsigned), the code can be simplified.
    #include <sys/user.h>
    #include <sys/remap.h>
    long long
    my_syscall2(int arg)
    {
           long long retval = my_syscall2_implementation(arg);
    
           if (IS64U)
           {
                  /* High-order word of a long long is returned in
                     general purpose register 3.  No shifting is necessary. */
                  return (long long)(saveretval64(retval));
           }
           return retval;
    }
    
    The saveretval64() kernel service is not needed when the 64-bit kernel is running, because 64-bit values fit in a single general purpose register. To allow for common code, the saveretval64() kernel service is defined as a macro that returns its argument, when a kernel extension is compiled in 64-bit mode.

Execution Environment

This kernel service can only be called from the process environment when the current process is in 64-bit mode.

Implementation Specifics

The saveretval64 kernel service is only available on the 32-bit PowerPC kernel.

Related Information

The get64bitparm kernel service, as_remap64 kernel service.

[ Top of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]