[RFC PATCH 5/9] docs/x86: Introduce FastABI

Teddy Astie posted 9 patches 2 months, 1 week ago
[RFC PATCH 5/9] docs/x86: Introduce FastABI
Posted by Teddy Astie 2 months, 1 week ago
FastABI is a alternative ABI designed with performance and coco-enabled
guest in mind. It is register-oriented instead of refering to C structures
in the guest memory (through a virtual memory pointer).

It only focuses on kernel-side hypercalls, it doesn't aim to provide toolstack
operations.

Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
---
 docs/guest-guide/x86/fastabi.pandoc |  50 ++++++++++
 docs/guest-guide/x86/index.rst      |   1 +
 xen/abi/event_channel.yml           | 130 ++++++++++++++++++++++++++
 xen/abi/grant_table.yml             |  46 +++++++++
 xen/abi/hvm.yml                     |  50 ++++++++++
 xen/abi/memory.yml                  |  11 +++
 xen/abi/sched.yml                   |  48 ++++++++++
 xen/abi/vcpu.yml                    | 139 ++++++++++++++++++++++++++++
 xen/abi/version.yml                 |  15 +++
 xen/include/public/arch-x86/cpuid.h |   4 +
 10 files changed, 494 insertions(+)
 create mode 100644 docs/guest-guide/x86/fastabi.pandoc
 create mode 100644 xen/abi/event_channel.yml
 create mode 100644 xen/abi/grant_table.yml
 create mode 100644 xen/abi/hvm.yml
 create mode 100644 xen/abi/memory.yml
 create mode 100644 xen/abi/sched.yml
 create mode 100644 xen/abi/vcpu.yml
 create mode 100644 xen/abi/version.yml

diff --git a/docs/guest-guide/x86/fastabi.pandoc b/docs/guest-guide/x86/fastabi.pandoc
new file mode 100644
index 0000000000..8ff8609f37
--- /dev/null
+++ b/docs/guest-guide/x86/fastabi.pandoc
@@ -0,0 +1,50 @@
+# x86 FastABI
+
+## Introduction
+
+FastABI is a alternative hypercall ABI designed with performance and confidential
+computing enabled guests (AMD SEV, Intel TDX, ...) in mind. It provides a minimal
+subset of the traditional ABI that is sufficient for having a working guest.
+
+This hypercall interface is designed around using registers for passing hypercall
+parameters and outputs rather than using pointer to C structures, thus it avoids
+potentially complicated or expensive memory copies from/to the guest.
+
+This ABI currently only supports HVM/PVH and x86 long mode.
+
+Each hypercall operation interface is described in a parsable yaml file, which
+defines each hypercall suboperation inputs and outputs and eventual metadata for
+code generation (e.g C stubs).
+
+## Support
+
+This interface is only supported if XEN_HVM_CPUID_FASTABI is set.
+
+## Semantics
+
+8 registers can be used as either input or output.
+
+Each hypercall operation (or sub-operation) defines its own set of used input and
+output registers. There is no implicit clobbering of unused registers, i.e input
+registers are not allowed to be modified by the hypervisor unless it is explicitely
+also marked as a output (or cloberred register).
+
+- reg0: `rax`: IN: hypercall operation index, OUT: error code
+- reg1: `rdi`: (if operation has sub-operations) IN: hypercall sub-operation index
+- reg2: `rsi`
+- reg3: `r8`
+- reg4: `r9`
+- reg5: `r10`
+- reg6: `r11`
+- reg7: `r12`
+
+`reg0` input is reserved for hypercall index.
+In order to distinguish FastABI with traditional hypercalls or viridian hypercalls,
+reg0 input needs to be OR-ed with 0x40000000 (__HYPERVISOR_FASTABI_MASK).
+
+`reg0` output is reserved for standard hypercall return code (errno) or returned value.
+
+`reg1` input can be used for identifying a sub-operation. output is available for use.
+
+The hypercall uses the native hypercall instruction, which is `vmcall` on Intel platforms
+and `vmmcall` on AMD platforms.
\ No newline at end of file
diff --git a/docs/guest-guide/x86/index.rst b/docs/guest-guide/x86/index.rst
index 6927271e53..aaae42da5a 100644
--- a/docs/guest-guide/x86/index.rst
+++ b/docs/guest-guide/x86/index.rst
@@ -7,4 +7,5 @@ x86
    :maxdepth: 2
 
    hypercall-abi
+   fastabi
    fixed-memory-layout
diff --git a/xen/abi/event_channel.yml b/xen/abi/event_channel.yml
new file mode 100644
index 0000000000..44a769cdbb
--- /dev/null
+++ b/xen/abi/event_channel.yml
@@ -0,0 +1,130 @@
+name: event_channel
+hypercall_index: 32
+
+subops:
+  alloc_unbound:
+    index: 6
+    input:
+      dom: 2
+      remote_dom: 3
+    output:
+      port: 4
+    c_lang:
+      struct: evtchn_alloc_unbound
+
+  bind_interdomain:
+    index: 0
+    input:
+      remote_dom: 2
+      remote_port: 3
+    output:
+      local_port: 4
+    c_lang:
+      struct: evtchn_bind_interdomain
+
+  bind_virq:
+    index: 1
+    input:
+      virq: 2
+      vcpu: 3
+    output:
+      port: 4
+    c_lang:
+      struct: evtchn_bind_virq
+
+  bind_ipi:
+    index: 7
+    input:
+      vcpu: 2
+    output:
+      port: 4
+    c_lang:
+      struct: evtchn_bind_ipi
+
+  bind_pirq:
+    index: 2
+    input:
+      pirq: 2
+      flags: 3
+    output:
+      port: 4
+    c_lang:
+      struct: evtchn_bind_pirq
+  
+  close:
+    index: 3
+    input:
+      port: 2
+    c_lang:
+      struct: evtchn_close
+  
+  send:
+    index: 4
+    input:
+      port: 2
+    c_lang:
+      struct: evtchn_send
+
+  status:
+    index: 5
+    input:
+      dom: 2
+      port: 3
+    output:
+      status: 4
+      vcpu: 5
+      output1: 6
+      output2: 7
+    c_lang:
+      struct: evtchn_status
+      mapping:
+        output1: u._output1
+        output2: u._output2
+  
+  bind_vcpu:
+    index: 8
+    input:
+      vcpu: 2
+      port: 3
+    c_lang:
+      struct: evtchn_bind_vcpu
+  
+  unmask:
+    index: 9
+    input:
+      port: 2
+    c_lang:
+      struct: evtchn_unmask
+  
+  reset:
+    index: 10
+    input:
+      dom: 2
+    c_lang:
+      struct: evtchn_reset
+
+  init_control:
+    index: 11
+    input:
+      control_gfn: 2
+      offset: 3
+      vcpu: 4
+    output:
+      link_bits: 5
+    c_lang:
+      struct: evtchn_init_control
+  
+  expand_array:
+    index: 12
+    input:
+      array_gfn: 2
+    c_lang:
+      struct: evtchn_expand_array
+
+  set_priority:
+    index: 13
+    input:
+      port: 2
+      priority: 3
+    c_lang:
+      struct: evtchn_set_priority
diff --git a/xen/abi/grant_table.yml b/xen/abi/grant_table.yml
new file mode 100644
index 0000000000..bcedaa966b
--- /dev/null
+++ b/xen/abi/grant_table.yml
@@ -0,0 +1,46 @@
+name: grant_table
+hypercall_index: 20
+
+subops:
+  map_grant_ref:
+    index: 0
+    input:
+      dom: 2
+      host_addr: 3
+      flags: 4
+      ref: 5
+    output:
+      handle: 6
+      status: 7
+    c_lang:
+      struct: gnttab_map_grant_ref
+  
+  unmap_grant_ref:
+    index: 1
+    input:
+      host_addr: 3
+      handle: 6
+    c_lang:
+      struct: gnttab_unmap_grant_ref
+  
+  query_size:
+    index: 6
+    output:
+      nr_frames: 2
+      max_nr_frames: 3
+    c_lang:
+      struct: gnttab_query_size
+
+  set_version:
+    index: 8
+    input:
+      version: 2
+    c_lang:
+      struct: gnttab_set_version
+
+  get_version:
+    index: 10
+    output:
+      version: 2
+    c_lang:
+      struct: gnttab_get_version
diff --git a/xen/abi/hvm.yml b/xen/abi/hvm.yml
new file mode 100644
index 0000000000..20c2421bdf
--- /dev/null
+++ b/xen/abi/hvm.yml
@@ -0,0 +1,50 @@
+name: hvm
+hypercall_index: 34
+
+subops:
+  set_param:
+    index: 0
+    input:
+      domid: 2
+      index: 3
+      value: 4
+    c_lang:
+      struct: xen_hvm_param
+
+  get_param:
+    index: 1
+    input:
+      domid: 2
+      index: 3
+    output:
+      value: 4
+    c_lang:
+      struct: xen_hvm_param
+
+  flush_tlbs:
+    index: 5
+
+  get_time:
+    index: 10
+    output:
+      now: 2
+    c_lang:
+      struct: xen_hvm_get_time
+
+  get_mem_type:
+    index: 15
+    input:
+      domid: 2
+      pfn: 3
+    output:
+      mem_type: 4
+    c_lang:
+      struct: xen_hvm_get_mem_type
+
+  set_evtchn_upcall_vector:
+    index: 23
+    input:
+      vcpu: 2
+      vector: 3
+    c_lang:
+      struct: xen_hvm_evtchn_upcall_vector
diff --git a/xen/abi/memory.yml b/xen/abi/memory.yml
new file mode 100644
index 0000000000..8b51490f8a
--- /dev/null
+++ b/xen/abi/memory.yml
@@ -0,0 +1,11 @@
+name: memory
+hypercall_index: 12
+
+subops:
+  memory_map:
+    index: 9
+    input:
+      nr_entries: 2
+      buffer: 3
+    c_lang:
+      struct: xen_memory_map
diff --git a/xen/abi/sched.yml b/xen/abi/sched.yml
new file mode 100644
index 0000000000..1b1ef50c7a
--- /dev/null
+++ b/xen/abi/sched.yml
@@ -0,0 +1,48 @@
+name: sched
+hypercall_index: 29
+
+subops:
+  yield:
+    index: 0
+
+  block:
+    index: 1
+
+  shutdown:
+    index: 2
+    input:
+      reason: 2
+    c_lang:
+      struct: sched_shutdown
+
+  poll:
+    index: 3
+    input:
+      timeout: 2
+      port: 3
+    c_lang:
+      params:
+        timeout: uint64_t
+        port: evtchn_port_t
+
+  shutdown_code:
+    index: 5
+    input:
+      reason: 2
+    c_lang:
+      struct: sched_shutdown
+
+  watchdog:
+    index: 6
+    input:
+      id: 2
+      timeout: 3
+    c_lang:
+      struct: sched_watchdog
+
+  pin_override:
+    index: 7
+    input:
+      pcpu: 2
+    c_lang:
+      struct: sched_pin_override
diff --git a/xen/abi/vcpu.yml b/xen/abi/vcpu.yml
new file mode 100644
index 0000000000..0b4fe4ea1f
--- /dev/null
+++ b/xen/abi/vcpu.yml
@@ -0,0 +1,139 @@
+name: vcpu
+hypercall_index: 24
+
+subops:
+  initialise:
+    index: 0
+    input:
+      vcpuid: 2
+      context_gfn: 3
+    c_lang:
+      params:
+        vcpuid: uint32_t
+        context_gfn: uint64_t
+
+  up:
+    index: 1
+    input:
+      vcpuid: 2
+    c_lang:
+      params:
+        vcpuid: uint32_t
+
+  down:
+    index: 2
+    input:
+      vcpuid: 2
+    c_lang:
+      params:
+        vcpuid: uint32_t
+
+  is_up:
+    index: 3
+    input:
+      vcpuid: 2
+    c_lang:
+      params:
+        vcpuid: uint32_t
+
+  get_runstate_info:
+    index: 4
+    input:
+      vcpuid: 2
+    output:
+      state: 2
+      state_entry_time: 3
+      time[0]: 4
+      time[1]: 5
+      time[2]: 6
+      time[3]: 7
+    c_lang:
+      struct: vcpu_runstate_info
+      params:
+        vcpuid: uint32_t
+
+  register_runstate_phys_area:
+    index: 14
+    input:
+      vcpuid: 2
+      addr.p: 3
+    c_lang:
+      struct: vcpu_register_time_memory_area
+      params:
+        vcpuid: uint32_t
+
+  set_periodic_timer:
+    index: 6
+    input:
+      vcpuid: 2
+      period_ns: 3
+    c_lang:
+      struct: vcpu_set_periodic_timer
+      params:
+        vcpuid: uint32_t
+
+  stop_periodic_timer:
+    index: 7
+    input:
+      vcpuid: 2
+    c_lang:
+      params:
+        vcpuid: uint32_t
+  
+  set_singleshot_timer:
+    index: 8
+    input:
+      vcpuid: 2
+      timeout_abs_ns: 3
+      flags: 4
+    c_lang:
+      struct: vcpu_set_singleshot_timer
+      params:
+        vcpuid: uint32_t
+
+  stop_singleshot_timer:
+    index: 9
+    input:
+      vcpuid: 2
+    c_lang:
+      params:
+        vcpuid: uint32_t
+
+  register_vcpu_info:
+    index: 10
+    input:
+      vcpuid: 2
+      mfn: 3
+      offset: 4
+    c_lang:
+      struct: vcpu_register_vcpu_info
+      params:
+        vcpuid: uint32_t
+
+  send_nmi:
+    index: 11
+    input:
+      vcpuid: 2
+    c_lang:
+      params:
+        vcpuid: uint32_t
+
+  get_physid:
+    index: 12
+    input:
+      vcpuid: 2
+      phys_id: 3
+    c_lang:
+      struct: vcpu_get_physid
+      params:
+        vcpuid: uint32_t
+
+  register_vcpu_time_phys_area:
+    index: 15
+    input:
+      vcpuid: 2
+      addr.p: 3
+    c_lang:
+      struct: vcpu_register_time_memory_area
+      params:
+        vcpuid: uint32_t
diff --git a/xen/abi/version.yml b/xen/abi/version.yml
new file mode 100644
index 0000000000..bce64a4d69
--- /dev/null
+++ b/xen/abi/version.yml
@@ -0,0 +1,15 @@
+name: version
+hypercall_index: 17
+
+subops:
+  version:
+    index: 0
+
+  get_features:
+    index: 6
+    input:
+      submap_idx: 2
+    output:
+      submap: 3
+    c_lang:
+      struct: xen_feature_info
diff --git a/xen/include/public/arch-x86/cpuid.h b/xen/include/public/arch-x86/cpuid.h
index 3bb0dd249f..ff44ce0e7b 100644
--- a/xen/include/public/arch-x86/cpuid.h
+++ b/xen/include/public/arch-x86/cpuid.h
@@ -106,6 +106,10 @@
  * bound to event channels.
  */
 #define XEN_HVM_CPUID_UPCALL_VECTOR    (1u << 6)
+/*
+ * Support for fast HVM ABI.
+ */
+#define XEN_HVM_CPUID_FASTABI          (1u << 7)
 
 /*
  * Leaf 6 (0x40000x05)
-- 
2.50.1



Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech
Re: [RFC PATCH 5/9] docs/x86: Introduce FastABI
Posted by Jan Beulich 2 months ago
On 21.08.2025 17:25, Teddy Astie wrote:
> FastABI is a alternative ABI designed with performance and coco-enabled
> guest in mind. It is register-oriented instead of refering to C structures
> in the guest memory (through a virtual memory pointer).
> 
> It only focuses on kernel-side hypercalls, it doesn't aim to provide toolstack
> operations.

And even there it excludes certain pretty relevant ones, like many of the
gnttabop sub-ops. As alluded to by a reply to an earlier patch, I don't
think having an ABI for just a subset of the hypercalls is going to help.

Jan
Re: [RFC PATCH 5/9] docs/x86: Introduce FastABI
Posted by Teddy Astie 2 months ago
Le 28/08/2025 à 14:35, Jan Beulich a écrit :
> On 21.08.2025 17:25, Teddy Astie wrote:
>> FastABI is a alternative ABI designed with performance and coco-enabled
>> guest in mind. It is register-oriented instead of refering to C structures
>> in the guest memory (through a virtual memory pointer).
>>
>> It only focuses on kernel-side hypercalls, it doesn't aim to provide toolstack
>> operations.
> 
> And even there it excludes certain pretty relevant ones, like many of the
> gnttabop sub-ops. As alluded to by a reply to an earlier patch, I don't
> think having an ABI for just a subset of the hypercalls is going to help.
> 

Many hypercalls are missing in current RFC, including the grant 
map/unmap ones. But a part of the idea is to still having some 
hypercalls out of scope (mainly legacy and toolstack-specific ones) to 
reduce the complexity.

> Jan
> 



Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech
Re: [RFC PATCH 5/9] docs/x86: Introduce FastABI
Posted by Jan Beulich 1 month, 4 weeks ago
On 29.08.2025 15:59, Teddy Astie wrote:
> Le 28/08/2025 à 14:35, Jan Beulich a écrit :
>> On 21.08.2025 17:25, Teddy Astie wrote:
>>> FastABI is a alternative ABI designed with performance and coco-enabled
>>> guest in mind. It is register-oriented instead of refering to C structures
>>> in the guest memory (through a virtual memory pointer).
>>>
>>> It only focuses on kernel-side hypercalls, it doesn't aim to provide toolstack
>>> operations.
>>
>> And even there it excludes certain pretty relevant ones, like many of the
>> gnttabop sub-ops. As alluded to by a reply to an earlier patch, I don't
>> think having an ABI for just a subset of the hypercalls is going to help.
>>
> 
> Many hypercalls are missing in current RFC, including the grant 
> map/unmap ones.

Yet the built-in batching that these come with would make it particularly
interesting to see how you envision to support them without needing to
access guest memory. (I simply can't see how that could work.)

Jan

> But a part of the idea is to still having some 
> hypercalls out of scope (mainly legacy and toolstack-specific ones) to 
> reduce the complexity.
> 
> Teddy Astie | Vates XCP-ng Developer
> 
> XCP-ng & Xen Orchestra - Vates solutions
> 
> web: https://vates.tech
> 
>