summaryrefslogtreecommitdiff
path: root/tools/include/xenguest.h
blob: a9984dbea56d4a05c1d0443cf2ab14cb738f7e5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
/******************************************************************************
 * xenguest.h
 *
 * A library for guest domain management in Xen.
 *
 * Copyright (c) 2003-2004, K A Fraser.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef XENGUEST_H
#define XENGUEST_H

#define XC_NUMA_NO_NODE   (~0U)

#define XCFLAGS_LIVE      (1 << 0)
#define XCFLAGS_DEBUG     (1 << 1)

#define X86_64_B_SIZE   64 
#define X86_32_B_SIZE   32

#define X86_HVM_NR_SPECIAL_PAGES    8
#define X86_HVM_END_SPECIAL_REGION  0xff000u
#define XG_MAX_MODULES 2

/* --- typedefs and structs ---------------------------------------- */

typedef uint64_t xen_vaddr_t;
typedef uint64_t xen_paddr_t;

#define PRIpfn PRI_xen_pfn

struct xc_dom_seg {
    xen_vaddr_t vstart;
    xen_vaddr_t vend;
    xen_pfn_t pfn;
    xen_pfn_t pages;
};

struct xc_hvm_firmware_module {
    uint8_t  *data;
    uint32_t  length;
    uint64_t  guest_addr_out;
};

struct xc_dom_mem {
    struct xc_dom_mem *next;
    void *ptr;
    enum {
        XC_DOM_MEM_TYPE_MALLOC_INTERNAL,
        XC_DOM_MEM_TYPE_MALLOC_EXTERNAL,
        XC_DOM_MEM_TYPE_MMAP,
    } type;
    size_t len;
    unsigned char memory[0];
};

struct xc_dom_phys {
    struct xc_dom_phys *next;
    void *ptr;
    xen_pfn_t first;
    xen_pfn_t count;
};

struct xc_dom_module {
    void *blob;
    size_t size;
    void *cmdline;
    /* If seg.vstart is non zero then the module will be loaded at that
     * address, otherwise it will automatically placed.
     *
     * If automatic placement is used and the module is gzip
     * compressed then it will be decompressed as it is loaded. If the
     * module has been explicitly placed then it is loaded as is
     * otherwise decompressing risks undoing the manual placement.
     */
    struct xc_dom_seg seg;
};

struct xc_dom_image {
    /* files */
    void *kernel_blob;
    size_t kernel_size;
    unsigned int num_modules;
    struct xc_dom_module modules[XG_MAX_MODULES];
    void *devicetree_blob;
    size_t devicetree_size;

    size_t max_kernel_size;
    size_t max_module_size;
    size_t max_devicetree_size;

    /* arguments and parameters */
    char *cmdline;
    size_t cmdline_size;
    uint32_t f_requested[XENFEAT_NR_SUBMAPS];

    /* info from (elf) kernel image */
    struct elf_dom_parms *parms;
    char *guest_type;

    /* memory layout */
    struct xc_dom_seg kernel_seg;
    struct xc_dom_seg p2m_seg;
    struct xc_dom_seg pgtables_seg;
    struct xc_dom_seg devicetree_seg;
    struct xc_dom_seg start_info_seg;
    xen_pfn_t start_info_pfn;
    xen_pfn_t console_pfn;
    xen_pfn_t xenstore_pfn;
    xen_pfn_t shared_info_pfn;
    xen_pfn_t bootstack_pfn;
    xen_pfn_t pfn_alloc_end;
    xen_vaddr_t virt_alloc_end;
    xen_vaddr_t bsd_symtab_start;

    /*
     * initrd parameters as specified in start_info page
     * Depending on capabilities of the booted kernel this may be a virtual
     * address or a pfn. Type is neutral and large enough to hold a virtual
     * address of a 64 bit kernel even with 32 bit toolstack.
     */
    uint64_t initrd_start;
    uint64_t initrd_len;

    unsigned int alloc_bootstack;
    xen_vaddr_t virt_pgtab_end;

    /* other state info */
    uint32_t f_active[XENFEAT_NR_SUBMAPS];

    /*
     * pv_p2m is specific to x86 PV guests, and maps GFNs to MFNs.  It is
     * eventually copied into guest context.
     */
    xen_pfn_t *pv_p2m;

    /* physical memory
     *
     * An x86 PV guest has one or more blocks of physical RAM,
     * consisting of total_pages starting at 0. The start address and
     * size of each block is controlled by vNUMA structures.
     *
     * An ARM guest has GUEST_RAM_BANKS regions of RAM, with
     * rambank_size[i] pages in each. The lowest RAM address
     * (corresponding to the base of the p2m arrays above) is stored
     * in rambase_pfn.
     */
    xen_pfn_t rambase_pfn;
    xen_pfn_t total_pages;
    xen_pfn_t p2m_size;         /* number of pfns covered by p2m */
    struct xc_dom_phys *phys_pages;
#if defined (__arm__) || defined(__aarch64__)
    xen_pfn_t rambank_size[GUEST_RAM_BANKS];
#endif

    /* malloc memory pool */
    struct xc_dom_mem *memblocks;

    /* memory footprint stats */
    size_t alloc_malloc;
    size_t alloc_mem_map;
    size_t alloc_file_map;
    size_t alloc_domU_map;

    /* misc xen domain config stuff */
    unsigned long flags;
    unsigned int console_evtchn;
    unsigned int xenstore_evtchn;
    uint32_t console_domid;
    uint32_t xenstore_domid;
    xen_pfn_t shared_info_mfn;

    xc_interface *xch;
    uint32_t guest_domid;
    int claim_enabled; /* 0 by default, 1 enables it */

    int xen_version;
    xen_capabilities_info_t xen_caps;

    /* kernel loader, arch hooks */
    struct xc_dom_loader *kernel_loader;
    void *private_loader;

    /* vNUMA information */
    xen_vmemrange_t *vmemranges;
    unsigned int nr_vmemranges;
    unsigned int *vnode_to_pnode;
    unsigned int nr_vnodes;

    /* domain type/architecture specific data */
    void *arch_private;

    /* kernel loader */
    struct xc_dom_arch *arch_hooks;
    /* allocate up to pfn_alloc_end */
    int (*allocate) (struct xc_dom_image * dom);

    /* Container type (HVM or PV). */
    enum {
        XC_DOM_PV_CONTAINER,
        XC_DOM_HVM_CONTAINER,
    } container_type;

    /* HVM specific fields. */
    xen_pfn_t target_pages;
    xen_paddr_t mmio_start;
    xen_paddr_t mmio_size;
    xen_paddr_t lowmem_end;
    xen_paddr_t highmem_end;
    xen_pfn_t vga_hole_size;

    /* If unset disables the setup of the IOREQ pages. */
    bool device_model;

    /* BIOS/Firmware passed to HVMLOADER */
    struct xc_hvm_firmware_module system_firmware_module;

    /* Extra ACPI tables */
#define MAX_ACPI_MODULES        4
    struct xc_hvm_firmware_module acpi_modules[MAX_ACPI_MODULES];

    /* Extra SMBIOS structures passed to HVMLOADER */
    struct xc_hvm_firmware_module smbios_module;

#if defined(__i386__) || defined(__x86_64__)
    struct e820entry *e820;
    unsigned int e820_entries;
#endif

    xen_pfn_t vuart_gfn;

    /* Number of vCPUs */
    unsigned int max_vcpus;
};

/* --- arch specific hooks ----------------------------------------- */

struct xc_dom_arch {
    int (*alloc_magic_pages) (struct xc_dom_image * dom);

    /* pagetable setup - x86 PV only */
    int (*alloc_pgtables) (struct xc_dom_image * dom);
    int (*alloc_p2m_list) (struct xc_dom_image * dom);
    int (*setup_pgtables) (struct xc_dom_image * dom);

    /* arch-specific data structs setup */
    /* in Mini-OS environment start_info might be a macro, avoid collision. */
#undef start_info
    int (*start_info) (struct xc_dom_image * dom);
    int (*shared_info) (struct xc_dom_image * dom, void *shared_info);
    int (*vcpu) (struct xc_dom_image * dom);
    int (*bootearly) (struct xc_dom_image * dom);
    int (*bootlate) (struct xc_dom_image * dom);

    /* arch-specific memory initialization. */
    int (*meminit) (struct xc_dom_image * dom);

    char *guest_type;
    char *native_protocol;
    int page_shift;
    int sizeof_pfn;
    int p2m_base_supported;
    int arch_private_size;

    struct xc_dom_arch *next;
};
void xc_dom_register_arch_hooks(struct xc_dom_arch *hooks);

#define XC_DOM_PAGE_SHIFT(dom)  ((dom)->arch_hooks->page_shift)
#define XC_DOM_PAGE_SIZE(dom)   (1LL << (dom)->arch_hooks->page_shift)

/* --- main functions ---------------------------------------------- */

struct xc_dom_image *xc_dom_allocate(xc_interface *xch,
                                     const char *cmdline, const char *features);
void xc_dom_release_phys(struct xc_dom_image *dom);
void xc_dom_release(struct xc_dom_image *dom);
int xc_dom_rambase_init(struct xc_dom_image *dom, uint64_t rambase);
int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb);

/* Set this larger if you have enormous modules/kernels. Note that
 * you should trust all kernels not to be maliciously large (e.g. to
 * exhaust all dom0 memory) if you do this (see CVE-2012-4544 /
 * XSA-25). You can also set the default independently for
 * modules/kernels in xc_dom_allocate() or call
 * xc_dom_{kernel,module}_max_size.
 */
#ifndef XC_DOM_DECOMPRESS_MAX
#define XC_DOM_DECOMPRESS_MAX (1024*1024*1024) /* 1GB */
#endif

int xc_dom_kernel_check_size(struct xc_dom_image *dom, size_t sz);
int xc_dom_kernel_max_size(struct xc_dom_image *dom, size_t sz);

int xc_dom_module_max_size(struct xc_dom_image *dom, size_t sz);

int xc_dom_devicetree_max_size(struct xc_dom_image *dom, size_t sz);

size_t xc_dom_check_gzip(xc_interface *xch,
                     void *blob, size_t ziplen);
int xc_dom_do_gunzip(xc_interface *xch,
                     void *src, size_t srclen, void *dst, size_t dstlen);
int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size);

int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename);
int xc_dom_module_file(struct xc_dom_image *dom, const char *filename,
                       const char *cmdline);
int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem,
                      size_t memsize);
int xc_dom_module_mem(struct xc_dom_image *dom, const void *mem,
                       size_t memsize, const char *cmdline);
int xc_dom_devicetree_file(struct xc_dom_image *dom, const char *filename);
int xc_dom_devicetree_mem(struct xc_dom_image *dom, const void *mem,
                          size_t memsize);

int xc_dom_parse_image(struct xc_dom_image *dom);
int xc_dom_set_arch_hooks(struct xc_dom_image *dom);
int xc_dom_build_image(struct xc_dom_image *dom);

int xc_dom_boot_xen_init(struct xc_dom_image *dom, xc_interface *xch,
                         uint32_t domid);
int xc_dom_boot_mem_init(struct xc_dom_image *dom);
void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn,
                           xen_pfn_t count);
int xc_dom_boot_image(struct xc_dom_image *dom);
int xc_dom_compat_check(struct xc_dom_image *dom);
int xc_dom_gnttab_init(struct xc_dom_image *dom);
int xc_dom_gnttab_seed(xc_interface *xch, uint32_t guest_domid,
                       bool is_hvm,
                       xen_pfn_t console_gfn,
                       xen_pfn_t xenstore_gfn,
                       uint32_t console_domid,
                       uint32_t xenstore_domid);
bool xc_dom_translated(const struct xc_dom_image *dom);

/* --- debugging bits ---------------------------------------------- */

int xc_dom_loginit(xc_interface *xch);

void xc_dom_printf(xc_interface *xch, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
void xc_dom_panic_func(xc_interface *xch,
                      const char *file, int line, xc_error_code err,
                      const char *fmt, ...)
    __attribute__ ((format(printf, 5, 6)));

#define xc_dom_panic(xch, err, fmt, args...) \
    xc_dom_panic_func(xch, __FILE__, __LINE__, err, fmt, ## args)
#define xc_dom_trace(mark) \
    xc_dom_printf("%s:%d: trace %s\n", __FILE__, __LINE__, mark)

void xc_dom_log_memory_footprint(struct xc_dom_image *dom);

/* --- simple memory pool ------------------------------------------ */

void *xc_dom_malloc(struct xc_dom_image *dom, size_t size);
int xc_dom_register_external(struct xc_dom_image *dom, void *ptr, size_t size);
void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size);
void *xc_dom_malloc_filemap(struct xc_dom_image *dom,
                            const char *filename, size_t * size,
                            const size_t max_size);
char *xc_dom_strdup(struct xc_dom_image *dom, const char *str);

/* --- alloc memory pool ------------------------------------------- */

xen_pfn_t xc_dom_alloc_page(struct xc_dom_image *dom, char *name);
int xc_dom_alloc_segment(struct xc_dom_image *dom,
                         struct xc_dom_seg *seg, char *name,
                         xen_vaddr_t start, xen_vaddr_t size);

/* --- misc bits --------------------------------------------------- */

void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t first,
                        xen_pfn_t count);
void *xc_dom_pfn_to_ptr_retcount(struct xc_dom_image *dom, xen_pfn_t first,
                                 xen_pfn_t count, xen_pfn_t *count_out);
void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn);
void xc_dom_unmap_all(struct xc_dom_image *dom);
void *xc_dom_vaddr_to_ptr(struct xc_dom_image *dom,
                          xen_vaddr_t vaddr, size_t *safe_region_out);
uint64_t xc_dom_virt_base(struct xc_dom_image *dom);
uint64_t xc_dom_virt_entry(struct xc_dom_image *dom);
uint64_t xc_dom_virt_hypercall(struct xc_dom_image *dom);
char *xc_dom_guest_os(struct xc_dom_image *dom);
bool xc_dom_feature_get(struct xc_dom_image *dom, unsigned int nr);

static inline void *xc_dom_seg_to_ptr_pages(struct xc_dom_image *dom,
                                      struct xc_dom_seg *seg,
                                      xen_pfn_t *pages_out)
{
    void *retval;

    retval = xc_dom_pfn_to_ptr(dom, seg->pfn, seg->pages);

    *pages_out = retval ? seg->pages : 0;
    return retval;
}

static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom,
                                      struct xc_dom_seg *seg)
{
    xen_pfn_t dummy;

    return xc_dom_seg_to_ptr_pages(dom, seg, &dummy);
}

static inline xen_pfn_t xc_dom_p2m(struct xc_dom_image *dom, xen_pfn_t pfn)
{
    if ( xc_dom_translated(dom) )
        return pfn;

    /* x86 PV only now. */
    if ( pfn >= dom->total_pages )
        return INVALID_MFN;

    return dom->pv_p2m[pfn];
}

/*
 * User not using xc_suspend_* / xc_await_suspent may not want to
 * include the full libxenevtchn API here.
 */
struct xenevtchn_handle;

/* For save's precopy_policy(). */
struct precopy_stats
{
    unsigned int iteration;
    unsigned int total_written;
    long dirty_count; /* -1 if unknown */
};

/*
 * A precopy_policy callback may not be running in the same address
 * space as libxc an so precopy_stats is passed by value.
 */
typedef int (*precopy_policy_t)(struct precopy_stats, void *);

/* callbacks provided by xc_domain_save */
struct save_callbacks {
    /*
     * Called after expiration of checkpoint interval,
     * to suspend the guest.
     */
    int (*suspend)(void *data);

    /*
     * Called before and after every batch of page data sent during
     * the precopy phase of a live migration to ask the caller what
     * to do next based on the current state of the precopy migration.
     *
     * Should return one of the values listed below:
     */
#define XGS_POLICY_ABORT          (-1) /* Abandon the migration entirely
                                        * and tidy up. */
#define XGS_POLICY_CONTINUE_PRECOPY 0  /* Remain in the precopy phase. */
#define XGS_POLICY_STOP_AND_COPY    1  /* Immediately suspend and transmit the
                                        * remaining dirty pages. */
    precopy_policy_t precopy_policy;

    /*
     * Called after the guest's dirty pages have been
     *  copied into an output buffer.
     * Callback function resumes the guest & the device model,
     *  returns to xc_domain_save.
     * xc_domain_save then flushes the output buffer, while the
     *  guest continues to run.
     */
    int (*postcopy)(void *data);

    /*
     * Called after the memory checkpoint has been flushed
     * out into the network. Typical actions performed in this
     * callback include:
     *   (a) send the saved device model state (for HVM guests),
     *   (b) wait for checkpoint ack
     *   (c) release the network output buffer pertaining to the acked checkpoint.
     *   (c) sleep for the checkpoint interval.
     *
     * returns:
     * 0: terminate checkpointing gracefully
     * 1: take another checkpoint
     */
    int (*checkpoint)(void *data);

    /*
     * Called after the checkpoint callback.
     *
     * returns:
     * 0: terminate checkpointing gracefully
     * 1: take another checkpoint
     */
    int (*wait_checkpoint)(void *data);

    /* Enable qemu-dm logging dirty pages to xen */
    int (*switch_qemu_logdirty)(uint32_t domid, unsigned enable, void *data); /* HVM only */

    /* to be provided as the last argument to each callback function */
    void *data;
};

/* Type of stream.  Plain, or using a continuous replication protocol? */
typedef enum {
    XC_STREAM_PLAIN,
    XC_STREAM_REMUS,
    XC_STREAM_COLO,
} xc_stream_type_t;

/**
 * This function will save a running domain.
 *
 * @param xch a handle to an open hypervisor interface
 * @param io_fd the file descriptor to save a domain to
 * @param dom the id of the domain
 * @param flags XCFLAGS_xxx
 * @param stream_type XC_STREAM_PLAIN if the far end of the stream
 *        doesn't use checkpointing
 * @param recv_fd Only used for XC_STREAM_COLO.  Contains backchannel from
 *        the destination side.
 * @return 0 on success, -1 on failure
 */
int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom,
                   uint32_t flags, struct save_callbacks *callbacks,
                   xc_stream_type_t stream_type, int recv_fd);

/* callbacks provided by xc_domain_restore */
struct restore_callbacks {
    /*
     * Called once the STATIC_DATA_END record has been received/inferred.
     *
     * For compatibility with older streams, provides a list of static data
     * expected to be found in the stream, which was missing.  A higher level
     * toolstack is responsible for providing any necessary compatibiltiy.
     */
#define XGR_SDD_MISSING_CPUID (1 << 0)
#define XGR_SDD_MISSING_MSR   (1 << 1)
    int (*static_data_done)(unsigned int missing, void *data);

    /* Called after a new checkpoint to suspend the guest. */
    int (*suspend)(void *data);

    /*
     * Called after the secondary vm is ready to resume.
     * Callback function resumes the guest & the device model,
     * returns to xc_domain_restore.
     */
    int (*postcopy)(void *data);

    /*
     * A checkpoint record has been found in the stream.
     * returns:
     */
#define XGR_CHECKPOINT_ERROR    0 /* Terminate processing */
#define XGR_CHECKPOINT_SUCCESS  1 /* Continue reading more data from the stream */
#define XGR_CHECKPOINT_FAILOVER 2 /* Failover and resume VM */
    int (*checkpoint)(void *data);

    /*
     * Called after the checkpoint callback.
     *
     * returns:
     * 0: terminate checkpointing gracefully
     * 1: take another checkpoint
     */
    int (*wait_checkpoint)(void *data);

    /*
     * callback to send store gfn and console gfn to xl
     * if we want to resume vm before xc_domain_save()
     * exits.
     */
    void (*restore_results)(xen_pfn_t store_gfn, xen_pfn_t console_gfn,
                            void *data);

    /* to be provided as the last argument to each callback function */
    void *data;
};

/**
 * This function will restore a saved domain.
 *
 * Domain is restored in a suspended state ready to be unpaused.
 *
 * @param xch a handle to an open hypervisor interface
 * @param io_fd the file descriptor to restore a domain from
 * @param dom the id of the domain
 * @param store_evtchn the xenstore event channel for this domain to use
 * @param store_mfn filled with the gfn of the store page
 * @param store_domid the backend domain for xenstore
 * @param console_evtchn the console event channel for this domain to use
 * @param console_mfn filled with the gfn of the console page
 * @param console_domid the backend domain for xenconsole
 * @param stream_type XC_STREAM_PLAIN if the far end of the stream is using
 *        checkpointing
 * @param callbacks non-NULL to receive a callback to restore toolstack
 *        specific data
 * @param send_back_fd Only used for XC_STREAM_COLO.  Contains backchannel to
 *        the source side.
 * @return 0 on success, -1 on failure
 */
int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                      unsigned int store_evtchn, unsigned long *store_mfn,
                      uint32_t store_domid, unsigned int console_evtchn,
                      unsigned long *console_mfn, uint32_t console_domid,
                      xc_stream_type_t stream_type,
                      struct restore_callbacks *callbacks, int send_back_fd);

/**
 * This function will create a domain for a paravirtualized Linux
 * using file names pointing to kernel and ramdisk
 *
 * @parm xch a handle to an open hypervisor interface
 * @parm domid the id of the domain
 * @parm mem_mb memory size in megabytes
 * @parm image_name name of the kernel image file
 * @parm ramdisk_name name of the ramdisk image file
 * @parm cmdline command line string
 * @parm flags domain creation flags
 * @parm store_evtchn the store event channel for this domain to use
 * @parm store_mfn returned with the mfn of the store page
 * @parm console_evtchn the console event channel for this domain to use
 * @parm conole_mfn returned with the mfn of the console page
 * @return 0 on success, -1 on failure
 */
int xc_linux_build(xc_interface *xch,
                   uint32_t domid,
                   unsigned int mem_mb,
                   const char *image_name,
                   const char *ramdisk_name,
                   const char *cmdline,
                   const char *features,
                   unsigned long flags,
                   unsigned int store_evtchn,
                   unsigned long *store_mfn,
                   unsigned int console_evtchn,
                   unsigned long *console_mfn);

/*
 * Sets *lockfd to -1.
 * Has deallocated everything even on error.
 */
int xc_suspend_evtchn_release(xc_interface *xch,
                              struct xenevtchn_handle *xce,
                              uint32_t domid, int suspend_evtchn, int *lockfd);

/**
 * This function eats the initial notification.
 * xce must not be used for anything else
 * See xc_suspend_evtchn_init_sane re lockfd.
 */
int xc_suspend_evtchn_init_exclusive(xc_interface *xch,
                                     struct xenevtchn_handle *xce,
                                     uint32_t domid, int port, int *lockfd);

/* xce must not be used for anything else */
int xc_await_suspend(xc_interface *xch, struct xenevtchn_handle *xce,
                     int suspend_evtchn);

/**
 * The port will be signaled immediately after this call
 * The caller should check the domain status and look for the next event
 * On success, *lockfd will be set to >=0 and *lockfd must be preserved
 * and fed to xc_suspend_evtchn_release.  (On error *lockfd is
 * undefined and xc_suspend_evtchn_release is not allowed.)
 */
int xc_suspend_evtchn_init_sane(xc_interface *xch,
                                struct xenevtchn_handle *xce,
                                uint32_t domid, int port, int *lockfd);

int xc_mark_page_online(xc_interface *xch, unsigned long start,
                        unsigned long end, uint32_t *status);

int xc_mark_page_offline(xc_interface *xch, unsigned long start,
                          unsigned long end, uint32_t *status);

int xc_query_page_offline_status(xc_interface *xch, unsigned long start,
                                 unsigned long end, uint32_t *status);

int xc_exchange_page(xc_interface *xch, uint32_t domid, xen_pfn_t mfn);


/**
 * Memory related information, such as PFN types, the P2M table,
 * the guest word width and the guest page table levels.
 */
struct xc_domain_meminfo {
    unsigned int pt_levels;
    unsigned int guest_width;
    xen_pfn_t *pfn_type;
    xen_pfn_t *p2m_table;
    unsigned long p2m_size;
};

int xc_map_domain_meminfo(xc_interface *xch, uint32_t domid,
                          struct xc_domain_meminfo *minfo);

int xc_unmap_domain_meminfo(xc_interface *xch, struct xc_domain_meminfo *mem);

/**
 * This function map m2p table
 * @parm xch a handle to an open hypervisor interface
 * @parm max_mfn the max pfn
 * @parm prot the flags to map, such as read/write etc
 * @parm mfn0 return the first mfn, can be NULL
 * @return mapped m2p table on success, NULL on failure
 */
xen_pfn_t *xc_map_m2p(xc_interface *xch,
                      unsigned long max_mfn,
                      int prot,
                      unsigned long *mfn0);
#endif /* XENGUEST_H */