diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c index 129365c42f..3fd0330714 100644 --- a/tools/libxc/xc_domain_restore.c +++ b/tools/libxc/xc_domain_restore.c @@ -640,6 +640,7 @@ typedef struct { uint64_t vcpumap; uint64_t identpt; uint64_t vm86_tss; + uint64_t console_pfn; } pagebuf_t; static int pagebuf_init(pagebuf_t* buf) @@ -737,6 +738,16 @@ static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx, return -1; } return pagebuf_get_one(xch, ctx, buf, fd, dom); + } else if (count == -8 ) { + /* Skip padding 4 bytes then read the console pfn location. */ + if ( read_exact(fd, &buf->console_pfn, sizeof(uint32_t)) || + read_exact(fd, &buf->console_pfn, sizeof(uint64_t)) ) + { + PERROR("error read the address of the console pfn"); + return -1; + } + // DPRINTF("console pfn location: %llx\n", buf->console_pfn); + return pagebuf_get_one(xch, ctx, buf, fd, dom); } else if ( (count > MAX_BATCH_SIZE) || (count < 0) ) { ERROR("Max batch size exceeded (%d). Giving up.", count); errno = EMSGSIZE; @@ -1055,6 +1066,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, pagebuf_t pagebuf; tailbuf_t tailbuf, tmptail; void* vcpup; + uint64_t console_pfn = 0; static struct restore_ctx _ctx = { .live_p2m = NULL, @@ -1207,6 +1219,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, xc_set_hvm_param(xch, dom, HVM_PARAM_IDENT_PT, pagebuf.identpt); if ( pagebuf.vm86_tss ) xc_set_hvm_param(xch, dom, HVM_PARAM_VM86_TSS, pagebuf.vm86_tss); + if ( pagebuf.console_pfn ) + console_pfn = pagebuf.console_pfn; break; /* our work here is done */ } @@ -1717,6 +1731,19 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, } *store_mfn = tailbuf.u.hvm.magicpfns[2]; + if ( console_pfn ) { + if ( xc_clear_domain_page(xch, dom, console_pfn) ) { + PERROR("error zeroing console page"); + goto out; + } + if ( (frc = xc_set_hvm_param(xch, dom, + HVM_PARAM_CONSOLE_PFN, console_pfn)) ) { + PERROR("error setting HVM param: %i", frc); + goto out; + } + *console_mfn = console_pfn; + } + frc = xc_domain_hvm_setcontext(xch, dom, tailbuf.u.hvm.hvmbuf, tailbuf.u.hvm.reclen); if ( frc ) diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c index cc6bd1318e..2ea2272406 100644 --- a/tools/libxc/xc_domain_save.c +++ b/tools/libxc/xc_domain_save.c @@ -1587,6 +1587,17 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter PERROR("Error when writing the vm86 TSS for guest"); goto out; } + + chunk.id = -8; + xc_get_hvm_param(xch, dom, HVM_PARAM_CONSOLE_PFN, + (unsigned long *)&chunk.data); + + if ( (chunk.data != 0) && + wrexact(io_fd, &chunk, sizeof(chunk)) ) + { + PERROR("Error when writing the console pfn for guest"); + goto out; + } } /* Zero terminate */ diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c index 4fc5f6d63e..7bdd50b1f3 100644 --- a/tools/libxc/xc_hvm_build.c +++ b/tools/libxc/xc_hvm_build.c @@ -28,7 +28,8 @@ #define SPECIALPAGE_XENSTORE 1 #define SPECIALPAGE_IOREQ 2 #define SPECIALPAGE_IDENT_PT 3 -#define NR_SPECIAL_PAGES 4 +#define SPECIALPAGE_CONSOLE 4 +#define NR_SPECIAL_PAGES 5 #define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x)) static void build_hvm_info(void *hvm_info_page, uint64_t mem_size) @@ -354,6 +355,8 @@ static int setup_guest(xc_interface *xch, special_pfn(SPECIALPAGE_BUFIOREQ)); xc_set_hvm_param(xch, dom, HVM_PARAM_IOREQ_PFN, special_pfn(SPECIALPAGE_IOREQ)); + xc_set_hvm_param(xch, dom, HVM_PARAM_CONSOLE_PFN, + special_pfn(SPECIALPAGE_CONSOLE)); /* * Identity-map page table is required for running with CR0.PG=0 when diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index b251d8aa4e..2c1b5351e6 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -237,7 +237,7 @@ int build_hvm(libxl_ctx *ctx, uint32_t domid, return ERROR_FAIL; } ret = hvm_build_set_params(ctx->xch, domid, info, state->store_port, - &state->store_mfn); + &state->store_mfn, state->console_port, &state->console_mfn); if (ret) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "hvm build set params failed"); return ERROR_FAIL; diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 3f0454468a..dde37df1aa 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -173,7 +173,8 @@ int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int bus /* from xenguest (helper */ int hvm_build_set_params(xc_interface *handle, uint32_t domid, libxl_domain_build_info *info, - int store_evtchn, unsigned long *store_mfn); + int store_evtchn, unsigned long *store_mfn, + int console_evtchn, unsigned long *console_mfn); /* xl_exec */ diff --git a/tools/libxl/xenguest.c b/tools/libxl/xenguest.c index 1f88b8a23a..9351f23e81 100644 --- a/tools/libxl/xenguest.c +++ b/tools/libxl/xenguest.c @@ -23,7 +23,8 @@ int hvm_build_set_params(xc_interface *handle, uint32_t domid, libxl_domain_build_info *info, - int store_evtchn, unsigned long *store_mfn) + int store_evtchn, unsigned long *store_mfn, + int console_evtchn, unsigned long *console_mfn) { struct hvm_info_table *va_hvm; uint8_t *va_map, sum; @@ -46,6 +47,7 @@ int hvm_build_set_params(xc_interface *handle, uint32_t domid, munmap(va_map, XC_PAGE_SIZE); xc_get_hvm_param(handle, domid, HVM_PARAM_STORE_PFN, store_mfn); + xc_get_hvm_param(handle, domid, HVM_PARAM_CONSOLE_PFN, console_mfn); xc_set_hvm_param(handle, domid, HVM_PARAM_PAE_ENABLED, info->u.hvm.pae); #if defined(__i386__) || defined(__x86_64__) xc_set_hvm_param(handle, domid, HVM_PARAM_VIRIDIAN, info->u.hvm.viridian); @@ -54,5 +56,6 @@ int hvm_build_set_params(xc_interface *handle, uint32_t domid, xc_set_hvm_param(handle, domid, HVM_PARAM_TIMER_MODE, (unsigned long) info->u.hvm.timer_mode); xc_set_hvm_param(handle, domid, HVM_PARAM_VPT_ALIGN, (unsigned long) info->u.hvm.vpt_align); xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn); + xc_set_hvm_param(handle, domid, HVM_PARAM_CONSOLE_EVTCHN, console_evtchn); return 0; } diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 51d9f4b31c..e42ad69cbe 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -1433,6 +1433,9 @@ start: } } if (d_config.c_info.hvm) { + init_console_info(&console, 0, &state); + console.domid = domid; + libxl_device_console_add(&ctx, domid, &console); dm_info.domid = domid; MUST( libxl_create_device_model(&ctx, &dm_info, d_config.disks, d_config.num_disks, diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index 7e276d92e0..673148bbfa 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -109,6 +109,10 @@ /* Boolean: Enable aligning all periodic vpts to reduce interrupts */ #define HVM_PARAM_VPT_ALIGN 16 -#define HVM_NR_PARAMS 17 +/* Console debug shared memory ring and event channel */ +#define HVM_PARAM_CONSOLE_PFN 17 +#define HVM_PARAM_CONSOLE_EVTCHN 18 + +#define HVM_NR_PARAMS 19 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */