1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /****************************************************************************** 3*4882a593Smuzhiyun * memory.h 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Memory reservation and information. 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Copyright (c) 2005, Keir Fraser <keir@xensource.com> 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #ifndef __XEN_PUBLIC_MEMORY_H__ 11*4882a593Smuzhiyun #define __XEN_PUBLIC_MEMORY_H__ 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun #include <linux/spinlock.h> 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun /* 16*4882a593Smuzhiyun * Increase or decrease the specified domain's memory reservation. Returns a 17*4882a593Smuzhiyun * -ve errcode on failure, or the # extents successfully allocated or freed. 18*4882a593Smuzhiyun * arg == addr of struct xen_memory_reservation. 19*4882a593Smuzhiyun */ 20*4882a593Smuzhiyun #define XENMEM_increase_reservation 0 21*4882a593Smuzhiyun #define XENMEM_decrease_reservation 1 22*4882a593Smuzhiyun #define XENMEM_populate_physmap 6 23*4882a593Smuzhiyun struct xen_memory_reservation { 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun /* 26*4882a593Smuzhiyun * XENMEM_increase_reservation: 27*4882a593Smuzhiyun * OUT: MFN (*not* GMFN) bases of extents that were allocated 28*4882a593Smuzhiyun * XENMEM_decrease_reservation: 29*4882a593Smuzhiyun * IN: GMFN bases of extents to free 30*4882a593Smuzhiyun * XENMEM_populate_physmap: 31*4882a593Smuzhiyun * IN: GPFN bases of extents to populate with memory 32*4882a593Smuzhiyun * OUT: GMFN bases of extents that were allocated 33*4882a593Smuzhiyun * (NB. This command also updates the mach_to_phys translation table) 34*4882a593Smuzhiyun */ 35*4882a593Smuzhiyun GUEST_HANDLE(xen_pfn_t) extent_start; 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun /* Number of extents, and size/alignment of each (2^extent_order pages). */ 38*4882a593Smuzhiyun xen_ulong_t nr_extents; 39*4882a593Smuzhiyun unsigned int extent_order; 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /* 42*4882a593Smuzhiyun * Maximum # bits addressable by the user of the allocated region (e.g., 43*4882a593Smuzhiyun * I/O devices often have a 32-bit limitation even in 64-bit systems). If 44*4882a593Smuzhiyun * zero then the user has no addressing restriction. 45*4882a593Smuzhiyun * This field is not used by XENMEM_decrease_reservation. 46*4882a593Smuzhiyun */ 47*4882a593Smuzhiyun unsigned int address_bits; 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun /* 50*4882a593Smuzhiyun * Domain whose reservation is being changed. 51*4882a593Smuzhiyun * Unprivileged domains can specify only DOMID_SELF. 52*4882a593Smuzhiyun */ 53*4882a593Smuzhiyun domid_t domid; 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun }; 56*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(xen_memory_reservation); 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /* 59*4882a593Smuzhiyun * An atomic exchange of memory pages. If return code is zero then 60*4882a593Smuzhiyun * @out.extent_list provides GMFNs of the newly-allocated memory. 61*4882a593Smuzhiyun * Returns zero on complete success, otherwise a negative error code. 62*4882a593Smuzhiyun * On complete success then always @nr_exchanged == @in.nr_extents. 63*4882a593Smuzhiyun * On partial success @nr_exchanged indicates how much work was done. 64*4882a593Smuzhiyun */ 65*4882a593Smuzhiyun #define XENMEM_exchange 11 66*4882a593Smuzhiyun struct xen_memory_exchange { 67*4882a593Smuzhiyun /* 68*4882a593Smuzhiyun * [IN] Details of memory extents to be exchanged (GMFN bases). 69*4882a593Smuzhiyun * Note that @in.address_bits is ignored and unused. 70*4882a593Smuzhiyun */ 71*4882a593Smuzhiyun struct xen_memory_reservation in; 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun /* 74*4882a593Smuzhiyun * [IN/OUT] Details of new memory extents. 75*4882a593Smuzhiyun * We require that: 76*4882a593Smuzhiyun * 1. @in.domid == @out.domid 77*4882a593Smuzhiyun * 2. @in.nr_extents << @in.extent_order == 78*4882a593Smuzhiyun * @out.nr_extents << @out.extent_order 79*4882a593Smuzhiyun * 3. @in.extent_start and @out.extent_start lists must not overlap 80*4882a593Smuzhiyun * 4. @out.extent_start lists GPFN bases to be populated 81*4882a593Smuzhiyun * 5. @out.extent_start is overwritten with allocated GMFN bases 82*4882a593Smuzhiyun */ 83*4882a593Smuzhiyun struct xen_memory_reservation out; 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun /* 86*4882a593Smuzhiyun * [OUT] Number of input extents that were successfully exchanged: 87*4882a593Smuzhiyun * 1. The first @nr_exchanged input extents were successfully 88*4882a593Smuzhiyun * deallocated. 89*4882a593Smuzhiyun * 2. The corresponding first entries in the output extent list correctly 90*4882a593Smuzhiyun * indicate the GMFNs that were successfully exchanged. 91*4882a593Smuzhiyun * 3. All other input and output extents are untouched. 92*4882a593Smuzhiyun * 4. If not all input exents are exchanged then the return code of this 93*4882a593Smuzhiyun * command will be non-zero. 94*4882a593Smuzhiyun * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER! 95*4882a593Smuzhiyun */ 96*4882a593Smuzhiyun xen_ulong_t nr_exchanged; 97*4882a593Smuzhiyun }; 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(xen_memory_exchange); 100*4882a593Smuzhiyun /* 101*4882a593Smuzhiyun * Returns the maximum machine frame number of mapped RAM in this system. 102*4882a593Smuzhiyun * This command always succeeds (it never returns an error code). 103*4882a593Smuzhiyun * arg == NULL. 104*4882a593Smuzhiyun */ 105*4882a593Smuzhiyun #define XENMEM_maximum_ram_page 2 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun /* 108*4882a593Smuzhiyun * Returns the current or maximum memory reservation, in pages, of the 109*4882a593Smuzhiyun * specified domain (may be DOMID_SELF). Returns -ve errcode on failure. 110*4882a593Smuzhiyun * arg == addr of domid_t. 111*4882a593Smuzhiyun */ 112*4882a593Smuzhiyun #define XENMEM_current_reservation 3 113*4882a593Smuzhiyun #define XENMEM_maximum_reservation 4 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun /* 116*4882a593Smuzhiyun * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys 117*4882a593Smuzhiyun * mapping table. Architectures which do not have a m2p table do not implement 118*4882a593Smuzhiyun * this command. 119*4882a593Smuzhiyun * arg == addr of xen_machphys_mfn_list_t. 120*4882a593Smuzhiyun */ 121*4882a593Smuzhiyun #define XENMEM_machphys_mfn_list 5 122*4882a593Smuzhiyun struct xen_machphys_mfn_list { 123*4882a593Smuzhiyun /* 124*4882a593Smuzhiyun * Size of the 'extent_start' array. Fewer entries will be filled if the 125*4882a593Smuzhiyun * machphys table is smaller than max_extents * 2MB. 126*4882a593Smuzhiyun */ 127*4882a593Smuzhiyun unsigned int max_extents; 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun /* 130*4882a593Smuzhiyun * Pointer to buffer to fill with list of extent starts. If there are 131*4882a593Smuzhiyun * any large discontiguities in the machine address space, 2MB gaps in 132*4882a593Smuzhiyun * the machphys table will be represented by an MFN base of zero. 133*4882a593Smuzhiyun */ 134*4882a593Smuzhiyun GUEST_HANDLE(xen_pfn_t) extent_start; 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun /* 137*4882a593Smuzhiyun * Number of extents written to the above array. This will be smaller 138*4882a593Smuzhiyun * than 'max_extents' if the machphys table is smaller than max_e * 2MB. 139*4882a593Smuzhiyun */ 140*4882a593Smuzhiyun unsigned int nr_extents; 141*4882a593Smuzhiyun }; 142*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mfn_list); 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun /* 145*4882a593Smuzhiyun * Returns the location in virtual address space of the machine_to_phys 146*4882a593Smuzhiyun * mapping table. Architectures which do not have a m2p table, or which do not 147*4882a593Smuzhiyun * map it by default into guest address space, do not implement this command. 148*4882a593Smuzhiyun * arg == addr of xen_machphys_mapping_t. 149*4882a593Smuzhiyun */ 150*4882a593Smuzhiyun #define XENMEM_machphys_mapping 12 151*4882a593Smuzhiyun struct xen_machphys_mapping { 152*4882a593Smuzhiyun xen_ulong_t v_start, v_end; /* Start and end virtual addresses. */ 153*4882a593Smuzhiyun xen_ulong_t max_mfn; /* Maximum MFN that can be looked up. */ 154*4882a593Smuzhiyun }; 155*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t); 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun #define XENMAPSPACE_shared_info 0 /* shared info page */ 158*4882a593Smuzhiyun #define XENMAPSPACE_grant_table 1 /* grant table page */ 159*4882a593Smuzhiyun #define XENMAPSPACE_gmfn 2 /* GMFN */ 160*4882a593Smuzhiyun #define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap only. */ 161*4882a593Smuzhiyun #define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom, 162*4882a593Smuzhiyun * XENMEM_add_to_physmap_range only. 163*4882a593Smuzhiyun */ 164*4882a593Smuzhiyun #define XENMAPSPACE_dev_mmio 5 /* device mmio region */ 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun /* 167*4882a593Smuzhiyun * Sets the GPFN at which a particular page appears in the specified guest's 168*4882a593Smuzhiyun * pseudophysical address space. 169*4882a593Smuzhiyun * arg == addr of xen_add_to_physmap_t. 170*4882a593Smuzhiyun */ 171*4882a593Smuzhiyun #define XENMEM_add_to_physmap 7 172*4882a593Smuzhiyun struct xen_add_to_physmap { 173*4882a593Smuzhiyun /* Which domain to change the mapping for. */ 174*4882a593Smuzhiyun domid_t domid; 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun /* Number of pages to go through for gmfn_range */ 177*4882a593Smuzhiyun uint16_t size; 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun /* Source mapping space. */ 180*4882a593Smuzhiyun unsigned int space; 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun /* Index into source mapping space. */ 183*4882a593Smuzhiyun xen_ulong_t idx; 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun /* GPFN where the source mapping page should appear. */ 186*4882a593Smuzhiyun xen_pfn_t gpfn; 187*4882a593Smuzhiyun }; 188*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap); 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun /*** REMOVED ***/ 191*4882a593Smuzhiyun /*#define XENMEM_translate_gpfn_list 8*/ 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun #define XENMEM_add_to_physmap_range 23 194*4882a593Smuzhiyun struct xen_add_to_physmap_range { 195*4882a593Smuzhiyun /* IN */ 196*4882a593Smuzhiyun /* Which domain to change the mapping for. */ 197*4882a593Smuzhiyun domid_t domid; 198*4882a593Smuzhiyun uint16_t space; /* => enum phys_map_space */ 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun /* Number of pages to go through */ 201*4882a593Smuzhiyun uint16_t size; 202*4882a593Smuzhiyun domid_t foreign_domid; /* IFF gmfn_foreign */ 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun /* Indexes into space being mapped. */ 205*4882a593Smuzhiyun GUEST_HANDLE(xen_ulong_t) idxs; 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun /* GPFN in domid where the source mapping page should appear. */ 208*4882a593Smuzhiyun GUEST_HANDLE(xen_pfn_t) gpfns; 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun /* OUT */ 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun /* Per index error code. */ 213*4882a593Smuzhiyun GUEST_HANDLE(int) errs; 214*4882a593Smuzhiyun }; 215*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap_range); 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun /* 218*4882a593Smuzhiyun * Returns the pseudo-physical memory map as it was when the domain 219*4882a593Smuzhiyun * was started (specified by XENMEM_set_memory_map). 220*4882a593Smuzhiyun * arg == addr of struct xen_memory_map. 221*4882a593Smuzhiyun */ 222*4882a593Smuzhiyun #define XENMEM_memory_map 9 223*4882a593Smuzhiyun struct xen_memory_map { 224*4882a593Smuzhiyun /* 225*4882a593Smuzhiyun * On call the number of entries which can be stored in buffer. On 226*4882a593Smuzhiyun * return the number of entries which have been stored in 227*4882a593Smuzhiyun * buffer. 228*4882a593Smuzhiyun */ 229*4882a593Smuzhiyun unsigned int nr_entries; 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun /* 232*4882a593Smuzhiyun * Entries in the buffer are in the same format as returned by the 233*4882a593Smuzhiyun * BIOS INT 0x15 EAX=0xE820 call. 234*4882a593Smuzhiyun */ 235*4882a593Smuzhiyun GUEST_HANDLE(void) buffer; 236*4882a593Smuzhiyun }; 237*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(xen_memory_map); 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun /* 240*4882a593Smuzhiyun * Returns the real physical memory map. Passes the same structure as 241*4882a593Smuzhiyun * XENMEM_memory_map. 242*4882a593Smuzhiyun * arg == addr of struct xen_memory_map. 243*4882a593Smuzhiyun */ 244*4882a593Smuzhiyun #define XENMEM_machine_memory_map 10 245*4882a593Smuzhiyun 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun /* 248*4882a593Smuzhiyun * Unmaps the page appearing at a particular GPFN from the specified guest's 249*4882a593Smuzhiyun * pseudophysical address space. 250*4882a593Smuzhiyun * arg == addr of xen_remove_from_physmap_t. 251*4882a593Smuzhiyun */ 252*4882a593Smuzhiyun #define XENMEM_remove_from_physmap 15 253*4882a593Smuzhiyun struct xen_remove_from_physmap { 254*4882a593Smuzhiyun /* Which domain to change the mapping for. */ 255*4882a593Smuzhiyun domid_t domid; 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun /* GPFN of the current mapping of the page. */ 258*4882a593Smuzhiyun xen_pfn_t gpfn; 259*4882a593Smuzhiyun }; 260*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(xen_remove_from_physmap); 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun /* 263*4882a593Smuzhiyun * Get the pages for a particular guest resource, so that they can be 264*4882a593Smuzhiyun * mapped directly by a tools domain. 265*4882a593Smuzhiyun */ 266*4882a593Smuzhiyun #define XENMEM_acquire_resource 28 267*4882a593Smuzhiyun struct xen_mem_acquire_resource { 268*4882a593Smuzhiyun /* IN - The domain whose resource is to be mapped */ 269*4882a593Smuzhiyun domid_t domid; 270*4882a593Smuzhiyun /* IN - the type of resource */ 271*4882a593Smuzhiyun uint16_t type; 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun #define XENMEM_resource_ioreq_server 0 274*4882a593Smuzhiyun #define XENMEM_resource_grant_table 1 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun /* 277*4882a593Smuzhiyun * IN - a type-specific resource identifier, which must be zero 278*4882a593Smuzhiyun * unless stated otherwise. 279*4882a593Smuzhiyun * 280*4882a593Smuzhiyun * type == XENMEM_resource_ioreq_server -> id == ioreq server id 281*4882a593Smuzhiyun * type == XENMEM_resource_grant_table -> id defined below 282*4882a593Smuzhiyun */ 283*4882a593Smuzhiyun uint32_t id; 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun #define XENMEM_resource_grant_table_id_shared 0 286*4882a593Smuzhiyun #define XENMEM_resource_grant_table_id_status 1 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun /* IN/OUT - As an IN parameter number of frames of the resource 289*4882a593Smuzhiyun * to be mapped. However, if the specified value is 0 and 290*4882a593Smuzhiyun * frame_list is NULL then this field will be set to the 291*4882a593Smuzhiyun * maximum value supported by the implementation on return. 292*4882a593Smuzhiyun */ 293*4882a593Smuzhiyun uint32_t nr_frames; 294*4882a593Smuzhiyun /* 295*4882a593Smuzhiyun * OUT - Must be zero on entry. On return this may contain a bitwise 296*4882a593Smuzhiyun * OR of the following values. 297*4882a593Smuzhiyun */ 298*4882a593Smuzhiyun uint32_t flags; 299*4882a593Smuzhiyun 300*4882a593Smuzhiyun /* The resource pages have been assigned to the calling domain */ 301*4882a593Smuzhiyun #define _XENMEM_rsrc_acq_caller_owned 0 302*4882a593Smuzhiyun #define XENMEM_rsrc_acq_caller_owned (1u << _XENMEM_rsrc_acq_caller_owned) 303*4882a593Smuzhiyun 304*4882a593Smuzhiyun /* 305*4882a593Smuzhiyun * IN - the index of the initial frame to be mapped. This parameter 306*4882a593Smuzhiyun * is ignored if nr_frames is 0. 307*4882a593Smuzhiyun */ 308*4882a593Smuzhiyun uint64_t frame; 309*4882a593Smuzhiyun 310*4882a593Smuzhiyun #define XENMEM_resource_ioreq_server_frame_bufioreq 0 311*4882a593Smuzhiyun #define XENMEM_resource_ioreq_server_frame_ioreq(n) (1 + (n)) 312*4882a593Smuzhiyun 313*4882a593Smuzhiyun /* 314*4882a593Smuzhiyun * IN/OUT - If the tools domain is PV then, upon return, frame_list 315*4882a593Smuzhiyun * will be populated with the MFNs of the resource. 316*4882a593Smuzhiyun * If the tools domain is HVM then it is expected that, on 317*4882a593Smuzhiyun * entry, frame_list will be populated with a list of GFNs 318*4882a593Smuzhiyun * that will be mapped to the MFNs of the resource. 319*4882a593Smuzhiyun * If -EIO is returned then the frame_list has only been 320*4882a593Smuzhiyun * partially mapped and it is up to the caller to unmap all 321*4882a593Smuzhiyun * the GFNs. 322*4882a593Smuzhiyun * This parameter may be NULL if nr_frames is 0. 323*4882a593Smuzhiyun */ 324*4882a593Smuzhiyun GUEST_HANDLE(xen_pfn_t) frame_list; 325*4882a593Smuzhiyun }; 326*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(xen_mem_acquire_resource); 327*4882a593Smuzhiyun 328*4882a593Smuzhiyun #endif /* __XEN_PUBLIC_MEMORY_H__ */ 329