1*8ac98aedSDavid Woodhouse /* SPDX-License-Identifier: MIT */ 250c88402SJoao Martins /****************************************************************************** 350c88402SJoao Martins * memory.h 450c88402SJoao Martins * 550c88402SJoao Martins * Memory reservation and information. 650c88402SJoao Martins * 750c88402SJoao Martins * Copyright (c) 2005, Keir Fraser <keir@xensource.com> 850c88402SJoao Martins */ 950c88402SJoao Martins 1050c88402SJoao Martins #ifndef __XEN_PUBLIC_MEMORY_H__ 1150c88402SJoao Martins #define __XEN_PUBLIC_MEMORY_H__ 1250c88402SJoao Martins 1350c88402SJoao Martins #include "xen.h" 1450c88402SJoao Martins #include "physdev.h" 1550c88402SJoao Martins 1650c88402SJoao Martins /* 1750c88402SJoao Martins * Increase or decrease the specified domain's memory reservation. Returns the 1850c88402SJoao Martins * number of extents successfully allocated or freed. 1950c88402SJoao Martins * arg == addr of struct xen_memory_reservation. 2050c88402SJoao Martins */ 2150c88402SJoao Martins #define XENMEM_increase_reservation 0 2250c88402SJoao Martins #define XENMEM_decrease_reservation 1 2350c88402SJoao Martins #define XENMEM_populate_physmap 6 2450c88402SJoao Martins 2550c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ >= 0x00030209 2650c88402SJoao Martins /* 2750c88402SJoao Martins * Maximum # bits addressable by the user of the allocated region (e.g., I/O 2850c88402SJoao Martins * devices often have a 32-bit limitation even in 64-bit systems). If zero 2950c88402SJoao Martins * then the user has no addressing restriction. This field is not used by 3050c88402SJoao Martins * XENMEM_decrease_reservation. 3150c88402SJoao Martins */ 3250c88402SJoao Martins #define XENMEMF_address_bits(x) (x) 3350c88402SJoao Martins #define XENMEMF_get_address_bits(x) ((x) & 0xffu) 3450c88402SJoao Martins /* NUMA node to allocate from. */ 3550c88402SJoao Martins #define XENMEMF_node(x) (((x) + 1) << 8) 3650c88402SJoao Martins #define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu) 3750c88402SJoao Martins /* Flag to populate physmap with populate-on-demand entries */ 3850c88402SJoao Martins #define XENMEMF_populate_on_demand (1<<16) 3950c88402SJoao Martins /* Flag to request allocation only from the node specified */ 4050c88402SJoao Martins #define XENMEMF_exact_node_request (1<<17) 4150c88402SJoao Martins #define XENMEMF_exact_node(n) (XENMEMF_node(n) | XENMEMF_exact_node_request) 4250c88402SJoao Martins /* Flag to indicate the node specified is virtual node */ 4350c88402SJoao Martins #define XENMEMF_vnode (1<<18) 4450c88402SJoao Martins #endif 4550c88402SJoao Martins 4650c88402SJoao Martins struct xen_memory_reservation { 4750c88402SJoao Martins 4850c88402SJoao Martins /* 4950c88402SJoao Martins * XENMEM_increase_reservation: 5050c88402SJoao Martins * OUT: MFN (*not* GMFN) bases of extents that were allocated 5150c88402SJoao Martins * XENMEM_decrease_reservation: 5250c88402SJoao Martins * IN: GMFN bases of extents to free 5350c88402SJoao Martins * XENMEM_populate_physmap: 5450c88402SJoao Martins * IN: GPFN bases of extents to populate with memory 5550c88402SJoao Martins * OUT: GMFN bases of extents that were allocated 5650c88402SJoao Martins * (NB. This command also updates the mach_to_phys translation table) 5750c88402SJoao Martins * XENMEM_claim_pages: 5850c88402SJoao Martins * IN: must be zero 5950c88402SJoao Martins */ 6050c88402SJoao Martins XEN_GUEST_HANDLE(xen_pfn_t) extent_start; 6150c88402SJoao Martins 6250c88402SJoao Martins /* Number of extents, and size/alignment of each (2^extent_order pages). */ 6350c88402SJoao Martins xen_ulong_t nr_extents; 6450c88402SJoao Martins unsigned int extent_order; 6550c88402SJoao Martins 6650c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ >= 0x00030209 6750c88402SJoao Martins /* XENMEMF flags. */ 6850c88402SJoao Martins unsigned int mem_flags; 6950c88402SJoao Martins #else 7050c88402SJoao Martins unsigned int address_bits; 7150c88402SJoao Martins #endif 7250c88402SJoao Martins 7350c88402SJoao Martins /* 7450c88402SJoao Martins * Domain whose reservation is being changed. 7550c88402SJoao Martins * Unprivileged domains can specify only DOMID_SELF. 7650c88402SJoao Martins */ 7750c88402SJoao Martins domid_t domid; 7850c88402SJoao Martins }; 7950c88402SJoao Martins typedef struct xen_memory_reservation xen_memory_reservation_t; 8050c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t); 8150c88402SJoao Martins 8250c88402SJoao Martins /* 8350c88402SJoao Martins * An atomic exchange of memory pages. If return code is zero then 8450c88402SJoao Martins * @out.extent_list provides GMFNs of the newly-allocated memory. 8550c88402SJoao Martins * Returns zero on complete success, otherwise a negative error code. 8650c88402SJoao Martins * On complete success then always @nr_exchanged == @in.nr_extents. 8750c88402SJoao Martins * On partial success @nr_exchanged indicates how much work was done. 8850c88402SJoao Martins * 8950c88402SJoao Martins * Note that only PV guests can use this operation. 9050c88402SJoao Martins */ 9150c88402SJoao Martins #define XENMEM_exchange 11 9250c88402SJoao Martins struct xen_memory_exchange { 9350c88402SJoao Martins /* 9450c88402SJoao Martins * [IN] Details of memory extents to be exchanged (GMFN bases). 9550c88402SJoao Martins * Note that @in.address_bits is ignored and unused. 9650c88402SJoao Martins */ 9750c88402SJoao Martins struct xen_memory_reservation in; 9850c88402SJoao Martins 9950c88402SJoao Martins /* 10050c88402SJoao Martins * [IN/OUT] Details of new memory extents. 10150c88402SJoao Martins * We require that: 10250c88402SJoao Martins * 1. @in.domid == @out.domid 10350c88402SJoao Martins * 2. @in.nr_extents << @in.extent_order == 10450c88402SJoao Martins * @out.nr_extents << @out.extent_order 10550c88402SJoao Martins * 3. @in.extent_start and @out.extent_start lists must not overlap 10650c88402SJoao Martins * 4. @out.extent_start lists GPFN bases to be populated 10750c88402SJoao Martins * 5. @out.extent_start is overwritten with allocated GMFN bases 10850c88402SJoao Martins */ 10950c88402SJoao Martins struct xen_memory_reservation out; 11050c88402SJoao Martins 11150c88402SJoao Martins /* 11250c88402SJoao Martins * [OUT] Number of input extents that were successfully exchanged: 11350c88402SJoao Martins * 1. The first @nr_exchanged input extents were successfully 11450c88402SJoao Martins * deallocated. 11550c88402SJoao Martins * 2. The corresponding first entries in the output extent list correctly 11650c88402SJoao Martins * indicate the GMFNs that were successfully exchanged. 11750c88402SJoao Martins * 3. All other input and output extents are untouched. 11850c88402SJoao Martins * 4. If not all input exents are exchanged then the return code of this 11950c88402SJoao Martins * command will be non-zero. 12050c88402SJoao Martins * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER! 12150c88402SJoao Martins */ 12250c88402SJoao Martins xen_ulong_t nr_exchanged; 12350c88402SJoao Martins }; 12450c88402SJoao Martins typedef struct xen_memory_exchange xen_memory_exchange_t; 12550c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t); 12650c88402SJoao Martins 12750c88402SJoao Martins /* 12850c88402SJoao Martins * Returns the maximum machine frame number of mapped RAM in this system. 12950c88402SJoao Martins * This command always succeeds (it never returns an error code). 13050c88402SJoao Martins * arg == NULL. 13150c88402SJoao Martins */ 13250c88402SJoao Martins #define XENMEM_maximum_ram_page 2 13350c88402SJoao Martins 13450c88402SJoao Martins struct xen_memory_domain { 13550c88402SJoao Martins /* [IN] Domain information is being queried for. */ 13650c88402SJoao Martins domid_t domid; 13750c88402SJoao Martins }; 13850c88402SJoao Martins 13950c88402SJoao Martins /* 14050c88402SJoao Martins * Returns the current or maximum memory reservation, in pages, of the 14150c88402SJoao Martins * specified domain (may be DOMID_SELF). Returns -ve errcode on failure. 14250c88402SJoao Martins * arg == addr of struct xen_memory_domain. 14350c88402SJoao Martins */ 14450c88402SJoao Martins #define XENMEM_current_reservation 3 14550c88402SJoao Martins #define XENMEM_maximum_reservation 4 14650c88402SJoao Martins 14750c88402SJoao Martins /* 14850c88402SJoao Martins * Returns the maximum GFN in use by the specified domain (may be DOMID_SELF). 14950c88402SJoao Martins * Returns -ve errcode on failure. 15050c88402SJoao Martins * arg == addr of struct xen_memory_domain. 15150c88402SJoao Martins */ 15250c88402SJoao Martins #define XENMEM_maximum_gpfn 14 15350c88402SJoao Martins 15450c88402SJoao Martins /* 15550c88402SJoao Martins * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys 15650c88402SJoao Martins * mapping table. Architectures which do not have a m2p table do not implement 15750c88402SJoao Martins * this command. 15850c88402SJoao Martins * arg == addr of xen_machphys_mfn_list_t. 15950c88402SJoao Martins */ 16050c88402SJoao Martins #define XENMEM_machphys_mfn_list 5 16150c88402SJoao Martins struct xen_machphys_mfn_list { 16250c88402SJoao Martins /* 16350c88402SJoao Martins * Size of the 'extent_start' array. Fewer entries will be filled if the 16450c88402SJoao Martins * machphys table is smaller than max_extents * 2MB. 16550c88402SJoao Martins */ 16650c88402SJoao Martins unsigned int max_extents; 16750c88402SJoao Martins 16850c88402SJoao Martins /* 16950c88402SJoao Martins * Pointer to buffer to fill with list of extent starts. If there are 17050c88402SJoao Martins * any large discontiguities in the machine address space, 2MB gaps in 17150c88402SJoao Martins * the machphys table will be represented by an MFN base of zero. 17250c88402SJoao Martins */ 17350c88402SJoao Martins XEN_GUEST_HANDLE(xen_pfn_t) extent_start; 17450c88402SJoao Martins 17550c88402SJoao Martins /* 17650c88402SJoao Martins * Number of extents written to the above array. This will be smaller 17750c88402SJoao Martins * than 'max_extents' if the machphys table is smaller than max_e * 2MB. 17850c88402SJoao Martins */ 17950c88402SJoao Martins unsigned int nr_extents; 18050c88402SJoao Martins }; 18150c88402SJoao Martins typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t; 18250c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t); 18350c88402SJoao Martins 18450c88402SJoao Martins /* 18550c88402SJoao Martins * For a compat caller, this is identical to XENMEM_machphys_mfn_list. 18650c88402SJoao Martins * 18750c88402SJoao Martins * For a non compat caller, this functions similarly to 18850c88402SJoao Martins * XENMEM_machphys_mfn_list, but returns the mfns making up the compatibility 18950c88402SJoao Martins * m2p table. 19050c88402SJoao Martins */ 19150c88402SJoao Martins #define XENMEM_machphys_compat_mfn_list 25 19250c88402SJoao Martins 19350c88402SJoao Martins /* 19450c88402SJoao Martins * Returns the location in virtual address space of the machine_to_phys 19550c88402SJoao Martins * mapping table. Architectures which do not have a m2p table, or which do not 19650c88402SJoao Martins * map it by default into guest address space, do not implement this command. 19750c88402SJoao Martins * arg == addr of xen_machphys_mapping_t. 19850c88402SJoao Martins */ 19950c88402SJoao Martins #define XENMEM_machphys_mapping 12 20050c88402SJoao Martins struct xen_machphys_mapping { 20150c88402SJoao Martins xen_ulong_t v_start, v_end; /* Start and end virtual addresses. */ 20250c88402SJoao Martins xen_ulong_t max_mfn; /* Maximum MFN that can be looked up. */ 20350c88402SJoao Martins }; 20450c88402SJoao Martins typedef struct xen_machphys_mapping xen_machphys_mapping_t; 20550c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t); 20650c88402SJoao Martins 20750c88402SJoao Martins /* Source mapping space. */ 20850c88402SJoao Martins /* ` enum phys_map_space { */ 20950c88402SJoao Martins #define XENMAPSPACE_shared_info 0 /* shared info page */ 21050c88402SJoao Martins #define XENMAPSPACE_grant_table 1 /* grant table page */ 21150c88402SJoao Martins #define XENMAPSPACE_gmfn 2 /* GMFN */ 21250c88402SJoao Martins #define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap only. */ 21350c88402SJoao Martins #define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom, 21450c88402SJoao Martins * XENMEM_add_to_physmap_batch only. */ 21550c88402SJoao Martins #define XENMAPSPACE_dev_mmio 5 /* device mmio region 21650c88402SJoao Martins ARM only; the region is mapped in 21750c88402SJoao Martins Stage-2 using the Normal Memory 21850c88402SJoao Martins Inner/Outer Write-Back Cacheable 21950c88402SJoao Martins memory attribute. */ 22050c88402SJoao Martins /* ` } */ 22150c88402SJoao Martins 22250c88402SJoao Martins /* 22350c88402SJoao Martins * Sets the GPFN at which a particular page appears in the specified guest's 22450c88402SJoao Martins * physical address space (translated guests only). 22550c88402SJoao Martins * arg == addr of xen_add_to_physmap_t. 22650c88402SJoao Martins */ 22750c88402SJoao Martins #define XENMEM_add_to_physmap 7 22850c88402SJoao Martins struct xen_add_to_physmap { 22950c88402SJoao Martins /* Which domain to change the mapping for. */ 23050c88402SJoao Martins domid_t domid; 23150c88402SJoao Martins 23250c88402SJoao Martins /* Number of pages to go through for gmfn_range */ 23350c88402SJoao Martins uint16_t size; 23450c88402SJoao Martins 23550c88402SJoao Martins unsigned int space; /* => enum phys_map_space */ 23650c88402SJoao Martins 23750c88402SJoao Martins #define XENMAPIDX_grant_table_status 0x80000000 23850c88402SJoao Martins 23950c88402SJoao Martins /* Index into space being mapped. */ 24050c88402SJoao Martins xen_ulong_t idx; 24150c88402SJoao Martins 24250c88402SJoao Martins /* GPFN in domid where the source mapping page should appear. */ 24350c88402SJoao Martins xen_pfn_t gpfn; 24450c88402SJoao Martins }; 24550c88402SJoao Martins typedef struct xen_add_to_physmap xen_add_to_physmap_t; 24650c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t); 24750c88402SJoao Martins 24850c88402SJoao Martins /* A batched version of add_to_physmap. */ 24950c88402SJoao Martins #define XENMEM_add_to_physmap_batch 23 25050c88402SJoao Martins struct xen_add_to_physmap_batch { 25150c88402SJoao Martins /* IN */ 25250c88402SJoao Martins /* Which domain to change the mapping for. */ 25350c88402SJoao Martins domid_t domid; 25450c88402SJoao Martins uint16_t space; /* => enum phys_map_space */ 25550c88402SJoao Martins 25650c88402SJoao Martins /* Number of pages to go through */ 25750c88402SJoao Martins uint16_t size; 25850c88402SJoao Martins 25950c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ < 0x00040700 26050c88402SJoao Martins domid_t foreign_domid; /* IFF gmfn_foreign. Should be 0 for other spaces. */ 26150c88402SJoao Martins #else 26250c88402SJoao Martins union xen_add_to_physmap_batch_extra { 26350c88402SJoao Martins domid_t foreign_domid; /* gmfn_foreign */ 26450c88402SJoao Martins uint16_t res0; /* All the other spaces. Should be 0 */ 26550c88402SJoao Martins } u; 26650c88402SJoao Martins #endif 26750c88402SJoao Martins 26850c88402SJoao Martins /* Indexes into space being mapped. */ 26950c88402SJoao Martins XEN_GUEST_HANDLE(xen_ulong_t) idxs; 27050c88402SJoao Martins 27150c88402SJoao Martins /* GPFN in domid where the source mapping page should appear. */ 27250c88402SJoao Martins XEN_GUEST_HANDLE(xen_pfn_t) gpfns; 27350c88402SJoao Martins 27450c88402SJoao Martins /* OUT */ 27550c88402SJoao Martins 27650c88402SJoao Martins /* Per index error code. */ 27750c88402SJoao Martins XEN_GUEST_HANDLE(int) errs; 27850c88402SJoao Martins }; 27950c88402SJoao Martins typedef struct xen_add_to_physmap_batch xen_add_to_physmap_batch_t; 28050c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_batch_t); 28150c88402SJoao Martins 28250c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ < 0x00040400 28350c88402SJoao Martins #define XENMEM_add_to_physmap_range XENMEM_add_to_physmap_batch 28450c88402SJoao Martins #define xen_add_to_physmap_range xen_add_to_physmap_batch 28550c88402SJoao Martins typedef struct xen_add_to_physmap_batch xen_add_to_physmap_range_t; 28650c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_range_t); 28750c88402SJoao Martins #endif 28850c88402SJoao Martins 28950c88402SJoao Martins /* 29050c88402SJoao Martins * Unmaps the page appearing at a particular GPFN from the specified guest's 29150c88402SJoao Martins * physical address space (translated guests only). 29250c88402SJoao Martins * arg == addr of xen_remove_from_physmap_t. 29350c88402SJoao Martins */ 29450c88402SJoao Martins #define XENMEM_remove_from_physmap 15 29550c88402SJoao Martins struct xen_remove_from_physmap { 29650c88402SJoao Martins /* Which domain to change the mapping for. */ 29750c88402SJoao Martins domid_t domid; 29850c88402SJoao Martins 29950c88402SJoao Martins /* GPFN of the current mapping of the page. */ 30050c88402SJoao Martins xen_pfn_t gpfn; 30150c88402SJoao Martins }; 30250c88402SJoao Martins typedef struct xen_remove_from_physmap xen_remove_from_physmap_t; 30350c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t); 30450c88402SJoao Martins 30550c88402SJoao Martins /*** REMOVED ***/ 30650c88402SJoao Martins /*#define XENMEM_translate_gpfn_list 8*/ 30750c88402SJoao Martins 30850c88402SJoao Martins /* 30950c88402SJoao Martins * Returns the pseudo-physical memory map as it was when the domain 31050c88402SJoao Martins * was started (specified by XENMEM_set_memory_map). 31150c88402SJoao Martins * arg == addr of xen_memory_map_t. 31250c88402SJoao Martins */ 31350c88402SJoao Martins #define XENMEM_memory_map 9 31450c88402SJoao Martins struct xen_memory_map { 31550c88402SJoao Martins /* 31650c88402SJoao Martins * On call the number of entries which can be stored in buffer. On 31750c88402SJoao Martins * return the number of entries which have been stored in 31850c88402SJoao Martins * buffer. 31950c88402SJoao Martins */ 32050c88402SJoao Martins unsigned int nr_entries; 32150c88402SJoao Martins 32250c88402SJoao Martins /* 32350c88402SJoao Martins * Entries in the buffer are in the same format as returned by the 32450c88402SJoao Martins * BIOS INT 0x15 EAX=0xE820 call. 32550c88402SJoao Martins */ 32650c88402SJoao Martins XEN_GUEST_HANDLE(void) buffer; 32750c88402SJoao Martins }; 32850c88402SJoao Martins typedef struct xen_memory_map xen_memory_map_t; 32950c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t); 33050c88402SJoao Martins 33150c88402SJoao Martins /* 33250c88402SJoao Martins * Returns the real physical memory map. Passes the same structure as 33350c88402SJoao Martins * XENMEM_memory_map. 33450c88402SJoao Martins * Specifying buffer as NULL will return the number of entries required 33550c88402SJoao Martins * to store the complete memory map. 33650c88402SJoao Martins * arg == addr of xen_memory_map_t. 33750c88402SJoao Martins */ 33850c88402SJoao Martins #define XENMEM_machine_memory_map 10 33950c88402SJoao Martins 34050c88402SJoao Martins /* 34150c88402SJoao Martins * Set the pseudo-physical memory map of a domain, as returned by 34250c88402SJoao Martins * XENMEM_memory_map. 34350c88402SJoao Martins * arg == addr of xen_foreign_memory_map_t. 34450c88402SJoao Martins */ 34550c88402SJoao Martins #define XENMEM_set_memory_map 13 34650c88402SJoao Martins struct xen_foreign_memory_map { 34750c88402SJoao Martins domid_t domid; 34850c88402SJoao Martins struct xen_memory_map map; 34950c88402SJoao Martins }; 35050c88402SJoao Martins typedef struct xen_foreign_memory_map xen_foreign_memory_map_t; 35150c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t); 35250c88402SJoao Martins 35350c88402SJoao Martins #define XENMEM_set_pod_target 16 35450c88402SJoao Martins #define XENMEM_get_pod_target 17 35550c88402SJoao Martins struct xen_pod_target { 35650c88402SJoao Martins /* IN */ 35750c88402SJoao Martins uint64_t target_pages; 35850c88402SJoao Martins /* OUT */ 35950c88402SJoao Martins uint64_t tot_pages; 36050c88402SJoao Martins uint64_t pod_cache_pages; 36150c88402SJoao Martins uint64_t pod_entries; 36250c88402SJoao Martins /* IN */ 36350c88402SJoao Martins domid_t domid; 36450c88402SJoao Martins }; 36550c88402SJoao Martins typedef struct xen_pod_target xen_pod_target_t; 36650c88402SJoao Martins 36750c88402SJoao Martins #if defined(__XEN__) || defined(__XEN_TOOLS__) 36850c88402SJoao Martins 36950c88402SJoao Martins #ifndef uint64_aligned_t 37050c88402SJoao Martins #define uint64_aligned_t uint64_t 37150c88402SJoao Martins #endif 37250c88402SJoao Martins 37350c88402SJoao Martins /* 37450c88402SJoao Martins * Get the number of MFNs saved through memory sharing. 37550c88402SJoao Martins * The call never fails. 37650c88402SJoao Martins */ 37750c88402SJoao Martins #define XENMEM_get_sharing_freed_pages 18 37850c88402SJoao Martins #define XENMEM_get_sharing_shared_pages 19 37950c88402SJoao Martins 38050c88402SJoao Martins #define XENMEM_paging_op 20 38150c88402SJoao Martins #define XENMEM_paging_op_nominate 0 38250c88402SJoao Martins #define XENMEM_paging_op_evict 1 38350c88402SJoao Martins #define XENMEM_paging_op_prep 2 38450c88402SJoao Martins 38550c88402SJoao Martins struct xen_mem_paging_op { 38650c88402SJoao Martins uint8_t op; /* XENMEM_paging_op_* */ 38750c88402SJoao Martins domid_t domain; 38850c88402SJoao Martins 38950c88402SJoao Martins /* IN: (XENMEM_paging_op_prep) buffer to immediately fill page from */ 39050c88402SJoao Martins XEN_GUEST_HANDLE_64(const_uint8) buffer; 39150c88402SJoao Martins /* IN: gfn of page being operated on */ 39250c88402SJoao Martins uint64_aligned_t gfn; 39350c88402SJoao Martins }; 39450c88402SJoao Martins typedef struct xen_mem_paging_op xen_mem_paging_op_t; 39550c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_mem_paging_op_t); 39650c88402SJoao Martins 39750c88402SJoao Martins #define XENMEM_access_op 21 39850c88402SJoao Martins #define XENMEM_access_op_set_access 0 39950c88402SJoao Martins #define XENMEM_access_op_get_access 1 40050c88402SJoao Martins /* 40150c88402SJoao Martins * XENMEM_access_op_enable_emulate and XENMEM_access_op_disable_emulate are 40250c88402SJoao Martins * currently unused, but since they have been in use please do not reuse them. 40350c88402SJoao Martins * 40450c88402SJoao Martins * #define XENMEM_access_op_enable_emulate 2 40550c88402SJoao Martins * #define XENMEM_access_op_disable_emulate 3 40650c88402SJoao Martins */ 40750c88402SJoao Martins #define XENMEM_access_op_set_access_multi 4 40850c88402SJoao Martins 40950c88402SJoao Martins typedef enum { 41050c88402SJoao Martins XENMEM_access_n, 41150c88402SJoao Martins XENMEM_access_r, 41250c88402SJoao Martins XENMEM_access_w, 41350c88402SJoao Martins XENMEM_access_rw, 41450c88402SJoao Martins XENMEM_access_x, 41550c88402SJoao Martins XENMEM_access_rx, 41650c88402SJoao Martins XENMEM_access_wx, 41750c88402SJoao Martins XENMEM_access_rwx, 41850c88402SJoao Martins /* 41950c88402SJoao Martins * Page starts off as r-x, but automatically 42050c88402SJoao Martins * change to r-w on a write 42150c88402SJoao Martins */ 42250c88402SJoao Martins XENMEM_access_rx2rw, 42350c88402SJoao Martins /* 42450c88402SJoao Martins * Log access: starts off as n, automatically 42550c88402SJoao Martins * goes to rwx, generating an event without 42650c88402SJoao Martins * pausing the vcpu 42750c88402SJoao Martins */ 42850c88402SJoao Martins XENMEM_access_n2rwx, 42950c88402SJoao Martins /* Take the domain default */ 43050c88402SJoao Martins XENMEM_access_default 43150c88402SJoao Martins } xenmem_access_t; 43250c88402SJoao Martins 43350c88402SJoao Martins struct xen_mem_access_op { 43450c88402SJoao Martins /* XENMEM_access_op_* */ 43550c88402SJoao Martins uint8_t op; 43650c88402SJoao Martins /* xenmem_access_t */ 43750c88402SJoao Martins uint8_t access; 43850c88402SJoao Martins domid_t domid; 43950c88402SJoao Martins /* 44050c88402SJoao Martins * Number of pages for set op (or size of pfn_list for 44150c88402SJoao Martins * XENMEM_access_op_set_access_multi) 44250c88402SJoao Martins * Ignored on setting default access and other ops 44350c88402SJoao Martins */ 44450c88402SJoao Martins uint32_t nr; 44550c88402SJoao Martins /* 44650c88402SJoao Martins * First pfn for set op 44750c88402SJoao Martins * pfn for get op 44850c88402SJoao Martins * ~0ull is used to set and get the default access for pages 44950c88402SJoao Martins */ 45050c88402SJoao Martins uint64_aligned_t pfn; 45150c88402SJoao Martins /* 45250c88402SJoao Martins * List of pfns to set access for 45350c88402SJoao Martins * Used only with XENMEM_access_op_set_access_multi 45450c88402SJoao Martins */ 45550c88402SJoao Martins XEN_GUEST_HANDLE(const_uint64) pfn_list; 45650c88402SJoao Martins /* 45750c88402SJoao Martins * Corresponding list of access settings for pfn_list 45850c88402SJoao Martins * Used only with XENMEM_access_op_set_access_multi 45950c88402SJoao Martins */ 46050c88402SJoao Martins XEN_GUEST_HANDLE(const_uint8) access_list; 46150c88402SJoao Martins }; 46250c88402SJoao Martins typedef struct xen_mem_access_op xen_mem_access_op_t; 46350c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t); 46450c88402SJoao Martins 46550c88402SJoao Martins #define XENMEM_sharing_op 22 46650c88402SJoao Martins #define XENMEM_sharing_op_nominate_gfn 0 46750c88402SJoao Martins #define XENMEM_sharing_op_nominate_gref 1 46850c88402SJoao Martins #define XENMEM_sharing_op_share 2 46950c88402SJoao Martins #define XENMEM_sharing_op_debug_gfn 3 47050c88402SJoao Martins #define XENMEM_sharing_op_debug_mfn 4 47150c88402SJoao Martins #define XENMEM_sharing_op_debug_gref 5 47250c88402SJoao Martins #define XENMEM_sharing_op_add_physmap 6 47350c88402SJoao Martins #define XENMEM_sharing_op_audit 7 47450c88402SJoao Martins #define XENMEM_sharing_op_range_share 8 47550c88402SJoao Martins #define XENMEM_sharing_op_fork 9 47650c88402SJoao Martins #define XENMEM_sharing_op_fork_reset 10 47750c88402SJoao Martins 47850c88402SJoao Martins #define XENMEM_SHARING_OP_S_HANDLE_INVALID (-10) 47950c88402SJoao Martins #define XENMEM_SHARING_OP_C_HANDLE_INVALID (-9) 48050c88402SJoao Martins 48150c88402SJoao Martins /* The following allows sharing of grant refs. This is useful 48250c88402SJoao Martins * for sharing utilities sitting as "filters" in IO backends 48350c88402SJoao Martins * (e.g. memshr + blktap(2)). The IO backend is only exposed 48450c88402SJoao Martins * to grant references, and this allows sharing of the grefs */ 48550c88402SJoao Martins #define XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG (xen_mk_ullong(1) << 62) 48650c88402SJoao Martins 48750c88402SJoao Martins #define XENMEM_SHARING_OP_FIELD_MAKE_GREF(field, val) \ 48850c88402SJoao Martins (field) = (XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG | val) 48950c88402SJoao Martins #define XENMEM_SHARING_OP_FIELD_IS_GREF(field) \ 49050c88402SJoao Martins ((field) & XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG) 49150c88402SJoao Martins #define XENMEM_SHARING_OP_FIELD_GET_GREF(field) \ 49250c88402SJoao Martins ((field) & (~XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG)) 49350c88402SJoao Martins 49450c88402SJoao Martins struct xen_mem_sharing_op { 49550c88402SJoao Martins uint8_t op; /* XENMEM_sharing_op_* */ 49650c88402SJoao Martins domid_t domain; 49750c88402SJoao Martins 49850c88402SJoao Martins union { 49950c88402SJoao Martins struct mem_sharing_op_nominate { /* OP_NOMINATE_xxx */ 50050c88402SJoao Martins union { 50150c88402SJoao Martins uint64_aligned_t gfn; /* IN: gfn to nominate */ 50250c88402SJoao Martins uint32_t grant_ref; /* IN: grant ref to nominate */ 50350c88402SJoao Martins } u; 50450c88402SJoao Martins uint64_aligned_t handle; /* OUT: the handle */ 50550c88402SJoao Martins } nominate; 50650c88402SJoao Martins struct mem_sharing_op_share { /* OP_SHARE/ADD_PHYSMAP */ 50750c88402SJoao Martins uint64_aligned_t source_gfn; /* IN: the gfn of the source page */ 50850c88402SJoao Martins uint64_aligned_t source_handle; /* IN: handle to the source page */ 50950c88402SJoao Martins uint64_aligned_t client_gfn; /* IN: the client gfn */ 51050c88402SJoao Martins uint64_aligned_t client_handle; /* IN: handle to the client page */ 51150c88402SJoao Martins domid_t client_domain; /* IN: the client domain id */ 51250c88402SJoao Martins } share; 51350c88402SJoao Martins struct mem_sharing_op_range { /* OP_RANGE_SHARE */ 51450c88402SJoao Martins uint64_aligned_t first_gfn; /* IN: the first gfn */ 51550c88402SJoao Martins uint64_aligned_t last_gfn; /* IN: the last gfn */ 51650c88402SJoao Martins uint64_aligned_t opaque; /* Must be set to 0 */ 51750c88402SJoao Martins domid_t client_domain; /* IN: the client domain id */ 51850c88402SJoao Martins uint16_t _pad[3]; /* Must be set to 0 */ 51950c88402SJoao Martins } range; 52050c88402SJoao Martins struct mem_sharing_op_debug { /* OP_DEBUG_xxx */ 52150c88402SJoao Martins union { 52250c88402SJoao Martins uint64_aligned_t gfn; /* IN: gfn to debug */ 52350c88402SJoao Martins uint64_aligned_t mfn; /* IN: mfn to debug */ 52450c88402SJoao Martins uint32_t gref; /* IN: gref to debug */ 52550c88402SJoao Martins } u; 52650c88402SJoao Martins } debug; 527*8ac98aedSDavid Woodhouse struct mem_sharing_op_fork { /* OP_FORK{,_RESET} */ 52850c88402SJoao Martins domid_t parent_domain; /* IN: parent's domain id */ 52950c88402SJoao Martins /* Only makes sense for short-lived forks */ 53050c88402SJoao Martins #define XENMEM_FORK_WITH_IOMMU_ALLOWED (1u << 0) 53150c88402SJoao Martins /* Only makes sense for short-lived forks */ 53250c88402SJoao Martins #define XENMEM_FORK_BLOCK_INTERRUPTS (1u << 1) 533*8ac98aedSDavid Woodhouse #define XENMEM_FORK_RESET_STATE (1u << 2) 534*8ac98aedSDavid Woodhouse #define XENMEM_FORK_RESET_MEMORY (1u << 3) 53550c88402SJoao Martins uint16_t flags; /* IN: optional settings */ 53650c88402SJoao Martins uint32_t pad; /* Must be set to 0 */ 53750c88402SJoao Martins } fork; 53850c88402SJoao Martins } u; 53950c88402SJoao Martins }; 54050c88402SJoao Martins typedef struct xen_mem_sharing_op xen_mem_sharing_op_t; 54150c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_mem_sharing_op_t); 54250c88402SJoao Martins 54350c88402SJoao Martins /* 54450c88402SJoao Martins * Attempt to stake a claim for a domain on a quantity of pages 54550c88402SJoao Martins * of system RAM, but _not_ assign specific pageframes. Only 54650c88402SJoao Martins * arithmetic is performed so the hypercall is very fast and need 54750c88402SJoao Martins * not be preemptible, thus sidestepping time-of-check-time-of-use 54850c88402SJoao Martins * races for memory allocation. Returns 0 if the hypervisor page 54950c88402SJoao Martins * allocator has atomically and successfully claimed the requested 55050c88402SJoao Martins * number of pages, else non-zero. 55150c88402SJoao Martins * 55250c88402SJoao Martins * Any domain may have only one active claim. When sufficient memory 55350c88402SJoao Martins * has been allocated to resolve the claim, the claim silently expires. 55450c88402SJoao Martins * Claiming zero pages effectively resets any outstanding claim and 55550c88402SJoao Martins * is always successful. 55650c88402SJoao Martins * 55750c88402SJoao Martins * Note that a valid claim may be staked even after memory has been 55850c88402SJoao Martins * allocated for a domain. In this case, the claim is not incremental, 55950c88402SJoao Martins * i.e. if the domain's total page count is 3, and a claim is staked 56050c88402SJoao Martins * for 10, only 7 additional pages are claimed. 56150c88402SJoao Martins * 56250c88402SJoao Martins * Caller must be privileged or the hypercall fails. 56350c88402SJoao Martins */ 56450c88402SJoao Martins #define XENMEM_claim_pages 24 56550c88402SJoao Martins 56650c88402SJoao Martins /* 56750c88402SJoao Martins * XENMEM_claim_pages flags - the are no flags at this time. 56850c88402SJoao Martins * The zero value is appropriate. 56950c88402SJoao Martins */ 57050c88402SJoao Martins 57150c88402SJoao Martins /* 57250c88402SJoao Martins * With some legacy devices, certain guest-physical addresses cannot safely 57350c88402SJoao Martins * be used for other purposes, e.g. to map guest RAM. This hypercall 57450c88402SJoao Martins * enumerates those regions so the toolstack can avoid using them. 57550c88402SJoao Martins */ 57650c88402SJoao Martins #define XENMEM_reserved_device_memory_map 27 57750c88402SJoao Martins struct xen_reserved_device_memory { 57850c88402SJoao Martins xen_pfn_t start_pfn; 57950c88402SJoao Martins xen_ulong_t nr_pages; 58050c88402SJoao Martins }; 58150c88402SJoao Martins typedef struct xen_reserved_device_memory xen_reserved_device_memory_t; 58250c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_t); 58350c88402SJoao Martins 58450c88402SJoao Martins struct xen_reserved_device_memory_map { 58550c88402SJoao Martins #define XENMEM_RDM_ALL 1 /* Request all regions (ignore dev union). */ 58650c88402SJoao Martins /* IN */ 58750c88402SJoao Martins uint32_t flags; 58850c88402SJoao Martins /* 58950c88402SJoao Martins * IN/OUT 59050c88402SJoao Martins * 59150c88402SJoao Martins * Gets set to the required number of entries when too low, 59250c88402SJoao Martins * signaled by error code -ERANGE. 59350c88402SJoao Martins */ 59450c88402SJoao Martins unsigned int nr_entries; 59550c88402SJoao Martins /* OUT */ 59650c88402SJoao Martins XEN_GUEST_HANDLE(xen_reserved_device_memory_t) buffer; 59750c88402SJoao Martins /* IN */ 59850c88402SJoao Martins union { 59950c88402SJoao Martins physdev_pci_device_t pci; 60050c88402SJoao Martins } dev; 60150c88402SJoao Martins }; 60250c88402SJoao Martins typedef struct xen_reserved_device_memory_map xen_reserved_device_memory_map_t; 60350c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_map_t); 60450c88402SJoao Martins 60550c88402SJoao Martins #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ 60650c88402SJoao Martins 60750c88402SJoao Martins /* 60850c88402SJoao Martins * Get the pages for a particular guest resource, so that they can be 60950c88402SJoao Martins * mapped directly by a tools domain. 61050c88402SJoao Martins */ 61150c88402SJoao Martins #define XENMEM_acquire_resource 28 61250c88402SJoao Martins struct xen_mem_acquire_resource { 61350c88402SJoao Martins /* IN - The domain whose resource is to be mapped */ 61450c88402SJoao Martins domid_t domid; 61550c88402SJoao Martins /* IN - the type of resource */ 61650c88402SJoao Martins uint16_t type; 61750c88402SJoao Martins 61850c88402SJoao Martins #define XENMEM_resource_ioreq_server 0 61950c88402SJoao Martins #define XENMEM_resource_grant_table 1 62050c88402SJoao Martins #define XENMEM_resource_vmtrace_buf 2 62150c88402SJoao Martins 62250c88402SJoao Martins /* 62350c88402SJoao Martins * IN - a type-specific resource identifier, which must be zero 62450c88402SJoao Martins * unless stated otherwise. 62550c88402SJoao Martins * 62650c88402SJoao Martins * type == XENMEM_resource_ioreq_server -> id == ioreq server id 62750c88402SJoao Martins * type == XENMEM_resource_grant_table -> id defined below 62850c88402SJoao Martins */ 62950c88402SJoao Martins uint32_t id; 63050c88402SJoao Martins 63150c88402SJoao Martins #define XENMEM_resource_grant_table_id_shared 0 63250c88402SJoao Martins #define XENMEM_resource_grant_table_id_status 1 63350c88402SJoao Martins 63450c88402SJoao Martins /* 63550c88402SJoao Martins * IN/OUT 63650c88402SJoao Martins * 63750c88402SJoao Martins * As an IN parameter number of frames of the resource to be mapped. 63850c88402SJoao Martins * This value may be updated over the course of the operation. 63950c88402SJoao Martins * 64050c88402SJoao Martins * When frame_list is NULL and nr_frames is 0, this is interpreted as a 64150c88402SJoao Martins * request for the size of the resource, which shall be returned in the 64250c88402SJoao Martins * nr_frames field. 64350c88402SJoao Martins * 64450c88402SJoao Martins * The size of a resource will never be zero, but a nonzero result doesn't 64550c88402SJoao Martins * guarantee that a subsequent mapping request will be successful. There 64650c88402SJoao Martins * are further type/id specific constraints which may change between the 64750c88402SJoao Martins * two calls. 64850c88402SJoao Martins */ 64950c88402SJoao Martins uint32_t nr_frames; 650*8ac98aedSDavid Woodhouse /* 651*8ac98aedSDavid Woodhouse * Padding field, must be zero on input. 652*8ac98aedSDavid Woodhouse * In a previous version this was an output field with the lowest bit 653*8ac98aedSDavid Woodhouse * named XENMEM_rsrc_acq_caller_owned. Future versions of this interface 654*8ac98aedSDavid Woodhouse * will not reuse this bit as an output with the field being zero on 655*8ac98aedSDavid Woodhouse * input. 656*8ac98aedSDavid Woodhouse */ 65750c88402SJoao Martins uint32_t pad; 65850c88402SJoao Martins /* 65950c88402SJoao Martins * IN - the index of the initial frame to be mapped. This parameter 66050c88402SJoao Martins * is ignored if nr_frames is 0. This value may be updated 66150c88402SJoao Martins * over the course of the operation. 66250c88402SJoao Martins */ 66350c88402SJoao Martins uint64_t frame; 66450c88402SJoao Martins 66550c88402SJoao Martins #define XENMEM_resource_ioreq_server_frame_bufioreq 0 66650c88402SJoao Martins #define XENMEM_resource_ioreq_server_frame_ioreq(n) (1 + (n)) 66750c88402SJoao Martins 66850c88402SJoao Martins /* 66950c88402SJoao Martins * IN/OUT - If the tools domain is PV then, upon return, frame_list 67050c88402SJoao Martins * will be populated with the MFNs of the resource. 67150c88402SJoao Martins * If the tools domain is HVM then it is expected that, on 67250c88402SJoao Martins * entry, frame_list will be populated with a list of GFNs 67350c88402SJoao Martins * that will be mapped to the MFNs of the resource. 67450c88402SJoao Martins * If -EIO is returned then the frame_list has only been 67550c88402SJoao Martins * partially mapped and it is up to the caller to unmap all 67650c88402SJoao Martins * the GFNs. 67750c88402SJoao Martins * This parameter may be NULL if nr_frames is 0. This 67850c88402SJoao Martins * value may be updated over the course of the operation. 67950c88402SJoao Martins */ 68050c88402SJoao Martins XEN_GUEST_HANDLE(xen_pfn_t) frame_list; 68150c88402SJoao Martins }; 68250c88402SJoao Martins typedef struct xen_mem_acquire_resource xen_mem_acquire_resource_t; 68350c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_mem_acquire_resource_t); 68450c88402SJoao Martins 68550c88402SJoao Martins /* 68650c88402SJoao Martins * XENMEM_get_vnumainfo used by guest to get 68750c88402SJoao Martins * vNUMA topology from hypervisor. 68850c88402SJoao Martins */ 68950c88402SJoao Martins #define XENMEM_get_vnumainfo 26 69050c88402SJoao Martins 69150c88402SJoao Martins /* vNUMA node memory ranges */ 69250c88402SJoao Martins struct xen_vmemrange { 69350c88402SJoao Martins uint64_t start, end; 69450c88402SJoao Martins unsigned int flags; 69550c88402SJoao Martins unsigned int nid; 69650c88402SJoao Martins }; 69750c88402SJoao Martins typedef struct xen_vmemrange xen_vmemrange_t; 69850c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_vmemrange_t); 69950c88402SJoao Martins 70050c88402SJoao Martins /* 70150c88402SJoao Martins * vNUMA topology specifies vNUMA node number, distance table, 70250c88402SJoao Martins * memory ranges and vcpu mapping provided for guests. 70350c88402SJoao Martins * XENMEM_get_vnumainfo hypercall expects to see from guest 70450c88402SJoao Martins * nr_vnodes, nr_vmemranges and nr_vcpus to indicate available memory. 70550c88402SJoao Martins * After filling guests structures, nr_vnodes, nr_vmemranges and nr_vcpus 70650c88402SJoao Martins * copied back to guest. Domain returns expected values of nr_vnodes, 70750c88402SJoao Martins * nr_vmemranges and nr_vcpus to guest if the values where incorrect. 70850c88402SJoao Martins */ 70950c88402SJoao Martins struct xen_vnuma_topology_info { 71050c88402SJoao Martins /* IN */ 71150c88402SJoao Martins domid_t domid; 71250c88402SJoao Martins uint16_t pad; 71350c88402SJoao Martins /* IN/OUT */ 71450c88402SJoao Martins unsigned int nr_vnodes; 71550c88402SJoao Martins unsigned int nr_vcpus; 71650c88402SJoao Martins unsigned int nr_vmemranges; 71750c88402SJoao Martins /* OUT */ 71850c88402SJoao Martins union { 71950c88402SJoao Martins XEN_GUEST_HANDLE(uint) h; 72050c88402SJoao Martins uint64_t pad; 72150c88402SJoao Martins } vdistance; 72250c88402SJoao Martins union { 72350c88402SJoao Martins XEN_GUEST_HANDLE(uint) h; 72450c88402SJoao Martins uint64_t pad; 72550c88402SJoao Martins } vcpu_to_vnode; 72650c88402SJoao Martins union { 72750c88402SJoao Martins XEN_GUEST_HANDLE(xen_vmemrange_t) h; 72850c88402SJoao Martins uint64_t pad; 72950c88402SJoao Martins } vmemrange; 73050c88402SJoao Martins }; 73150c88402SJoao Martins typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t; 73250c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t); 73350c88402SJoao Martins 73450c88402SJoao Martins /* Next available subop number is 29 */ 73550c88402SJoao Martins 73650c88402SJoao Martins #endif /* __XEN_PUBLIC_MEMORY_H__ */ 73750c88402SJoao Martins 73850c88402SJoao Martins /* 73950c88402SJoao Martins * Local variables: 74050c88402SJoao Martins * mode: C 74150c88402SJoao Martins * c-file-style: "BSD" 74250c88402SJoao Martins * c-basic-offset: 4 74350c88402SJoao Martins * tab-width: 4 74450c88402SJoao Martins * indent-tabs-mode: nil 74550c88402SJoao Martins * End: 74650c88402SJoao Martins */ 747