Embedded Hypervisor ABI (draft)

Hypercall Instruction

The hypercall instruction on legacy Book E implementations shall be the pattern 0x03ffffff (opcode 0, which guaranteed to be an illegal instruction on hardware). Using an instruction which is recognized as a Program interrupt, rather than a variant of the sc instruction, will ensure that intra-guest system calls are not accidentally interpreted as hypercalls.

There is a performance penalty, since the host's Program Interrupt handler must perform a load from the guest effective address of the faulting instruction (specified in SRR0) in order to recognize a hypercall. However, the Program Interrupt handler is not likely to be performance-sensitive, and the overhead relative to a full hypercall is not likely to be significant.

Programming Note: When running on implementations which implement the "embedded hypervisor" architecture, the guest or host may replace the guest hypercall instructions with the architecturally defined hypercall instruction at runtime.

Parameter Passing

The hypercall number shall be contained in r0 (like system calls in most PowerPC ABIs).

Input parameters shall be contained in r3 through r11, inclusive.

Hypercalls shall return a success code and place this value in r11.

Further output parameters shall be contained in r3 through r10, inclusive.

If more data must be transferred in either direction in a single hypercall, that data must be placed into memory, and that must be specified by the hypercall API (the ABI does not define this behavior).

Summary of Register Usage

Contents of registers that are considered "Volatile" will not be preserved across a hypercall invocation:

Register

Description

r0

Volatile Hypercall Token

r1-r2

Non-Volatile

r3 - r10

Volatile input parameters and output values

r11

Volatile input parameter and output return status

r12

Volatile

r13 - r31

Non-Volatile

LR

Non-Volatile

CTR

Non-Volatile

XER

Non-Volatile

CR2-CR4 Fields

Non-Volatile

Remaining CR fields

Volatile

Other Registers

Non-Volatile

Contents of registers that are considered "Non-Volatile" shall be preserved across hypercalls.

/!\ The content of non-volatile registers must be completely preserved, regardless of the size the register and the state of the processor at the time of hypercall invocation. For example, all 64 bits of a 64-bit register must be preserved even if MSR[SF] or MSR[CM] specifies 32-bit mode.

TODO

Endianness

Background

Introduction to Hypervisor Calls

This page describes the existing hcall ABI defined by the various Hypervisors available for the PowerPC platform.

Known Hypervisor hcall() ABIs are:

  1. PAPR ABI, as used by IBM PHYP Hypervisor and Xen on POWER
  2. BEAT ABI, as used by Toshiba CellEB
  3. PS3 ABI, as used by Sony PS3

The Hypervisor Call Mechanism

Calls to the hypervisor layer are performed by executing an instruction that causes an exception, in much the same way as a Unix System Call is performed. The first argument is a token that designates that actual function to perform. The remaining arguments and there interpretation is specific to the function of the hcall().

The hcall function depends on an instruction that can "trap" to the hypervisor. Some chip implementations have a modified system call (LEVEL=1) that traps directly to the processor mode that the hypervisor runs in. In the case where the there the processor does not have this special form it is suggest that the system call instruction is used where r0 is -1.

The definition for HSC is as follows:

#ifdef SC_LEVEL
#define HSC    .long 0x44000022  /* SC with LEVEL=1 */
#elseif
#define HSC    li r0,-1; sc
#endif

/!\ In order to safely use r0 the hcall definition must have full binding and not be inlined. This way the ABI shall guarantee the volatility of r0.

C Language Calling Convention

        int hcall_func(unsigned long ret[], unsigned long arg<n>, ...)

/!\ Assumes that unsigned long contains the same number of bit as a GPR

Example Usage

The following is a C function using a C language binding for an hcall

void
example(unsigned long arg1, unsigned long arg2)
{
        int rc;
        unsigned long results[2];

        rc = hcall_ex(results, arg1, arg2);
        if (rc != H_Success) {
                ... Failure Case ...
        }
        ... return values are in results array ...
}

PAPR ABI

The PAPR Spec is available thru Power.org.

Inputs

The PAPR ABI expects when the call is placed requires the token for the specific hcall to be place in r3, the remaining parameters for the hcall occupy r4 thru r11.

Outputs

Upon completion of the hcall, a return code indicating status will be placed r3 and subsequent registers r4 thru r11 will contain additional returned values if any.

Volatile State

The native function calling ABI is respected with respect to non-volatiles and typically guarantees extra non-volatiles, specifically:

Register

Description

r0-r1

Non-Volatile

r3

Volatile parameter and return value for status

r4 - r11

Volatile

r12

Volatile

r13 - r31

Non-Volatile

LR

Non-Volatile

CTR

Non-Volatile

XER

Non-Volatile

CR0-CR7

Non-Volatile

(!) Xen hcall()s that are not inherited from the PAPR continue to use r3 for return code but use memory references for additional return information. :o

Example Definition

Example of creating a C callable function that perform an hcall() called H_EX for PowerPC 64 bit ELF ABI:

hcall_ex_64.s

        .align 3
        .globl hcall_ex
        # Insert ABI specific instruction to make symbol callable by C
hcall_ex:
        std     r3,-8(1)   # r3 (array of values) stored in stack
        li      r3,H_EX    # load r3 with hypervisor code
        HSC                # Hypervisor Trap
        ld      r12,-8(1)  # reload array into r12
        cmpi    0,12,0     # only store return regs if array is non-NULL
        bne     ret2       # this hcall() only returns contents of r4,r5
        blr                # return no values

ret8:   std r11,(7 * 8)(r12)
ret7:   std r10,(6 * 8)(r12)
ret6:   std r9,(5 * 8)(r12)
ret5:   std r8,(4 * 8)(r12)
ret4:   std r7,(3 * 8)(r12)
ret3:   std r6,(2 * 8)(r12)
ret2:   std r5,(1 * 8)(r12)
ret1:   std r4,(0 * 8)(r12)
        blr

(!) 32-bit variant of this function would use lwz and stw /!\ r11 on the hypervisor side will require to be placed in the stack when switching back to C, please see the PowerPC ELF ABI for details

BEAT ABI

The BEAT ABI is used by CellEB Hypervisor from Toshiba

Inputs

The BEAT ABI expects when the call is placed requires the token for the specific hcall to be place in r11, the remaining parameters for the hcall occupy r3 thru r10.

Outputs

Upon completion of the hcall, a return code indicating status will be placed r3 and subsequent registers r4 thru r11 will contain additional returned values if any.

Volatile State

The native function calling ABI is respected with respect to non-volatiles and typically guarantees extra non-volatiles, specifically:

Register

Description

PS3 ABI

The PS3 ABI is used by Playstation 3 Hypervisor from Sony

Inputs

The BEAT ABI expects when the call is placed requires the token for the specific hcall to be place in r11, the remaining parameters for the hcall occupy r3 thru r10.

Outputs

Upon completion of the hcall, a return code indicating status will be placed r3 and subsequent registers r4 thru r11 will contain additional returned values if any.

Volatile State

The native function calling ABI is respected with respect to non-volatiles and typically guarantees extra non-volatiles, specifically:

Register

Description


CategoryPowerPC

PowerPC Hypercall ABI (last edited 2008-06-19 18:43:06 by AlecMocatta)