[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] tools/libxc: rename libxenguest internal headers
commit 256920d3a232c2e6631dbd505d036c0d3046d299 Author: Juergen Gross <jgross@xxxxxxxx> AuthorDate: Fri Aug 28 17:07:29 2020 +0200 Commit: Wei Liu <wl@xxxxxxx> CommitDate: Wed Sep 9 10:57:25 2020 +0000 tools/libxc: rename libxenguest internal headers Rename the header files private to libxenguest from xc_*.h to xg_*.h. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> Acked-by: Wei Liu <wl@xxxxxxx> --- tools/libxc/xc_dom_decompress.h | 8 - tools/libxc/xc_dom_decompress_unsafe.h | 20 -- tools/libxc/xc_sr_common.h | 468 --------------------------- tools/libxc/xc_sr_common_x86.h | 51 --- tools/libxc/xc_sr_common_x86_pv.h | 109 ------- tools/libxc/xc_sr_stream_format.h | 150 --------- tools/libxc/xg_dom_bzimageloader.c | 2 +- tools/libxc/xg_dom_decompress.h | 8 + tools/libxc/xg_dom_decompress_lz4.c | 2 +- tools/libxc/xg_dom_decompress_unsafe.c | 2 +- tools/libxc/xg_dom_decompress_unsafe.h | 20 ++ tools/libxc/xg_dom_decompress_unsafe_bzip2.c | 2 +- tools/libxc/xg_dom_decompress_unsafe_lzma.c | 2 +- tools/libxc/xg_dom_decompress_unsafe_lzo1x.c | 2 +- tools/libxc/xg_dom_decompress_unsafe_xz.c | 2 +- tools/libxc/xg_sr_common.c | 2 +- tools/libxc/xg_sr_common.h | 468 +++++++++++++++++++++++++++ tools/libxc/xg_sr_common_x86.c | 2 +- tools/libxc/xg_sr_common_x86.h | 51 +++ tools/libxc/xg_sr_common_x86_pv.c | 2 +- tools/libxc/xg_sr_common_x86_pv.h | 109 +++++++ tools/libxc/xg_sr_restore.c | 2 +- tools/libxc/xg_sr_restore_x86_hvm.c | 2 +- tools/libxc/xg_sr_restore_x86_pv.c | 2 +- tools/libxc/xg_sr_save.c | 2 +- tools/libxc/xg_sr_save_x86_hvm.c | 2 +- tools/libxc/xg_sr_save_x86_pv.c | 2 +- tools/libxc/xg_sr_stream_format.h | 150 +++++++++ 28 files changed, 822 insertions(+), 822 deletions(-) diff --git a/tools/libxc/xc_dom_decompress.h b/tools/libxc/xc_dom_decompress.h deleted file mode 100644 index 42cefa3f0e..0000000000 --- a/tools/libxc/xc_dom_decompress.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __MINIOS__ -# include "xc_dom.h" -#else -# include "xc_dom_decompress_unsafe.h" -#endif - -int xc_try_lz4_decode(struct xc_dom_image *dom, void **blob, size_t *size); - diff --git a/tools/libxc/xc_dom_decompress_unsafe.h b/tools/libxc/xc_dom_decompress_unsafe.h deleted file mode 100644 index 64f68864b1..0000000000 --- a/tools/libxc/xc_dom_decompress_unsafe.h +++ /dev/null @@ -1,20 +0,0 @@ -#include "xc_dom.h" - -typedef int decompress_fn(unsigned char *inbuf, unsigned int len, - int (*fill)(void*, unsigned int), - int (*flush)(void*, unsigned int), - unsigned char *outbuf, unsigned int *posp, - void (*error)(const char *x)); - -int xc_dom_decompress_unsafe( - decompress_fn fn, struct xc_dom_image *dom, void **blob, size_t *size) - __attribute__((visibility("internal"))); - -int xc_try_bzip2_decode(struct xc_dom_image *dom, void **blob, size_t *size) - __attribute__((visibility("internal"))); -int xc_try_lzma_decode(struct xc_dom_image *dom, void **blob, size_t *size) - __attribute__((visibility("internal"))); -int xc_try_lzo1x_decode(struct xc_dom_image *dom, void **blob, size_t *size) - __attribute__((visibility("internal"))); -int xc_try_xz_decode(struct xc_dom_image *dom, void **blob, size_t *size) - __attribute__((visibility("internal"))); diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h deleted file mode 100644 index f3bdea8006..0000000000 --- a/tools/libxc/xc_sr_common.h +++ /dev/null @@ -1,468 +0,0 @@ -#ifndef __COMMON__H -#define __COMMON__H - -#include <stdbool.h> - -#include "xg_private.h" -#include "xg_save_restore.h" -#include "xc_dom.h" -#include "xc_bitops.h" - -#include "xc_sr_stream_format.h" - -/* String representation of Domain Header types. */ -const char *dhdr_type_to_str(uint32_t type); - -/* String representation of Record types. */ -const char *rec_type_to_str(uint32_t type); - -struct xc_sr_context; -struct xc_sr_record; - -/** - * Save operations. To be implemented for each type of guest, for use by the - * common save algorithm. - * - * Every function must be implemented, even if only with a no-op stub. - */ -struct xc_sr_save_ops -{ - /* Convert a PFN to GFN. May return ~0UL for an invalid mapping. */ - xen_pfn_t (*pfn_to_gfn)(const struct xc_sr_context *ctx, xen_pfn_t pfn); - - /** - * Optionally transform the contents of a page from being specific to the - * sending environment, to being generic for the stream. - * - * The page of data at the end of 'page' may be a read-only mapping of a - * running guest; it must not be modified. If no transformation is - * required, the callee should leave '*pages' untouched. - * - * If a transformation is required, the callee should allocate themselves - * a local page using malloc() and return it via '*page'. - * - * The caller shall free() '*page' in all cases. In the case that the - * callee encounters an error, it should *NOT* free() the memory it - * allocated for '*page'. - * - * It is valid to fail with EAGAIN if the transformation is not able to be - * completed at this point. The page shall be retried later. - * - * @returns 0 for success, -1 for failure, with errno appropriately set. - */ - int (*normalise_page)(struct xc_sr_context *ctx, xen_pfn_t type, - void **page); - - /** - * Set up local environment to save a domain. (Typically querying - * running domain state, setting up mappings etc.) - * - * This is called once before any common setup has occurred, allowing for - * guest-specific adjustments to be made to common state. - */ - int (*setup)(struct xc_sr_context *ctx); - - /** - * Send static records at the head of the stream. This is called once, - * after the Image and Domain headers are written. - */ - int (*static_data)(struct xc_sr_context *ctx); - - /** - * Send dynamic records which need to be at the start of the stream. This - * is called after the STATIC_DATA_END record is written. - */ - int (*start_of_stream)(struct xc_sr_context *ctx); - - /** - * Send records which need to be at the start of a checkpoint. This is - * called once, or once per checkpoint in a checkpointed stream, and is - * ahead of memory data. - */ - int (*start_of_checkpoint)(struct xc_sr_context *ctx); - - /** - * Send records which need to be at the end of the checkpoint. This is - * called once, or once per checkpoint in a checkpointed stream, and is - * after the memory data. - */ - int (*end_of_checkpoint)(struct xc_sr_context *ctx); - - /** - * Check state of guest to decide whether it makes sense to continue - * migration. This is called in each iteration or checkpoint to check - * whether all criteria for the migration are still met. If that's not - * the case either migration is cancelled via a bad rc or the situation - * is handled, e.g. by sending appropriate records. - */ - int (*check_vm_state)(struct xc_sr_context *ctx); - - /** - * Clean up the local environment. Will be called exactly once, either - * after a successful save, or upon encountering an error. - */ - int (*cleanup)(struct xc_sr_context *ctx); -}; - - -/** - * Restore operations. To be implemented for each type of guest, for use by - * the common restore algorithm. - * - * Every function must be implemented, even if only with a no-op stub. - */ -struct xc_sr_restore_ops -{ - /* Convert a PFN to GFN. May return ~0UL for an invalid mapping. */ - xen_pfn_t (*pfn_to_gfn)(const struct xc_sr_context *ctx, xen_pfn_t pfn); - - /* Check to see whether a PFN is valid. */ - bool (*pfn_is_valid)(const struct xc_sr_context *ctx, xen_pfn_t pfn); - - /* Set the GFN of a PFN. */ - void (*set_gfn)(struct xc_sr_context *ctx, xen_pfn_t pfn, xen_pfn_t gfn); - - /* Set the type of a PFN. */ - void (*set_page_type)(struct xc_sr_context *ctx, xen_pfn_t pfn, - xen_pfn_t type); - - /** - * Optionally transform the contents of a page from being generic in the - * stream, to being specific to the restoring environment. - * - * 'page' is expected to be modified in-place if a transformation is - * required. - * - * @returns 0 for success, -1 for failure, with errno appropriately set. - */ - int (*localise_page)(struct xc_sr_context *ctx, uint32_t type, void *page); - - /** - * Set up local environment to restore a domain. - * - * This is called once before any common setup has occurred, allowing for - * guest-specific adjustments to be made to common state. - */ - int (*setup)(struct xc_sr_context *ctx); - - /** - * Process an individual record from the stream. The caller shall take - * care of processing common records (e.g. END, PAGE_DATA). - * - * @return 0 for success, -1 for failure, or the following sentinels: - * - RECORD_NOT_PROCESSED - * - BROKEN_CHANNEL: under Remus/COLO, this means master may be dead, and - * a failover is needed. - */ -#define RECORD_NOT_PROCESSED 1 -#define BROKEN_CHANNEL 2 - int (*process_record)(struct xc_sr_context *ctx, struct xc_sr_record *rec); - - /** - * Perform any actions required after the static data has arrived. Called - * when the STATIC_DATA_COMPLETE record has been recieved/inferred. - * 'missing' should be filled in for any data item the higher level - * toolstack needs to provide compatiblity for. - */ - int (*static_data_complete)(struct xc_sr_context *ctx, - unsigned int *missing); - - /** - * Perform any actions required after the stream has been finished. Called - * after the END record has been received. - */ - int (*stream_complete)(struct xc_sr_context *ctx); - - /** - * Clean up the local environment. Will be called exactly once, either - * after a successful restore, or upon encountering an error. - */ - int (*cleanup)(struct xc_sr_context *ctx); -}; - -/* Wrapper for blobs of data heading Xen-wards. */ -struct xc_sr_blob -{ - void *ptr; - size_t size; -}; - -/* - * Update a blob. Duplicate src/size, freeing the old blob if necessary. May - * fail due to memory allocation. - */ -static inline int update_blob(struct xc_sr_blob *blob, - const void *src, size_t size) -{ - void *ptr; - - if ( !src || !size ) - { - errno = EINVAL; - return -1; - } - - if ( (ptr = malloc(size)) == NULL ) - return -1; - - free(blob->ptr); - blob->ptr = memcpy(ptr, src, size); - blob->size = size; - - return 0; -} - -struct xc_sr_context -{ - xc_interface *xch; - uint32_t domid; - int fd; - - /* Plain VM, or checkpoints over time. */ - xc_stream_type_t stream_type; - - xc_dominfo_t dominfo; - - union /* Common save or restore data. */ - { - struct /* Save data. */ - { - int recv_fd; - - struct xc_sr_save_ops ops; - struct save_callbacks *callbacks; - - /* Live migrate vs non live suspend. */ - bool live; - - /* Further debugging information in the stream. */ - bool debug; - - unsigned long p2m_size; - - struct precopy_stats stats; - - xen_pfn_t *batch_pfns; - unsigned int nr_batch_pfns; - unsigned long *deferred_pages; - unsigned long nr_deferred_pages; - xc_hypercall_buffer_t dirty_bitmap_hbuf; - } save; - - struct /* Restore data. */ - { - struct xc_sr_restore_ops ops; - struct restore_callbacks *callbacks; - - int send_back_fd; - unsigned long p2m_size; - xc_hypercall_buffer_t dirty_bitmap_hbuf; - - /* From Image Header. */ - uint32_t format_version; - - /* From Domain Header. */ - uint32_t guest_type; - uint32_t guest_page_size; - - /* Currently buffering records between a checkpoint */ - bool buffer_all_records; - - /* Whether a STATIC_DATA_END record has been seen/inferred. */ - bool seen_static_data_end; - -/* - * With Remus/COLO, we buffer the records sent by the primary at checkpoint, - * in case the primary will fail, we can recover from the last - * checkpoint state. - * This should be enough for most of the cases because primary only send - * dirty pages at checkpoint. - */ -#define DEFAULT_BUF_RECORDS 1024 - struct xc_sr_record *buffered_records; - unsigned int allocated_rec_num; - unsigned int buffered_rec_num; - - /* - * Xenstore and Console parameters. - * INPUT: evtchn & domid - * OUTPUT: gfn - */ - xen_pfn_t xenstore_gfn, console_gfn; - unsigned int xenstore_evtchn, console_evtchn; - uint32_t xenstore_domid, console_domid; - - /* Bitmap of currently populated PFNs during restore. */ - unsigned long *populated_pfns; - xen_pfn_t max_populated_pfn; - - /* Sender has invoked verify mode on the stream. */ - bool verify; - } restore; - }; - - union /* Guest-arch specific data. */ - { - struct /* x86 */ - { - /* Common save/restore data. */ - union - { - struct - { - /* X86_{CPUID,MSR}_DATA blobs for CPU Policy. */ - struct xc_sr_blob cpuid, msr; - } restore; - }; - - struct /* x86 PV guest. */ - { - /* 4 or 8; 32 or 64 bit domain */ - unsigned int width; - /* 3 or 4 pagetable levels */ - unsigned int levels; - - /* Maximum Xen frame */ - xen_pfn_t max_mfn; - /* Read-only machine to phys map */ - xen_pfn_t *m2p; - /* first mfn of the compat m2p (Only needed for 32bit PV guests) */ - xen_pfn_t compat_m2p_mfn0; - /* Number of m2p frames mapped */ - unsigned long nr_m2p_frames; - - /* Maximum guest frame */ - xen_pfn_t max_pfn; - - /* Number of frames making up the p2m */ - unsigned int p2m_frames; - /* Guest's phys to machine map. Mapped read-only (save) or - * allocated locally (restore). Uses guest unsigned longs. */ - void *p2m; - /* The guest pfns containing the p2m leaves */ - xen_pfn_t *p2m_pfns; - - /* Read-only mapping of guests shared info page */ - shared_info_any_t *shinfo; - - /* p2m generation count for verifying validity of local p2m. */ - uint64_t p2m_generation; - - union - { - struct - { - /* State machine for the order of received records. */ - bool seen_pv_info; - - /* Types for each page (bounded by max_pfn). */ - uint32_t *pfn_types; - - /* x86 PV per-vcpu storage structure for blobs. */ - struct xc_sr_x86_pv_restore_vcpu - { - struct xc_sr_blob basic, extd, xsave, msr; - } *vcpus; - unsigned int nr_vcpus; - } restore; - }; - } pv; - - struct /* x86 HVM guest. */ - { - union - { - struct - { - /* Whether qemu enabled logdirty mode, and we should - * disable on cleanup. */ - bool qemu_enabled_logdirty; - } save; - - struct - { - /* HVM context blob. */ - struct xc_sr_blob context; - } restore; - }; - } hvm; - - } x86; - }; -}; - -extern struct xc_sr_save_ops save_ops_x86_pv; -extern struct xc_sr_save_ops save_ops_x86_hvm; - -extern struct xc_sr_restore_ops restore_ops_x86_pv; -extern struct xc_sr_restore_ops restore_ops_x86_hvm; - -struct xc_sr_record -{ - uint32_t type; - uint32_t length; - void *data; -}; - -/* - * Writes a split record to the stream, applying correct padding where - * appropriate. It is common when sending records containing blobs from Xen - * that the header and blob data are separate. This function accepts a second - * buffer and length, and will merge it with the main record when sending. - * - * Records with a non-zero length must provide a valid data field; records - * with a 0 length shall have their data field ignored. - * - * Returns 0 on success and non0 on failure. - */ -int write_split_record(struct xc_sr_context *ctx, struct xc_sr_record *rec, - void *buf, size_t sz); - -/* - * Writes a record to the stream, applying correct padding where appropriate. - * Records with a non-zero length must provide a valid data field; records - * with a 0 length shall have their data field ignored. - * - * Returns 0 on success and non0 on failure. - */ -static inline int write_record(struct xc_sr_context *ctx, - struct xc_sr_record *rec) -{ - return write_split_record(ctx, rec, NULL, 0); -} - -/* - * Reads a record from the stream, and fills in the record structure. - * - * Returns 0 on success and non-0 on failure. - * - * On success, the records type and size shall be valid. - * - If size is 0, data shall be NULL. - * - If size is non-0, data shall be a buffer allocated by malloc() which must - * be passed to free() by the caller. - * - * On failure, the contents of the record structure are undefined. - */ -int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec); - -/* - * This would ideally be private in restore.c, but is needed by - * x86_pv_localise_page() if we receive pagetables frames ahead of the - * contents of the frames they point at. - */ -int populate_pfns(struct xc_sr_context *ctx, unsigned int count, - const xen_pfn_t *original_pfns, const uint32_t *types); - -/* Handle a STATIC_DATA_END record. */ -int handle_static_data_end(struct xc_sr_context *ctx); - -#endif -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xc_sr_common_x86.h b/tools/libxc/xc_sr_common_x86.h deleted file mode 100644 index e08d81e0e7..0000000000 --- a/tools/libxc/xc_sr_common_x86.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __COMMON_X86__H -#define __COMMON_X86__H - -#include "xc_sr_common.h" - -/* - * Obtains a domains TSC information from Xen and writes a X86_TSC_INFO record - * into the stream. - */ -int write_x86_tsc_info(struct xc_sr_context *ctx); - -/* - * Parses a X86_TSC_INFO record and applies the result to the domain. - */ -int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec); - -/* - * Obtains a domains CPU Policy from Xen, and writes X86_{CPUID,MSR}_POLICY - * records into the stream. - */ -int write_x86_cpu_policy_records(struct xc_sr_context *ctx); - -/* - * Parses an X86_CPUID_POLICY record and stashes the content for application - * when a STATIC_DATA_END record is encountered. - */ -int handle_x86_cpuid_policy(struct xc_sr_context *ctx, - struct xc_sr_record *rec); - -/* - * Parses an X86_MSR_POLICY record and stashes the content for application - * when a STATIC_DATA_END record is encountered. - */ -int handle_x86_msr_policy(struct xc_sr_context *ctx, - struct xc_sr_record *rec); - -/* - * Perform common x86 actions required after the static data has arrived. - */ -int x86_static_data_complete(struct xc_sr_context *ctx, unsigned int *missing); - -#endif -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xc_sr_common_x86_pv.h b/tools/libxc/xc_sr_common_x86_pv.h deleted file mode 100644 index 2ed03309af..0000000000 --- a/tools/libxc/xc_sr_common_x86_pv.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef __COMMON_X86_PV_H -#define __COMMON_X86_PV_H - -#include "xc_sr_common_x86.h" - -/* Virtual address ranges reserved for hypervisor. */ -#define HYPERVISOR_VIRT_START_X86_64 0xFFFF800000000000ULL -#define HYPERVISOR_VIRT_END_X86_64 0xFFFF87FFFFFFFFFFULL - -#define HYPERVISOR_VIRT_START_X86_32 0x00000000F5800000ULL -#define HYPERVISOR_VIRT_END_X86_32 0x00000000FFFFFFFFULL - -/* - * Convert an mfn to a pfn, given Xen's m2p table. - * - * Caller must ensure that the requested mfn is in range. - */ -xen_pfn_t mfn_to_pfn(struct xc_sr_context *ctx, xen_pfn_t mfn); - -/* - * Query whether a particular mfn is valid in the physmap of a guest. - */ -bool mfn_in_pseudophysmap(struct xc_sr_context *ctx, xen_pfn_t mfn); - -/* - * Debug a particular mfn by walking the p2m and m2p. - */ -void dump_bad_pseudophysmap_entry(struct xc_sr_context *ctx, xen_pfn_t mfn); - -/* - * Convert a PV cr3 field to an mfn. - * - * Adjusts for Xen's extended-cr3 format to pack a 44bit physical address into - * a 32bit architectural cr3. - */ -xen_pfn_t cr3_to_mfn(struct xc_sr_context *ctx, uint64_t cr3); - -/* - * Convert an mfn to a PV cr3 field. - * - * Adjusts for Xen's extended-cr3 format to pack a 44bit physical address into - * a 32bit architectural cr3. - */ -uint64_t mfn_to_cr3(struct xc_sr_context *ctx, xen_pfn_t mfn); - -/* Bits 12 through 51 of a PTE point at the frame */ -#define PTE_FRAME_MASK 0x000ffffffffff000ULL - -/* - * Extract an mfn from a Pagetable Entry. May return INVALID_MFN if the pte - * would overflow a 32bit xen_pfn_t. - */ -static inline xen_pfn_t pte_to_frame(uint64_t pte) -{ - uint64_t frame = (pte & PTE_FRAME_MASK) >> PAGE_SHIFT; - -#ifdef __i386__ - if ( frame >= INVALID_MFN ) - return INVALID_MFN; -#endif - - return frame; -} - -/* - * Change the frame in a Pagetable Entry while leaving the flags alone. - */ -static inline uint64_t merge_pte(uint64_t pte, xen_pfn_t mfn) -{ - return (pte & ~PTE_FRAME_MASK) | ((uint64_t)mfn << PAGE_SHIFT); -} - -/* - * Get current domain information. - * - * Fills ctx->x86.pv - * - .width - * - .levels - * - .fpp - * - .p2m_frames - * - * Used by the save side to create the X86_PV_INFO record, and by the restore - * side to verify the incoming stream. - * - * Returns 0 on success and non-zero on error. - */ -int x86_pv_domain_info(struct xc_sr_context *ctx); - -/* - * Maps the Xen M2P. - * - * Fills ctx->x86.pv. - * - .max_mfn - * - .m2p - * - * Returns 0 on success and non-zero on error. - */ -int x86_pv_map_m2p(struct xc_sr_context *ctx); - -#endif -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xc_sr_stream_format.h b/tools/libxc/xc_sr_stream_format.h deleted file mode 100644 index 8a0da26f75..0000000000 --- a/tools/libxc/xc_sr_stream_format.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef __STREAM_FORMAT__H -#define __STREAM_FORMAT__H - -/* - * C structures for the Migration v2 stream format. - * See docs/specs/libxc-migration-stream.pandoc - */ - -#include <inttypes.h> - -/* - * Image Header - */ -struct xc_sr_ihdr -{ - uint64_t marker; - uint32_t id; - uint32_t version; - uint16_t options; - uint16_t _res1; - uint32_t _res2; -}; - -#define IHDR_MARKER 0xffffffffffffffffULL -#define IHDR_ID 0x58454E46U - -#define _IHDR_OPT_ENDIAN 0 -#define IHDR_OPT_LITTLE_ENDIAN (0 << _IHDR_OPT_ENDIAN) -#define IHDR_OPT_BIG_ENDIAN (1 << _IHDR_OPT_ENDIAN) - -/* - * Domain Header - */ -struct xc_sr_dhdr -{ - uint32_t type; - uint16_t page_shift; - uint16_t _res1; - uint32_t xen_major; - uint32_t xen_minor; -}; - -#define DHDR_TYPE_X86_PV 0x00000001U -#define DHDR_TYPE_X86_HVM 0x00000002U - -/* - * Record Header - */ -struct xc_sr_rhdr -{ - uint32_t type; - uint32_t length; -}; - -/* All records must be aligned up to an 8 octet boundary */ -#define REC_ALIGN_ORDER (3U) -/* Somewhat arbitrary - 128MB */ -#define REC_LENGTH_MAX (128U << 20) - -#define REC_TYPE_END 0x00000000U -#define REC_TYPE_PAGE_DATA 0x00000001U -#define REC_TYPE_X86_PV_INFO 0x00000002U -#define REC_TYPE_X86_PV_P2M_FRAMES 0x00000003U -#define REC_TYPE_X86_PV_VCPU_BASIC 0x00000004U -#define REC_TYPE_X86_PV_VCPU_EXTENDED 0x00000005U -#define REC_TYPE_X86_PV_VCPU_XSAVE 0x00000006U -#define REC_TYPE_SHARED_INFO 0x00000007U -#define REC_TYPE_X86_TSC_INFO 0x00000008U -#define REC_TYPE_HVM_CONTEXT 0x00000009U -#define REC_TYPE_HVM_PARAMS 0x0000000aU -#define REC_TYPE_TOOLSTACK 0x0000000bU -#define REC_TYPE_X86_PV_VCPU_MSRS 0x0000000cU -#define REC_TYPE_VERIFY 0x0000000dU -#define REC_TYPE_CHECKPOINT 0x0000000eU -#define REC_TYPE_CHECKPOINT_DIRTY_PFN_LIST 0x0000000fU -#define REC_TYPE_STATIC_DATA_END 0x00000010U -#define REC_TYPE_X86_CPUID_POLICY 0x00000011U -#define REC_TYPE_X86_MSR_POLICY 0x00000012U - -#define REC_TYPE_OPTIONAL 0x80000000U - -/* PAGE_DATA */ -struct xc_sr_rec_page_data_header -{ - uint32_t count; - uint32_t _res1; - uint64_t pfn[0]; -}; - -#define PAGE_DATA_PFN_MASK 0x000fffffffffffffULL -#define PAGE_DATA_TYPE_MASK 0xf000000000000000ULL - -/* X86_PV_INFO */ -struct xc_sr_rec_x86_pv_info -{ - uint8_t guest_width; - uint8_t pt_levels; - uint8_t _res[6]; -}; - -/* X86_PV_P2M_FRAMES */ -struct xc_sr_rec_x86_pv_p2m_frames -{ - uint32_t start_pfn; - uint32_t end_pfn; - uint64_t p2m_pfns[0]; -}; - -/* X86_PV_VCPU_{BASIC,EXTENDED,XSAVE,MSRS} */ -struct xc_sr_rec_x86_pv_vcpu_hdr -{ - uint32_t vcpu_id; - uint32_t _res1; - uint8_t context[0]; -}; - -/* X86_TSC_INFO */ -struct xc_sr_rec_x86_tsc_info -{ - uint32_t mode; - uint32_t khz; - uint64_t nsec; - uint32_t incarnation; - uint32_t _res1; -}; - -/* HVM_PARAMS */ -struct xc_sr_rec_hvm_params_entry -{ - uint64_t index; - uint64_t value; -}; - -struct xc_sr_rec_hvm_params -{ - uint32_t count; - uint32_t _res1; - struct xc_sr_rec_hvm_params_entry param[0]; -}; - -#endif -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xg_dom_bzimageloader.c b/tools/libxc/xg_dom_bzimageloader.c index a7d70cc7c6..f959a77602 100644 --- a/tools/libxc/xg_dom_bzimageloader.c +++ b/tools/libxc/xg_dom_bzimageloader.c @@ -32,7 +32,7 @@ #include <inttypes.h> #include "xg_private.h" -#include "xc_dom_decompress.h" +#include "xg_dom_decompress.h" #include <xen-tools/libs.h> diff --git a/tools/libxc/xg_dom_decompress.h b/tools/libxc/xg_dom_decompress.h new file mode 100644 index 0000000000..d9a21cf297 --- /dev/null +++ b/tools/libxc/xg_dom_decompress.h @@ -0,0 +1,8 @@ +#ifndef __MINIOS__ +# include "xc_dom.h" +#else +# include "xg_dom_decompress_unsafe.h" +#endif + +int xc_try_lz4_decode(struct xc_dom_image *dom, void **blob, size_t *size); + diff --git a/tools/libxc/xg_dom_decompress_lz4.c b/tools/libxc/xg_dom_decompress_lz4.c index b6a33f27a8..97ba620d86 100644 --- a/tools/libxc/xg_dom_decompress_lz4.c +++ b/tools/libxc/xg_dom_decompress_lz4.c @@ -4,7 +4,7 @@ #include <stdint.h> #include "xg_private.h" -#include "xc_dom_decompress.h" +#include "xg_dom_decompress.h" #define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS diff --git a/tools/libxc/xg_dom_decompress_unsafe.c b/tools/libxc/xg_dom_decompress_unsafe.c index 164e35558f..21d964787d 100644 --- a/tools/libxc/xg_dom_decompress_unsafe.c +++ b/tools/libxc/xg_dom_decompress_unsafe.c @@ -3,7 +3,7 @@ #include <inttypes.h> #include "xg_private.h" -#include "xc_dom_decompress_unsafe.h" +#include "xg_dom_decompress_unsafe.h" static struct xc_dom_image *unsafe_dom; static unsigned char *output_blob; diff --git a/tools/libxc/xg_dom_decompress_unsafe.h b/tools/libxc/xg_dom_decompress_unsafe.h new file mode 100644 index 0000000000..64f68864b1 --- /dev/null +++ b/tools/libxc/xg_dom_decompress_unsafe.h @@ -0,0 +1,20 @@ +#include "xc_dom.h" + +typedef int decompress_fn(unsigned char *inbuf, unsigned int len, + int (*fill)(void*, unsigned int), + int (*flush)(void*, unsigned int), + unsigned char *outbuf, unsigned int *posp, + void (*error)(const char *x)); + +int xc_dom_decompress_unsafe( + decompress_fn fn, struct xc_dom_image *dom, void **blob, size_t *size) + __attribute__((visibility("internal"))); + +int xc_try_bzip2_decode(struct xc_dom_image *dom, void **blob, size_t *size) + __attribute__((visibility("internal"))); +int xc_try_lzma_decode(struct xc_dom_image *dom, void **blob, size_t *size) + __attribute__((visibility("internal"))); +int xc_try_lzo1x_decode(struct xc_dom_image *dom, void **blob, size_t *size) + __attribute__((visibility("internal"))); +int xc_try_xz_decode(struct xc_dom_image *dom, void **blob, size_t *size) + __attribute__((visibility("internal"))); diff --git a/tools/libxc/xg_dom_decompress_unsafe_bzip2.c b/tools/libxc/xg_dom_decompress_unsafe_bzip2.c index 4dcabe4061..9d3709e6cc 100644 --- a/tools/libxc/xg_dom_decompress_unsafe_bzip2.c +++ b/tools/libxc/xg_dom_decompress_unsafe_bzip2.c @@ -3,7 +3,7 @@ #include <inttypes.h> #include "xg_private.h" -#include "xc_dom_decompress_unsafe.h" +#include "xg_dom_decompress_unsafe.h" #include "../../xen/common/bunzip2.c" diff --git a/tools/libxc/xg_dom_decompress_unsafe_lzma.c b/tools/libxc/xg_dom_decompress_unsafe_lzma.c index 4ee8cdbab1..5d178f0c43 100644 --- a/tools/libxc/xg_dom_decompress_unsafe_lzma.c +++ b/tools/libxc/xg_dom_decompress_unsafe_lzma.c @@ -3,7 +3,7 @@ #include <inttypes.h> #include "xg_private.h" -#include "xc_dom_decompress_unsafe.h" +#include "xg_dom_decompress_unsafe.h" #include "../../xen/common/unlzma.c" diff --git a/tools/libxc/xg_dom_decompress_unsafe_lzo1x.c b/tools/libxc/xg_dom_decompress_unsafe_lzo1x.c index 59888b9da2..a4f8ebd42d 100644 --- a/tools/libxc/xg_dom_decompress_unsafe_lzo1x.c +++ b/tools/libxc/xg_dom_decompress_unsafe_lzo1x.c @@ -5,7 +5,7 @@ #include <stdint.h> #include "xg_private.h" -#include "xc_dom_decompress_unsafe.h" +#include "xg_dom_decompress_unsafe.h" typedef uint8_t u8; typedef uint32_t u32; diff --git a/tools/libxc/xg_dom_decompress_unsafe_xz.c b/tools/libxc/xg_dom_decompress_unsafe_xz.c index fe7a7f49b4..ff6824b38d 100644 --- a/tools/libxc/xg_dom_decompress_unsafe_xz.c +++ b/tools/libxc/xg_dom_decompress_unsafe_xz.c @@ -6,7 +6,7 @@ #include <inttypes.h> #include "xg_private.h" -#include "xc_dom_decompress_unsafe.h" +#include "xg_dom_decompress_unsafe.h" // TODO #define XZ_DEC_X86 diff --git a/tools/libxc/xg_sr_common.c b/tools/libxc/xg_sr_common.c index 7c54b03414..17567ab133 100644 --- a/tools/libxc/xg_sr_common.c +++ b/tools/libxc/xg_sr_common.c @@ -1,6 +1,6 @@ #include <assert.h> -#include "xc_sr_common.h" +#include "xg_sr_common.h" #include <xen-tools/libs.h> diff --git a/tools/libxc/xg_sr_common.h b/tools/libxc/xg_sr_common.h new file mode 100644 index 0000000000..35f23fabb5 --- /dev/null +++ b/tools/libxc/xg_sr_common.h @@ -0,0 +1,468 @@ +#ifndef __COMMON__H +#define __COMMON__H + +#include <stdbool.h> + +#include "xg_private.h" +#include "xg_save_restore.h" +#include "xc_dom.h" +#include "xc_bitops.h" + +#include "xg_sr_stream_format.h" + +/* String representation of Domain Header types. */ +const char *dhdr_type_to_str(uint32_t type); + +/* String representation of Record types. */ +const char *rec_type_to_str(uint32_t type); + +struct xc_sr_context; +struct xc_sr_record; + +/** + * Save operations. To be implemented for each type of guest, for use by the + * common save algorithm. + * + * Every function must be implemented, even if only with a no-op stub. + */ +struct xc_sr_save_ops +{ + /* Convert a PFN to GFN. May return ~0UL for an invalid mapping. */ + xen_pfn_t (*pfn_to_gfn)(const struct xc_sr_context *ctx, xen_pfn_t pfn); + + /** + * Optionally transform the contents of a page from being specific to the + * sending environment, to being generic for the stream. + * + * The page of data at the end of 'page' may be a read-only mapping of a + * running guest; it must not be modified. If no transformation is + * required, the callee should leave '*pages' untouched. + * + * If a transformation is required, the callee should allocate themselves + * a local page using malloc() and return it via '*page'. + * + * The caller shall free() '*page' in all cases. In the case that the + * callee encounters an error, it should *NOT* free() the memory it + * allocated for '*page'. + * + * It is valid to fail with EAGAIN if the transformation is not able to be + * completed at this point. The page shall be retried later. + * + * @returns 0 for success, -1 for failure, with errno appropriately set. + */ + int (*normalise_page)(struct xc_sr_context *ctx, xen_pfn_t type, + void **page); + + /** + * Set up local environment to save a domain. (Typically querying + * running domain state, setting up mappings etc.) + * + * This is called once before any common setup has occurred, allowing for + * guest-specific adjustments to be made to common state. + */ + int (*setup)(struct xc_sr_context *ctx); + + /** + * Send static records at the head of the stream. This is called once, + * after the Image and Domain headers are written. + */ + int (*static_data)(struct xc_sr_context *ctx); + + /** + * Send dynamic records which need to be at the start of the stream. This + * is called after the STATIC_DATA_END record is written. + */ + int (*start_of_stream)(struct xc_sr_context *ctx); + + /** + * Send records which need to be at the start of a checkpoint. This is + * called once, or once per checkpoint in a checkpointed stream, and is + * ahead of memory data. + */ + int (*start_of_checkpoint)(struct xc_sr_context *ctx); + + /** + * Send records which need to be at the end of the checkpoint. This is + * called once, or once per checkpoint in a checkpointed stream, and is + * after the memory data. + */ + int (*end_of_checkpoint)(struct xc_sr_context *ctx); + + /** + * Check state of guest to decide whether it makes sense to continue + * migration. This is called in each iteration or checkpoint to check + * whether all criteria for the migration are still met. If that's not + * the case either migration is cancelled via a bad rc or the situation + * is handled, e.g. by sending appropriate records. + */ + int (*check_vm_state)(struct xc_sr_context *ctx); + + /** + * Clean up the local environment. Will be called exactly once, either + * after a successful save, or upon encountering an error. + */ + int (*cleanup)(struct xc_sr_context *ctx); +}; + + +/** + * Restore operations. To be implemented for each type of guest, for use by + * the common restore algorithm. + * + * Every function must be implemented, even if only with a no-op stub. + */ +struct xc_sr_restore_ops +{ + /* Convert a PFN to GFN. May return ~0UL for an invalid mapping. */ + xen_pfn_t (*pfn_to_gfn)(const struct xc_sr_context *ctx, xen_pfn_t pfn); + + /* Check to see whether a PFN is valid. */ + bool (*pfn_is_valid)(const struct xc_sr_context *ctx, xen_pfn_t pfn); + + /* Set the GFN of a PFN. */ + void (*set_gfn)(struct xc_sr_context *ctx, xen_pfn_t pfn, xen_pfn_t gfn); + + /* Set the type of a PFN. */ + void (*set_page_type)(struct xc_sr_context *ctx, xen_pfn_t pfn, + xen_pfn_t type); + + /** + * Optionally transform the contents of a page from being generic in the + * stream, to being specific to the restoring environment. + * + * 'page' is expected to be modified in-place if a transformation is + * required. + * + * @returns 0 for success, -1 for failure, with errno appropriately set. + */ + int (*localise_page)(struct xc_sr_context *ctx, uint32_t type, void *page); + + /** + * Set up local environment to restore a domain. + * + * This is called once before any common setup has occurred, allowing for + * guest-specific adjustments to be made to common state. + */ + int (*setup)(struct xc_sr_context *ctx); + + /** + * Process an individual record from the stream. The caller shall take + * care of processing common records (e.g. END, PAGE_DATA). + * + * @return 0 for success, -1 for failure, or the following sentinels: + * - RECORD_NOT_PROCESSED + * - BROKEN_CHANNEL: under Remus/COLO, this means master may be dead, and + * a failover is needed. + */ +#define RECORD_NOT_PROCESSED 1 +#define BROKEN_CHANNEL 2 + int (*process_record)(struct xc_sr_context *ctx, struct xc_sr_record *rec); + + /** + * Perform any actions required after the static data has arrived. Called + * when the STATIC_DATA_COMPLETE record has been recieved/inferred. + * 'missing' should be filled in for any data item the higher level + * toolstack needs to provide compatiblity for. + */ + int (*static_data_complete)(struct xc_sr_context *ctx, + unsigned int *missing); + + /** + * Perform any actions required after the stream has been finished. Called + * after the END record has been received. + */ + int (*stream_complete)(struct xc_sr_context *ctx); + + /** + * Clean up the local environment. Will be called exactly once, either + * after a successful restore, or upon encountering an error. + */ + int (*cleanup)(struct xc_sr_context *ctx); +}; + +/* Wrapper for blobs of data heading Xen-wards. */ +struct xc_sr_blob +{ + void *ptr; + size_t size; +}; + +/* + * Update a blob. Duplicate src/size, freeing the old blob if necessary. May + * fail due to memory allocation. + */ +static inline int update_blob(struct xc_sr_blob *blob, + const void *src, size_t size) +{ + void *ptr; + + if ( !src || !size ) + { + errno = EINVAL; + return -1; + } + + if ( (ptr = malloc(size)) == NULL ) + return -1; + + free(blob->ptr); + blob->ptr = memcpy(ptr, src, size); + blob->size = size; + + return 0; +} + +struct xc_sr_context +{ + xc_interface *xch; + uint32_t domid; + int fd; + + /* Plain VM, or checkpoints over time. */ + xc_stream_type_t stream_type; + + xc_dominfo_t dominfo; + + union /* Common save or restore data. */ + { + struct /* Save data. */ + { + int recv_fd; + + struct xc_sr_save_ops ops; + struct save_callbacks *callbacks; + + /* Live migrate vs non live suspend. */ + bool live; + + /* Further debugging information in the stream. */ + bool debug; + + unsigned long p2m_size; + + struct precopy_stats stats; + + xen_pfn_t *batch_pfns; + unsigned int nr_batch_pfns; + unsigned long *deferred_pages; + unsigned long nr_deferred_pages; + xc_hypercall_buffer_t dirty_bitmap_hbuf; + } save; + + struct /* Restore data. */ + { + struct xc_sr_restore_ops ops; + struct restore_callbacks *callbacks; + + int send_back_fd; + unsigned long p2m_size; + xc_hypercall_buffer_t dirty_bitmap_hbuf; + + /* From Image Header. */ + uint32_t format_version; + + /* From Domain Header. */ + uint32_t guest_type; + uint32_t guest_page_size; + + /* Currently buffering records between a checkpoint */ + bool buffer_all_records; + + /* Whether a STATIC_DATA_END record has been seen/inferred. */ + bool seen_static_data_end; + +/* + * With Remus/COLO, we buffer the records sent by the primary at checkpoint, + * in case the primary will fail, we can recover from the last + * checkpoint state. + * This should be enough for most of the cases because primary only send + * dirty pages at checkpoint. + */ +#define DEFAULT_BUF_RECORDS 1024 + struct xc_sr_record *buffered_records; + unsigned int allocated_rec_num; + unsigned int buffered_rec_num; + + /* + * Xenstore and Console parameters. + * INPUT: evtchn & domid + * OUTPUT: gfn + */ + xen_pfn_t xenstore_gfn, console_gfn; + unsigned int xenstore_evtchn, console_evtchn; + uint32_t xenstore_domid, console_domid; + + /* Bitmap of currently populated PFNs during restore. */ + unsigned long *populated_pfns; + xen_pfn_t max_populated_pfn; + + /* Sender has invoked verify mode on the stream. */ + bool verify; + } restore; + }; + + union /* Guest-arch specific data. */ + { + struct /* x86 */ + { + /* Common save/restore data. */ + union + { + struct + { + /* X86_{CPUID,MSR}_DATA blobs for CPU Policy. */ + struct xc_sr_blob cpuid, msr; + } restore; + }; + + struct /* x86 PV guest. */ + { + /* 4 or 8; 32 or 64 bit domain */ + unsigned int width; + /* 3 or 4 pagetable levels */ + unsigned int levels; + + /* Maximum Xen frame */ + xen_pfn_t max_mfn; + /* Read-only machine to phys map */ + xen_pfn_t *m2p; + /* first mfn of the compat m2p (Only needed for 32bit PV guests) */ + xen_pfn_t compat_m2p_mfn0; + /* Number of m2p frames mapped */ + unsigned long nr_m2p_frames; + + /* Maximum guest frame */ + xen_pfn_t max_pfn; + + /* Number of frames making up the p2m */ + unsigned int p2m_frames; + /* Guest's phys to machine map. Mapped read-only (save) or + * allocated locally (restore). Uses guest unsigned longs. */ + void *p2m; + /* The guest pfns containing the p2m leaves */ + xen_pfn_t *p2m_pfns; + + /* Read-only mapping of guests shared info page */ + shared_info_any_t *shinfo; + + /* p2m generation count for verifying validity of local p2m. */ + uint64_t p2m_generation; + + union + { + struct + { + /* State machine for the order of received records. */ + bool seen_pv_info; + + /* Types for each page (bounded by max_pfn). */ + uint32_t *pfn_types; + + /* x86 PV per-vcpu storage structure for blobs. */ + struct xc_sr_x86_pv_restore_vcpu + { + struct xc_sr_blob basic, extd, xsave, msr; + } *vcpus; + unsigned int nr_vcpus; + } restore; + }; + } pv; + + struct /* x86 HVM guest. */ + { + union + { + struct + { + /* Whether qemu enabled logdirty mode, and we should + * disable on cleanup. */ + bool qemu_enabled_logdirty; + } save; + + struct + { + /* HVM context blob. */ + struct xc_sr_blob context; + } restore; + }; + } hvm; + + } x86; + }; +}; + +extern struct xc_sr_save_ops save_ops_x86_pv; +extern struct xc_sr_save_ops save_ops_x86_hvm; + +extern struct xc_sr_restore_ops restore_ops_x86_pv; +extern struct xc_sr_restore_ops restore_ops_x86_hvm; + +struct xc_sr_record +{ + uint32_t type; + uint32_t length; + void *data; +}; + +/* + * Writes a split record to the stream, applying correct padding where + * appropriate. It is common when sending records containing blobs from Xen + * that the header and blob data are separate. This function accepts a second + * buffer and length, and will merge it with the main record when sending. + * + * Records with a non-zero length must provide a valid data field; records + * with a 0 length shall have their data field ignored. + * + * Returns 0 on success and non0 on failure. + */ +int write_split_record(struct xc_sr_context *ctx, struct xc_sr_record *rec, + void *buf, size_t sz); + +/* + * Writes a record to the stream, applying correct padding where appropriate. + * Records with a non-zero length must provide a valid data field; records + * with a 0 length shall have their data field ignored. + * + * Returns 0 on success and non0 on failure. + */ +static inline int write_record(struct xc_sr_context *ctx, + struct xc_sr_record *rec) +{ + return write_split_record(ctx, rec, NULL, 0); +} + +/* + * Reads a record from the stream, and fills in the record structure. + * + * Returns 0 on success and non-0 on failure. + * + * On success, the records type and size shall be valid. + * - If size is 0, data shall be NULL. + * - If size is non-0, data shall be a buffer allocated by malloc() which must + * be passed to free() by the caller. + * + * On failure, the contents of the record structure are undefined. + */ +int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec); + +/* + * This would ideally be private in restore.c, but is needed by + * x86_pv_localise_page() if we receive pagetables frames ahead of the + * contents of the frames they point at. + */ +int populate_pfns(struct xc_sr_context *ctx, unsigned int count, + const xen_pfn_t *original_pfns, const uint32_t *types); + +/* Handle a STATIC_DATA_END record. */ +int handle_static_data_end(struct xc_sr_context *ctx); + +#endif +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/xg_sr_common_x86.c b/tools/libxc/xg_sr_common_x86.c index 77ea044a74..6f12483907 100644 --- a/tools/libxc/xg_sr_common_x86.c +++ b/tools/libxc/xg_sr_common_x86.c @@ -1,4 +1,4 @@ -#include "xc_sr_common_x86.h" +#include "xg_sr_common_x86.h" int write_x86_tsc_info(struct xc_sr_context *ctx) { diff --git a/tools/libxc/xg_sr_common_x86.h b/tools/libxc/xg_sr_common_x86.h new file mode 100644 index 0000000000..b55758c96d --- /dev/null +++ b/tools/libxc/xg_sr_common_x86.h @@ -0,0 +1,51 @@ +#ifndef __COMMON_X86__H +#define __COMMON_X86__H + +#include "xg_sr_common.h" + +/* + * Obtains a domains TSC information from Xen and writes a X86_TSC_INFO record + * into the stream. + */ +int write_x86_tsc_info(struct xc_sr_context *ctx); + +/* + * Parses a X86_TSC_INFO record and applies the result to the domain. + */ +int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec); + +/* + * Obtains a domains CPU Policy from Xen, and writes X86_{CPUID,MSR}_POLICY + * records into the stream. + */ +int write_x86_cpu_policy_records(struct xc_sr_context *ctx); + +/* + * Parses an X86_CPUID_POLICY record and stashes the content for application + * when a STATIC_DATA_END record is encountered. + */ +int handle_x86_cpuid_policy(struct xc_sr_context *ctx, + struct xc_sr_record *rec); + +/* + * Parses an X86_MSR_POLICY record and stashes the content for application + * when a STATIC_DATA_END record is encountered. + */ +int handle_x86_msr_policy(struct xc_sr_context *ctx, + struct xc_sr_record *rec); + +/* + * Perform common x86 actions required after the static data has arrived. + */ +int x86_static_data_complete(struct xc_sr_context *ctx, unsigned int *missing); + +#endif +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/xg_sr_common_x86_pv.c b/tools/libxc/xg_sr_common_x86_pv.c index d3d425cb82..cd33406aab 100644 --- a/tools/libxc/xg_sr_common_x86_pv.c +++ b/tools/libxc/xg_sr_common_x86_pv.c @@ -1,6 +1,6 @@ #include <assert.h> -#include "xc_sr_common_x86_pv.h" +#include "xg_sr_common_x86_pv.h" xen_pfn_t mfn_to_pfn(struct xc_sr_context *ctx, xen_pfn_t mfn) { diff --git a/tools/libxc/xg_sr_common_x86_pv.h b/tools/libxc/xg_sr_common_x86_pv.h new file mode 100644 index 0000000000..953b5bfb8d --- /dev/null +++ b/tools/libxc/xg_sr_common_x86_pv.h @@ -0,0 +1,109 @@ +#ifndef __COMMON_X86_PV_H +#define __COMMON_X86_PV_H + +#include "xg_sr_common_x86.h" + +/* Virtual address ranges reserved for hypervisor. */ +#define HYPERVISOR_VIRT_START_X86_64 0xFFFF800000000000ULL +#define HYPERVISOR_VIRT_END_X86_64 0xFFFF87FFFFFFFFFFULL + +#define HYPERVISOR_VIRT_START_X86_32 0x00000000F5800000ULL +#define HYPERVISOR_VIRT_END_X86_32 0x00000000FFFFFFFFULL + +/* + * Convert an mfn to a pfn, given Xen's m2p table. + * + * Caller must ensure that the requested mfn is in range. + */ +xen_pfn_t mfn_to_pfn(struct xc_sr_context *ctx, xen_pfn_t mfn); + +/* + * Query whether a particular mfn is valid in the physmap of a guest. + */ +bool mfn_in_pseudophysmap(struct xc_sr_context *ctx, xen_pfn_t mfn); + +/* + * Debug a particular mfn by walking the p2m and m2p. + */ +void dump_bad_pseudophysmap_entry(struct xc_sr_context *ctx, xen_pfn_t mfn); + +/* + * Convert a PV cr3 field to an mfn. + * + * Adjusts for Xen's extended-cr3 format to pack a 44bit physical address into + * a 32bit architectural cr3. + */ +xen_pfn_t cr3_to_mfn(struct xc_sr_context *ctx, uint64_t cr3); + +/* + * Convert an mfn to a PV cr3 field. + * + * Adjusts for Xen's extended-cr3 format to pack a 44bit physical address into + * a 32bit architectural cr3. + */ +uint64_t mfn_to_cr3(struct xc_sr_context *ctx, xen_pfn_t mfn); + +/* Bits 12 through 51 of a PTE point at the frame */ +#define PTE_FRAME_MASK 0x000ffffffffff000ULL + +/* + * Extract an mfn from a Pagetable Entry. May return INVALID_MFN if the pte + * would overflow a 32bit xen_pfn_t. + */ +static inline xen_pfn_t pte_to_frame(uint64_t pte) +{ + uint64_t frame = (pte & PTE_FRAME_MASK) >> PAGE_SHIFT; + +#ifdef __i386__ + if ( frame >= INVALID_MFN ) + return INVALID_MFN; +#endif + + return frame; +} + +/* + * Change the frame in a Pagetable Entry while leaving the flags alone. + */ +static inline uint64_t merge_pte(uint64_t pte, xen_pfn_t mfn) +{ + return (pte & ~PTE_FRAME_MASK) | ((uint64_t)mfn << PAGE_SHIFT); +} + +/* + * Get current domain information. + * + * Fills ctx->x86.pv + * - .width + * - .levels + * - .fpp + * - .p2m_frames + * + * Used by the save side to create the X86_PV_INFO record, and by the restore + * side to verify the incoming stream. + * + * Returns 0 on success and non-zero on error. + */ +int x86_pv_domain_info(struct xc_sr_context *ctx); + +/* + * Maps the Xen M2P. + * + * Fills ctx->x86.pv. + * - .max_mfn + * - .m2p + * + * Returns 0 on success and non-zero on error. + */ +int x86_pv_map_m2p(struct xc_sr_context *ctx); + +#endif +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/xg_sr_restore.c b/tools/libxc/xg_sr_restore.c index bc811e6e3a..b57a787519 100644 --- a/tools/libxc/xg_sr_restore.c +++ b/tools/libxc/xg_sr_restore.c @@ -2,7 +2,7 @@ #include <assert.h> -#include "xc_sr_common.h" +#include "xg_sr_common.h" /* * Read and validate the Image and Domain headers. diff --git a/tools/libxc/xg_sr_restore_x86_hvm.c b/tools/libxc/xg_sr_restore_x86_hvm.c index a77624cc9d..d6ea6f3012 100644 --- a/tools/libxc/xg_sr_restore_x86_hvm.c +++ b/tools/libxc/xg_sr_restore_x86_hvm.c @@ -1,7 +1,7 @@ #include <assert.h> #include <arpa/inet.h> -#include "xc_sr_common_x86.h" +#include "xg_sr_common_x86.h" /* * Process an HVM_CONTEXT record from the stream. diff --git a/tools/libxc/xg_sr_restore_x86_pv.c b/tools/libxc/xg_sr_restore_x86_pv.c index d086271efb..dc50b0f5a8 100644 --- a/tools/libxc/xg_sr_restore_x86_pv.c +++ b/tools/libxc/xg_sr_restore_x86_pv.c @@ -1,6 +1,6 @@ #include <assert.h> -#include "xc_sr_common_x86_pv.h" +#include "xg_sr_common_x86_pv.h" static xen_pfn_t pfn_to_mfn(const struct xc_sr_context *ctx, xen_pfn_t pfn) { diff --git a/tools/libxc/xg_sr_save.c b/tools/libxc/xg_sr_save.c index 80b1d5de1f..d74c72cba6 100644 --- a/tools/libxc/xg_sr_save.c +++ b/tools/libxc/xg_sr_save.c @@ -1,7 +1,7 @@ #include <assert.h> #include <arpa/inet.h> -#include "xc_sr_common.h" +#include "xg_sr_common.h" /* * Writes an Image header and Domain header into the stream. diff --git a/tools/libxc/xg_sr_save_x86_hvm.c b/tools/libxc/xg_sr_save_x86_hvm.c index 0b2abb26bd..1634a7bc43 100644 --- a/tools/libxc/xg_sr_save_x86_hvm.c +++ b/tools/libxc/xg_sr_save_x86_hvm.c @@ -1,6 +1,6 @@ #include <assert.h> -#include "xc_sr_common_x86.h" +#include "xg_sr_common_x86.h" #include <xen/hvm/params.h> diff --git a/tools/libxc/xg_sr_save_x86_pv.c b/tools/libxc/xg_sr_save_x86_pv.c index c7e246ef4f..4964f1f7b8 100644 --- a/tools/libxc/xg_sr_save_x86_pv.c +++ b/tools/libxc/xg_sr_save_x86_pv.c @@ -1,7 +1,7 @@ #include <assert.h> #include <limits.h> -#include "xc_sr_common_x86_pv.h" +#include "xg_sr_common_x86_pv.h" /* Check a 64 bit virtual address for being canonical. */ static inline bool is_canonical_address(xen_vaddr_t vaddr) diff --git a/tools/libxc/xg_sr_stream_format.h b/tools/libxc/xg_sr_stream_format.h new file mode 100644 index 0000000000..8a0da26f75 --- /dev/null +++ b/tools/libxc/xg_sr_stream_format.h @@ -0,0 +1,150 @@ +#ifndef __STREAM_FORMAT__H +#define __STREAM_FORMAT__H + +/* + * C structures for the Migration v2 stream format. + * See docs/specs/libxc-migration-stream.pandoc + */ + +#include <inttypes.h> + +/* + * Image Header + */ +struct xc_sr_ihdr +{ + uint64_t marker; + uint32_t id; + uint32_t version; + uint16_t options; + uint16_t _res1; + uint32_t _res2; +}; + +#define IHDR_MARKER 0xffffffffffffffffULL +#define IHDR_ID 0x58454E46U + +#define _IHDR_OPT_ENDIAN 0 +#define IHDR_OPT_LITTLE_ENDIAN (0 << _IHDR_OPT_ENDIAN) +#define IHDR_OPT_BIG_ENDIAN (1 << _IHDR_OPT_ENDIAN) + +/* + * Domain Header + */ +struct xc_sr_dhdr +{ + uint32_t type; + uint16_t page_shift; + uint16_t _res1; + uint32_t xen_major; + uint32_t xen_minor; +}; + +#define DHDR_TYPE_X86_PV 0x00000001U +#define DHDR_TYPE_X86_HVM 0x00000002U + +/* + * Record Header + */ +struct xc_sr_rhdr +{ + uint32_t type; + uint32_t length; +}; + +/* All records must be aligned up to an 8 octet boundary */ +#define REC_ALIGN_ORDER (3U) +/* Somewhat arbitrary - 128MB */ +#define REC_LENGTH_MAX (128U << 20) + +#define REC_TYPE_END 0x00000000U +#define REC_TYPE_PAGE_DATA 0x00000001U +#define REC_TYPE_X86_PV_INFO 0x00000002U +#define REC_TYPE_X86_PV_P2M_FRAMES 0x00000003U +#define REC_TYPE_X86_PV_VCPU_BASIC 0x00000004U +#define REC_TYPE_X86_PV_VCPU_EXTENDED 0x00000005U +#define REC_TYPE_X86_PV_VCPU_XSAVE 0x00000006U +#define REC_TYPE_SHARED_INFO 0x00000007U +#define REC_TYPE_X86_TSC_INFO 0x00000008U +#define REC_TYPE_HVM_CONTEXT 0x00000009U +#define REC_TYPE_HVM_PARAMS 0x0000000aU +#define REC_TYPE_TOOLSTACK 0x0000000bU +#define REC_TYPE_X86_PV_VCPU_MSRS 0x0000000cU +#define REC_TYPE_VERIFY 0x0000000dU +#define REC_TYPE_CHECKPOINT 0x0000000eU +#define REC_TYPE_CHECKPOINT_DIRTY_PFN_LIST 0x0000000fU +#define REC_TYPE_STATIC_DATA_END 0x00000010U +#define REC_TYPE_X86_CPUID_POLICY 0x00000011U +#define REC_TYPE_X86_MSR_POLICY 0x00000012U + +#define REC_TYPE_OPTIONAL 0x80000000U + +/* PAGE_DATA */ +struct xc_sr_rec_page_data_header +{ + uint32_t count; + uint32_t _res1; + uint64_t pfn[0]; +}; + +#define PAGE_DATA_PFN_MASK 0x000fffffffffffffULL +#define PAGE_DATA_TYPE_MASK 0xf000000000000000ULL + +/* X86_PV_INFO */ +struct xc_sr_rec_x86_pv_info +{ + uint8_t guest_width; + uint8_t pt_levels; + uint8_t _res[6]; +}; + +/* X86_PV_P2M_FRAMES */ +struct xc_sr_rec_x86_pv_p2m_frames +{ + uint32_t start_pfn; + uint32_t end_pfn; + uint64_t p2m_pfns[0]; +}; + +/* X86_PV_VCPU_{BASIC,EXTENDED,XSAVE,MSRS} */ +struct xc_sr_rec_x86_pv_vcpu_hdr +{ + uint32_t vcpu_id; + uint32_t _res1; + uint8_t context[0]; +}; + +/* X86_TSC_INFO */ +struct xc_sr_rec_x86_tsc_info +{ + uint32_t mode; + uint32_t khz; + uint64_t nsec; + uint32_t incarnation; + uint32_t _res1; +}; + +/* HVM_PARAMS */ +struct xc_sr_rec_hvm_params_entry +{ + uint64_t index; + uint64_t value; +}; + +struct xc_sr_rec_hvm_params +{ + uint32_t count; + uint32_t _res1; + struct xc_sr_rec_hvm_params_entry param[0]; +}; + +#endif +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ -- generated by git-patchbot for /home/xen/git/xen.git#staging
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |