XEN_DOMCTL_claim_memory

Hypercall command for installing claim sets for a domain.

This hypercall command allows domain builders to install a claim set targeting NUMA nodes and global claims.

The hypervisor tracks the installed claims for each domain and enforces them during memory allocation, so that claimed memory is protected from other allocations and the domain’s memory requirements can be met even when other parallel domain builders are also allocating memory for other domains in parallel.

Claim set installation describes how the Xen hypervisor processes the claim sets installed via this hypercall command.

API example using libxenctrl

The example below shows how a domain builder can install a claim set and later replace or clear it. memory_claim_t contains padding for future expansion; zero-initialise the structure or use designated initializers to ensure forward compatibility.

#include <xenctrl.h>

void example_claims(xc_interface *xch, uint32_t domid)
{
  /* Claim 1024 pages on node 0, 1024 pages on node 1, and 1024 global */
  memory_claim_t claims[] = {
    {.pages = 1024, .node = XEN_DOMCTL_CLAIM_MEMORY_GLOBAL},
    {.pages = 1024, .node = 0},
    {.pages = 1024, .node = 1}
  };
  xc_domain_claim_memory(xch, domid, ARRAY_SIZE(claims), claims);

  /* Replace the claim set with claims on nodes 1, 2, and 3 */
  memory_claim_t claims2[] = {
    {.pages = 1024, .node = 1},
    {.pages = 1024, .node = 2},
    {.pages = 1024, .node = 3},
  };
  xc_domain_claim_memory(xch, domid, ARRAY_SIZE(claims2), claims2);

  /* Release any remaining claim once the domain is built */
  memory_claim_t clear[] = {
    {.pages = 0, .node = XEN_DOMCTL_CLAIM_MEMORY_GLOBAL}
  };
  xc_domain_claim_memory(xch, domid, ARRAY_SIZE(clear), clear);
}

Call sequence diagram

The following sequence diagram illustrates the call flow for claiming memory for a domain using this hypercall command from an OCaml domain builder:

        %% SPDX-License-Identifier: CC-BY-4.0
sequenceDiagram

actor DomainBuilder
participant OcamlStub as OCaml stub for<br>xc_domain<br>claim_memory
participant Libxc as xc_domain<br>claim_memory
participant Domctl as XEN_DOMCTL<br>claim_memory
#participant DomainLogic as claim_memory
participant Alloc as domain<br>set<br>outstanding_pages

DomainBuilder->>OcamlStub: claims
OcamlStub->>OcamlStub: marshall claims -----> OCaml to C
OcamlStub->>Libxc: claims

Libxc->>Domctl: do_domctl

Domctl->>Domctl: copy_from_guest(claim)
Domctl->>Domctl: validate claim
Domctl->>Alloc: set<br>outstanding_pages
Alloc-->>Domctl: result
Domctl-->>Libxc: rc
Libxc-->>OcamlStub: rc
OcamlStub-->>DomainBuilder: claim_result
    

Sequence diagram: Call flow for claiming memory for a domain

Claim workflow

This diagram illustrates a workflow for claiming and populating memory:

        %% SPDX-License-Identifier: CC-BY-4.0
sequenceDiagram

participant Toolstack
participant Xen
participant NUMA Node memory

Toolstack->>Xen: XEN_DOMCTL_createdomain
Toolstack->>Xen: XEN_DOMCTL_max_mem(max_pages)

Toolstack->>Xen: XEN_DOMCTL_claim_memory(pages, node)
Xen->>NUMA Node memory: Claim pages on node
Xen-->>Toolstack: Claim granted

Toolstack->>Xen: XEN_DOMCTL_set_nodeaffinity(node)

loop Populate domain memory
    Toolstack->>Xen: XENMEM_populate_physmap(memflags:node)
    Xen->>NUMA Node memory: alloc from claimed node
end

Toolstack->>Xen: XEN_DOMCTL_claim_memory(0, NO_NODE)
Xen-->>Toolstack: Remaining claims released

    

Workflow diagram: Claiming and populating memory for a domain

Used functions & data structures

This diagram illustrates the key functions and data structures involved in installing claims via the XEN_DOMCTL_claim_memory hypercall command:

        %% SPDX-License-Identifier: CC-BY-4.0
classDiagram
class do_domctl["Args passed to <tt>do_domctl()</tt>"] {
    +uint32_t cmd: XEN_DOMCTL_claim_memory
    +uint32_t domain: Domain ID
    +xen_domctl_claim_memory: Claim set
}
class xen_domctl_claim_memory["Claim set passed to <tt>do_domctl()</tt>"] {
    +memory_claim_t* claims: Claim entries
    +uint32_t nr_claims: Number of claim entries
    +uint32_t pad: always 0 for future use
}
class memory_claim_t["Claim set: Array of claim entries"] {
    +pages: Pages to claim
    +node: Claim selector or node
    +pad: always 0 for future use
}
class xc_domain_claim_memory["xc_domain_claim_memory()"] {
    +xc_interface* xch
    +uint32_t domid
    +uint32_t nr_claims
    +memory_claim_t* claims
}
class global_claimss["Global and Node claim counters"] {
    global free = total_avail_pages - outstanding_claims
    node free = node_avail_pages[node] - node_outstanding_claims[node]
}
class claim["XEN_DOMCTL_claim_memory"] {
    +domain_set_outstanding_pages()
    +domain_set_node_claims()
}
class domain["Claim fields in struct domain"] {
    +global_claims - Global claims of the domain
    +node_claims - Sum of claims on all nodes of the domain
    +claims[] - Array of claims on specific nodes
}
xen_domctl_claim_memory o--> memory_claim_t
do_domctl o--> xen_domctl_claim_memory
xc_domain_claim_memory ..> do_domctl: passes<br> <tt>Claim set</tt>
xc_domain_claim_memory ..> claim : calls <tt>do_domctl()</tt>
claim ..> xen_domctl_claim_memory : reads
claim ..> domain : sets
domain ..> global_claimss : updates outstanding claims

    

Diagram: Function and data relationships for installing claims