All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/31] Introduce HVM without dm and new boot ABI
@ 2015-08-07 10:17 Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling Roger Pau Monne
                   ` (30 more replies)
  0 siblings, 31 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel

This series is split in the following order:

 - Patch 1 is a fixup of the error paths in libxl__build_hvm and related
   functions (and can go in independently of the rest of the series).
 - Patches from 2 to 11 switch HVM domain contruction to use the xc_dom_*
   family of functions, like they are used to build PV domains. This batch
   of patches can go in regardless of the status of the rest of the series
   IMHO, and in fact would help me quite a lot with the rebasing.
 - Patches from 12 to 22 allow disabling the devices emulated inside of Xen.
 - Patches from 23 to 31 introduce the creation of HVM guests without a
   device model and without the devices emulated inside of Xen.

This series has been successfully tested on the following hardware:

 - Intel Xeon W3550.
 - AMD Opteron 4184.

With both hap=0 and hap=1 in the configuration file. I've been able to boot
a SMP guest in this mode with a virtual hard drive and a virtual network
card, all working fine AFAICT.

For this round only maintainers of the specific code being modified have
been Cced on the patches.

The series can also be found in the following git repo:

git://xenbits.xen.org/people/royger/xen.git branch hvm_without_dm_v4

And for the FreeBSD part:

git://xenbits.xen.org/people/royger/freebsd.git branch new_entry_point_v3

In case someone wants to give it a try, I've uploaded a FreeBSD kernel that
should work when booted into this mode:

https://people.freebsd.org/~royger/kernel_no_dm

This FreeBSD kernel starts the APs in long mode. There are examples for 
starting the APs in other modes in the sys/x86/xen/pv.c file.

The config file that I've used is:

<config>
kernel="/path/to/kernel_no_dm"

builder="hvm"
device_model_version="none"

memory=128
vcpus=2
name = "freebsd"
</config>

Of course if you have a FreeBSD disk already setup it can also be added to
the configuration file, and the following line can be used to point FreeBSD
to the disk:

extra="vfs.root.mountfrom=ufs:/dev/ufsid/<disk_id>"

N  01/31 libxl: fix libxl__build_hvm error handling
AW 02/31 libxc: split x86 HVM setup_guest into smaller
AW 03/31 libxc: unify xc_dom_p2m_{host/guest}
AW 04/31 libxc: introduce the notion of a container type
AW 05/31 libxc: introduce a domain loader for HVM guest
AW 06/31 libxc: make arch_setup_meminit a xc_dom_arch hook
AW 07/31 libxc: make arch_setup_boot{init/late} xc_dom_arch
M  08/31 libxc: rework BSP initialization
M  09/31 libxc: introduce a xc_dom_arch for hvm-3.0-x86_32
M  10/31 libxl: switch HVM domain building to use xc_dom_*
   11/31 libxc: remove dead HVM building code
M  12/31 xen/x86: add bitmap of enabled emulated devices
   13/31 xen/x86: allow disabling the emulated local apic
   14/31 xen/x86: allow disabling the emulated HPET
   15/31 xen/x86: allow disabling the pmtimer
   16/31 xen/x86: allow disabling the emulated RTC
   17/31 xen/x86: allow disabling the emulated IO APIC
   18/31 xen/x86: allow disabling the emulated PIC
   19/31 xen/x86: allow disabling the emulated pmu
   20/31 xen/x86: allow disabling the emulated VGA
   21/31 xen/x86: allow disabling the emulated IOMMU
   22/31 xen/x86: allow disabling all emulated devices inside
   23/31 elfnotes: intorduce a new PHYS_ENTRY elfnote
M  24/31 libxc: allow creating domains without emulated
   25/31 xen: allow HVM guests to use XENMEM_memory_map
M  26/31 xen/x86: allow HVM guests to use hypercalls to bring
M  27/31 xenconsole: try to attach to PV console if HVM fails
   28/31 libxc/xen: introduce HVM_PARAM_CMDLINE_PFN
   29/31 libxc/xen: introduce HVM_PARAM_MODLIST_PFN
   30/31 libxc: switch xc_dom_elfloader to be used with
M  31/31 libxl: allow the creation of HVM domains without a

A = Acked/Reviewed by Andrew Cooper.
W = Acked/Reviewed by Wei Liu.
N = New in this version.
M = Modified in this version.

Thanks, Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:49   ` Wei Liu
                     ` (2 more replies)
  2015-08-07 10:17 ` [PATCH v4 02/31] libxc: split x86 HVM setup_guest into smaller logical functions Roger Pau Monne
                   ` (29 subsequent siblings)
  30 siblings, 3 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

With the current code in libxl__build_hvm it is possible for the function to
fail and still return 0.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxl/libxl_dom.c | 39 ++++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index e1f11a3..38fb939 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -766,7 +766,7 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
                                   XC_PAGE_SIZE, PROT_READ | PROT_WRITE,
                                   HVM_INFO_PFN);
     if (va_map == NULL)
-        return -1;
+        return ERROR_FAIL;
 
     va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
     va_hvm->apic_mode = libxl_defbool_val(info->u.hvm.apic);
@@ -912,7 +912,7 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     struct xc_hvm_build_args args = {};
-    int ret, rc = ERROR_FAIL;
+    int ret, rc;
     uint64_t mmio_start, lowmem_end, highmem_end;
     libxl_domain_build_info *const info = &d_config->b_info;
 
@@ -932,7 +932,9 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
         if (max_ram_below_4g < HVM_BELOW_4G_MMIO_START)
             args.mmio_size = info->u.hvm.mmio_hole_memkb << 10;
     }
-    if (libxl__domain_firmware(gc, info, &args)) {
+
+    rc = libxl__domain_firmware(gc, info, &args);
+    if (rc != 0) {
         LOG(ERROR, "initializing domain firmware failed");
         goto out;
     }
@@ -963,15 +965,15 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
     if (info->num_vnuma_nodes != 0) {
         int i;
 
-        ret = libxl__vnuma_build_vmemrange_hvm(gc, domid, info, state, &args);
-        if (ret) {
-            LOGEV(ERROR, ret, "hvm build vmemranges failed");
+        rc = libxl__vnuma_build_vmemrange_hvm(gc, domid, info, state, &args);
+        if (rc != 0) {
+            LOG(ERROR, "hvm build vmemranges failed");
             goto out;
         }
-        ret = libxl__vnuma_config_check(gc, info, state);
-        if (ret) goto out;
-        ret = set_vnuma_info(gc, domid, info, state);
-        if (ret) goto out;
+        rc = libxl__vnuma_config_check(gc, info, state);
+        if (rc != 0) goto out;
+        rc = set_vnuma_info(gc, domid, info, state);
+        if (rc != 0) goto out;
 
         args.nr_vmemranges = state->num_vmemranges;
         args.vmemranges = libxl__malloc(gc, sizeof(*args.vmemranges) *
@@ -994,31 +996,34 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
     ret = xc_hvm_build(ctx->xch, domid, &args);
     if (ret) {
         LOGEV(ERROR, ret, "hvm building failed");
+        rc = ERROR_FAIL;
         goto out;
     }
 
-    if (libxl__arch_domain_construct_memmap(gc, d_config, domid, &args)) {
+    rc = libxl__arch_domain_construct_memmap(gc, d_config, domid, &args);
+    if (rc != 0) {
         LOG(ERROR, "setting domain memory map failed");
         goto out;
     }
 
-    ret = hvm_build_set_params(ctx->xch, domid, info, state->store_port,
+    rc = hvm_build_set_params(ctx->xch, domid, info, state->store_port,
                                &state->store_mfn, state->console_port,
                                &state->console_mfn, state->store_domid,
                                state->console_domid);
-    if (ret) {
-        LOGEV(ERROR, ret, "hvm build set params failed");
+    if (rc != 0) {
+        LOG(ERROR, "hvm build set params failed");
         goto out;
     }
 
-    ret = hvm_build_set_xs_values(gc, domid, &args);
-    if (ret) {
-        LOG(ERROR, "hvm build set xenstore values failed (ret=%d)", ret);
+    rc = hvm_build_set_xs_values(gc, domid, &args);
+    if (rc != 0) {
+        LOG(ERROR, "hvm build set xenstore values failed");
         goto out;
     }
 
     return 0;
 out:
+    assert(rc != 0);
     return rc;
 }
 
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 02/31] libxc: split x86 HVM setup_guest into smaller logical functions
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 03/31] libxc: unify xc_dom_p2m_{host/guest} Roger Pau Monne
                   ` (28 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

This is just a preparatory change to clean up the code in setup_guest.
Should not introduce any functional changes.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Changes since v3:
 - Add Andrew Cooper Reviewed-by.
 - Add Wei Acked-by.
---
 tools/libxc/xc_hvm_build_x86.c | 198 ++++++++++++++++++++++++-----------------
 1 file changed, 117 insertions(+), 81 deletions(-)

diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
index ec11f15..6f79686 100644
--- a/tools/libxc/xc_hvm_build_x86.c
+++ b/tools/libxc/xc_hvm_build_x86.c
@@ -231,28 +231,20 @@ static int check_mmio_hole(uint64_t start, uint64_t memsize,
         return 1;
 }
 
-static int setup_guest(xc_interface *xch,
-                       uint32_t dom, struct xc_hvm_build_args *args,
-                       char *image, unsigned long image_size)
+static int xc_hvm_populate_memory(xc_interface *xch, uint32_t dom,
+                                  struct xc_hvm_build_args *args,
+                                  xen_pfn_t *page_array)
 {
-    xen_pfn_t *page_array = NULL;
     unsigned long i, vmemid, nr_pages = args->mem_size >> PAGE_SHIFT;
     unsigned long p2m_size;
     unsigned long target_pages = args->mem_target >> PAGE_SHIFT;
-    unsigned long entry_eip, cur_pages, cur_pfn;
-    void *hvm_info_page;
-    uint32_t *ident_pt;
-    struct elf_binary elf;
-    uint64_t v_start, v_end;
-    uint64_t m_start = 0, m_end = 0;
+    unsigned long cur_pages, cur_pfn;
     int rc;
     xen_capabilities_info_t caps;
     unsigned long stat_normal_pages = 0, stat_2mb_pages = 0, 
         stat_1gb_pages = 0;
     unsigned int memflags = 0;
     int claim_enabled = args->claim_enabled;
-    xen_pfn_t special_array[NR_SPECIAL_PAGES];
-    xen_pfn_t ioreq_server_array[NR_IOREQ_SERVER_PAGES];
     uint64_t total_pages;
     xen_vmemrange_t dummy_vmemrange[2];
     unsigned int dummy_vnode_to_pnode[1];
@@ -260,19 +252,6 @@ static int setup_guest(xc_interface *xch,
     unsigned int *vnode_to_pnode;
     unsigned int nr_vmemranges, nr_vnodes;
 
-    memset(&elf, 0, sizeof(elf));
-    if ( elf_init(&elf, image, image_size) != 0 )
-    {
-        PERROR("Could not initialise ELF image");
-        goto error_out;
-    }
-
-    xc_elf_set_logfile(xch, &elf, 1);
-
-    elf_parse_binary(&elf);
-    v_start = 0;
-    v_end = args->mem_size;
-
     if ( nr_pages > target_pages )
         memflags |= XENMEMF_populate_on_demand;
 
@@ -345,24 +324,6 @@ static int setup_guest(xc_interface *xch,
         goto error_out;
     }
 
-    if ( modules_init(args, v_end, &elf, &m_start, &m_end) != 0 )
-    {
-        ERROR("Insufficient space to load modules.");
-        goto error_out;
-    }
-
-    DPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
-    DPRINTF("  Loader:   %016"PRIx64"->%016"PRIx64"\n", elf.pstart, elf.pend);
-    DPRINTF("  Modules:  %016"PRIx64"->%016"PRIx64"\n", m_start, m_end);
-    DPRINTF("  TOTAL:    %016"PRIx64"->%016"PRIx64"\n", v_start, v_end);
-    DPRINTF("  ENTRY:    %016"PRIx64"\n", elf_uval(&elf, elf.ehdr, e_entry));
-
-    if ( (page_array = malloc(p2m_size * sizeof(xen_pfn_t))) == NULL )
-    {
-        PERROR("Could not allocate memory.");
-        goto error_out;
-    }
-
     for ( i = 0; i < p2m_size; i++ )
         page_array[i] = ((xen_pfn_t)-1);
     for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
@@ -562,7 +523,54 @@ static int setup_guest(xc_interface *xch,
     DPRINTF("  4KB PAGES: 0x%016lx\n", stat_normal_pages);
     DPRINTF("  2MB PAGES: 0x%016lx\n", stat_2mb_pages);
     DPRINTF("  1GB PAGES: 0x%016lx\n", stat_1gb_pages);
-    
+
+    rc = 0;
+    goto out;
+ error_out:
+    rc = -1;
+ out:
+
+    /* ensure no unclaimed pages are left unused */
+    xc_domain_claim_pages(xch, dom, 0 /* cancels the claim */);
+
+    return rc;
+}
+
+static int xc_hvm_load_image(xc_interface *xch,
+                       uint32_t dom, struct xc_hvm_build_args *args,
+                       xen_pfn_t *page_array)
+{
+    unsigned long entry_eip, image_size;
+    struct elf_binary elf;
+    uint64_t v_start, v_end;
+    uint64_t m_start = 0, m_end = 0;
+    char *image;
+    int rc;
+
+    image = xc_read_image(xch, args->image_file_name, &image_size);
+    if ( image == NULL )
+        return -1;
+
+    memset(&elf, 0, sizeof(elf));
+    if ( elf_init(&elf, image, image_size) != 0 )
+        goto error_out;
+
+    xc_elf_set_logfile(xch, &elf, 1);
+
+    elf_parse_binary(&elf);
+    v_start = 0;
+    v_end = args->mem_size;
+
+    if ( modules_init(args, v_end, &elf, &m_start, &m_end) != 0 )
+    {
+        ERROR("Insufficient space to load modules.");
+        goto error_out;
+    }
+
+    DPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
+    DPRINTF("  Loader:   %016"PRIx64"->%016"PRIx64"\n", elf.pstart, elf.pend);
+    DPRINTF("  Modules:  %016"PRIx64"->%016"PRIx64"\n", m_start, m_end);
+
     if ( loadelfimage(xch, &elf, dom, page_array) != 0 )
     {
         PERROR("Could not load ELF image");
@@ -575,6 +583,44 @@ static int setup_guest(xc_interface *xch,
         goto error_out;
     }
 
+    /* Insert JMP <rel32> instruction at address 0x0 to reach entry point. */
+    entry_eip = elf_uval(&elf, elf.ehdr, e_entry);
+    if ( entry_eip != 0 )
+    {
+        char *page0 = xc_map_foreign_range(
+            xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, 0);
+        if ( page0 == NULL )
+            goto error_out;
+        page0[0] = 0xe9;
+        *(uint32_t *)&page0[1] = entry_eip - 5;
+        munmap(page0, PAGE_SIZE);
+    }
+
+    rc = 0;
+    goto out;
+ error_out:
+    rc = -1;
+ out:
+    if ( elf_check_broken(&elf) )
+        ERROR("HVM ELF broken: %s", elf_check_broken(&elf));
+    free(image);
+
+    return rc;
+}
+
+static int xc_hvm_populate_params(xc_interface *xch, uint32_t dom,
+                                  struct xc_hvm_build_args *args)
+{
+    unsigned long i;
+    void *hvm_info_page;
+    uint32_t *ident_pt;
+    uint64_t v_end;
+    int rc;
+    xen_pfn_t special_array[NR_SPECIAL_PAGES];
+    xen_pfn_t ioreq_server_array[NR_IOREQ_SERVER_PAGES];
+
+    v_end = args->mem_size;
+
     if ( (hvm_info_page = xc_map_foreign_range(
               xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
               HVM_INFO_PFN)) == NULL )
@@ -663,34 +709,12 @@ static int setup_guest(xc_interface *xch,
     xc_hvm_param_set(xch, dom, HVM_PARAM_IDENT_PT,
                      special_pfn(SPECIALPAGE_IDENT_PT) << PAGE_SHIFT);
 
-    /* Insert JMP <rel32> instruction at address 0x0 to reach entry point. */
-    entry_eip = elf_uval(&elf, elf.ehdr, e_entry);
-    if ( entry_eip != 0 )
-    {
-        char *page0 = xc_map_foreign_range(
-            xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, 0);
-        if ( page0 == NULL )
-        {
-            PERROR("Could not map page0");
-            goto error_out;
-        }
-        page0[0] = 0xe9;
-        *(uint32_t *)&page0[1] = entry_eip - 5;
-        munmap(page0, PAGE_SIZE);
-    }
-
     rc = 0;
     goto out;
  error_out:
     rc = -1;
  out:
-    if ( elf_check_broken(&elf) )
-        ERROR("HVM ELF broken: %s", elf_check_broken(&elf));
-
-    /* ensure no unclaimed pages are left unused */
-    xc_domain_claim_pages(xch, dom, 0 /* cancels the claim */);
 
-    free(page_array);
     return rc;
 }
 
@@ -701,9 +725,8 @@ int xc_hvm_build(xc_interface *xch, uint32_t domid,
                  struct xc_hvm_build_args *hvm_args)
 {
     struct xc_hvm_build_args args = *hvm_args;
-    void *image;
-    unsigned long image_size;
-    int sts;
+    xen_pfn_t *parray = NULL;
+    int rc;
 
     if ( domid == 0 )
         return -1;
@@ -714,24 +737,37 @@ int xc_hvm_build(xc_interface *xch, uint32_t domid,
     if ( args.mem_size < (2ull << 20) || args.mem_target < (2ull << 20) )
         return -1;
 
-    image = xc_read_image(xch, args.image_file_name, &image_size);
-    if ( image == NULL )
+    parray = malloc((args.mem_size >> PAGE_SHIFT) * sizeof(xen_pfn_t));
+    if ( parray == NULL )
         return -1;
 
-    sts = setup_guest(xch, domid, &args, image, image_size);
-
-    if (!sts)
+    rc = xc_hvm_populate_memory(xch, domid, &args, parray);
+    if ( rc != 0 )
     {
-        /* Return module load addresses to caller */
-        hvm_args->acpi_module.guest_addr_out = 
-            args.acpi_module.guest_addr_out;
-        hvm_args->smbios_module.guest_addr_out = 
-            args.smbios_module.guest_addr_out;
+        PERROR("xc_hvm_populate_memory failed");
+        goto out;
+    }
+    rc = xc_hvm_load_image(xch, domid, &args, parray);
+    if ( rc != 0 )
+    {
+        PERROR("xc_hvm_load_image failed");
+        goto out;
+    }
+    rc = xc_hvm_populate_params(xch, domid, &args);
+    if ( rc != 0 )
+    {
+        PERROR("xc_hvm_populate_params failed");
+        goto out;
     }
 
-    free(image);
+    /* Return module load addresses to caller */
+    hvm_args->acpi_module.guest_addr_out = args.acpi_module.guest_addr_out;
+    hvm_args->smbios_module.guest_addr_out = args.smbios_module.guest_addr_out;
 
-    return sts;
+out:
+    free(parray);
+
+    return rc;
 }
 
 /* xc_hvm_build_target_mem: 
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 03/31] libxc: unify xc_dom_p2m_{host/guest}
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 02/31] libxc: split x86 HVM setup_guest into smaller logical functions Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 04/31] libxc: introduce the notion of a container type Roger Pau Monne
                   ` (27 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Ian Jackson,
	Samuel Thibault, Roger Pau Monne

Unify both functions into xc_dom_p2m. Should not introduce any functional
change.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
Changes since v3:
 - Add Andrew Cooper Reviewed-by.
 - Add Wei Acked-by.
---
 stubdom/grub/kexec.c              |  4 ++--
 tools/libxc/include/xc_dom.h      | 14 ++------------
 tools/libxc/xc_dom_boot.c         | 10 +++++-----
 tools/libxc/xc_dom_compat_linux.c |  4 ++--
 tools/libxc/xc_dom_x86.c          | 32 ++++++++++++++++----------------
 tools/libxl/libxl_dom.c           |  4 ++--
 6 files changed, 29 insertions(+), 39 deletions(-)

diff --git a/stubdom/grub/kexec.c b/stubdom/grub/kexec.c
index 4c33b25..0b2f4f3 100644
--- a/stubdom/grub/kexec.c
+++ b/stubdom/grub/kexec.c
@@ -358,9 +358,9 @@ void kexec(void *kernel, long kernel_size, void *module, long module_size, char
 #ifdef __x86_64__
                 MMUEXT_PIN_L4_TABLE,
 #endif
-                xc_dom_p2m_host(dom, dom->pgtables_seg.pfn),
+                xc_dom_p2m(dom, dom->pgtables_seg.pfn),
                 dom->guest_domid)) != 0 ) {
-        grub_printf("pin_table(%lx) returned %d\n", xc_dom_p2m_host(dom,
+        grub_printf("pin_table(%lx) returned %d\n", xc_dom_p2m(dom,
                     dom->pgtables_seg.pfn), rc);
         errnum = ERR_BOOT_FAILURE;
         goto out_remap;
diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 600aef6..9cf13e2 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -375,19 +375,9 @@ static inline void *xc_dom_vaddr_to_ptr(struct xc_dom_image *dom,
     return ptr + offset;
 }
 
-static inline xen_pfn_t xc_dom_p2m_host(struct xc_dom_image *dom, xen_pfn_t pfn)
+static inline xen_pfn_t xc_dom_p2m(struct xc_dom_image *dom, xen_pfn_t pfn)
 {
-    if (dom->shadow_enabled)
-        return pfn;
-    if (pfn < dom->rambase_pfn || pfn >= dom->rambase_pfn + dom->total_pages)
-        return INVALID_MFN;
-    return dom->p2m_host[pfn - dom->rambase_pfn];
-}
-
-static inline xen_pfn_t xc_dom_p2m_guest(struct xc_dom_image *dom,
-                                         xen_pfn_t pfn)
-{
-    if (xc_dom_feature_translated(dom))
+    if ( dom->shadow_enabled || xc_dom_feature_translated(dom) )
         return pfn;
     if (pfn < dom->rambase_pfn || pfn >= dom->rambase_pfn + dom->total_pages)
         return INVALID_MFN;
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index 8e06406..7c30f96 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -53,7 +53,7 @@ static int setup_hypercall_page(struct xc_dom_image *dom)
                   dom->parms.virt_hypercall, pfn);
     domctl.cmd = XEN_DOMCTL_hypercall_init;
     domctl.domain = dom->guest_domid;
-    domctl.u.hypercall_init.gmfn = xc_dom_p2m_guest(dom, pfn);
+    domctl.u.hypercall_init.gmfn = xc_dom_p2m(dom, pfn);
     rc = do_domctl(dom->xch, &domctl);
     if ( rc != 0 )
         xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
@@ -83,7 +83,7 @@ static int clear_page(struct xc_dom_image *dom, xen_pfn_t pfn)
     if ( pfn == 0 )
         return 0;
 
-    dst = xc_dom_p2m_host(dom, pfn);
+    dst = xc_dom_p2m(dom, pfn);
     DOMPRINTF("%s: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "",
               __FUNCTION__, pfn, dst);
     rc = xc_clear_domain_page(dom->xch, dom->guest_domid, dst);
@@ -177,7 +177,7 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn,
     }
 
     for ( i = 0; i < count; i++ )
-        entries[i].mfn = xc_dom_p2m_host(dom, pfn + i);
+        entries[i].mfn = xc_dom_p2m(dom, pfn + i);
 
     ptr = xc_map_foreign_ranges(dom->xch, dom->guest_domid,
                 count << page_shift, PROT_READ | PROT_WRITE, 1 << page_shift,
@@ -434,8 +434,8 @@ int xc_dom_gnttab_init(struct xc_dom_image *dom)
                                       dom->console_domid, dom->xenstore_domid);
     } else {
         return xc_dom_gnttab_seed(dom->xch, dom->guest_domid,
-                                  xc_dom_p2m_host(dom, dom->console_pfn),
-                                  xc_dom_p2m_host(dom, dom->xenstore_pfn),
+                                  xc_dom_p2m(dom, dom->console_pfn),
+                                  xc_dom_p2m(dom, dom->xenstore_pfn),
                                   dom->console_domid, dom->xenstore_domid);
     }
 }
diff --git a/tools/libxc/xc_dom_compat_linux.c b/tools/libxc/xc_dom_compat_linux.c
index a3abb99..5c1f043 100644
--- a/tools/libxc/xc_dom_compat_linux.c
+++ b/tools/libxc/xc_dom_compat_linux.c
@@ -64,8 +64,8 @@ static int xc_linux_build_internal(struct xc_dom_image *dom,
     if ( (rc = xc_dom_gnttab_init(dom)) != 0)
         goto out;
 
-    *console_mfn = xc_dom_p2m_host(dom, dom->console_pfn);
-    *store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn);
+    *console_mfn = xc_dom_p2m(dom, dom->console_pfn);
+    *store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn);
 
  out:
     return rc;
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 3d40fa4..dc2f4aa 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -247,7 +247,7 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
     unsigned long l3off, l2off = 0, l1off;
     xen_vaddr_t addr;
     xen_pfn_t pgpfn;
-    xen_pfn_t l3mfn = xc_dom_p2m_guest(dom, l3pfn);
+    xen_pfn_t l3mfn = xc_dom_p2m(dom, l3pfn);
 
     if ( dom->parms.pae == 1 )
     {
@@ -279,7 +279,7 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
                 goto pfn_error;
             l3off = l3_table_offset_pae(addr);
             l3tab[l3off] =
-                pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
+                pfn_to_paddr(xc_dom_p2m(dom, l2pfn)) | L3_PROT;
             l2pfn++;
         }
 
@@ -291,7 +291,7 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
                 goto pfn_error;
             l2off = l2_table_offset_pae(addr);
             l2tab[l2off] =
-                pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
+                pfn_to_paddr(xc_dom_p2m(dom, l1pfn)) | L2_PROT;
             l1pfn++;
         }
 
@@ -299,7 +299,7 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
         l1off = l1_table_offset_pae(addr);
         pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86;
         l1tab[l1off] =
-            pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT;
+            pfn_to_paddr(xc_dom_p2m(dom, pgpfn)) | L1_PROT;
         if ( (addr >= dom->pgtables_seg.vstart) &&
              (addr < dom->pgtables_seg.vend) )
             l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */
@@ -315,7 +315,7 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
     if ( dom->virt_pgtab_end <= 0xc0000000 )
     {
         DOMPRINTF("%s: PAE: extra l2 page table for l3#3", __FUNCTION__);
-        l3tab[3] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
+        l3tab[3] = pfn_to_paddr(xc_dom_p2m(dom, l2pfn)) | L3_PROT;
     }
     return 0;
 
@@ -374,7 +374,7 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
                 goto pfn_error;
             l4off = l4_table_offset_x86_64(addr);
             l4tab[l4off] =
-                pfn_to_paddr(xc_dom_p2m_guest(dom, l3pfn)) | L4_PROT;
+                pfn_to_paddr(xc_dom_p2m(dom, l3pfn)) | L4_PROT;
             l3pfn++;
         }
 
@@ -386,7 +386,7 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
                 goto pfn_error;
             l3off = l3_table_offset_x86_64(addr);
             l3tab[l3off] =
-                pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
+                pfn_to_paddr(xc_dom_p2m(dom, l2pfn)) | L3_PROT;
             l2pfn++;
         }
 
@@ -398,7 +398,7 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
                 goto pfn_error;
             l2off = l2_table_offset_x86_64(addr);
             l2tab[l2off] =
-                pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
+                pfn_to_paddr(xc_dom_p2m(dom, l1pfn)) | L2_PROT;
             l1pfn++;
         }
 
@@ -406,7 +406,7 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
         l1off = l1_table_offset_x86_64(addr);
         pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86;
         l1tab[l1off] =
-            pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT;
+            pfn_to_paddr(xc_dom_p2m(dom, pgpfn)) | L1_PROT;
         if ( (!dom->pvh_enabled)                &&
              (addr >= dom->pgtables_seg.vstart) &&
              (addr < dom->pgtables_seg.vend) )
@@ -489,9 +489,9 @@ static int start_info_x86_32(struct xc_dom_image *dom)
     start_info->mfn_list = dom->p2m_seg.vstart;
 
     start_info->flags = dom->flags;
-    start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn);
+    start_info->store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn);
     start_info->store_evtchn = dom->xenstore_evtchn;
-    start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn);
+    start_info->console.domU.mfn = xc_dom_p2m(dom, dom->console_pfn);
     start_info->console.domU.evtchn = dom->console_evtchn;
 
     if ( dom->ramdisk_blob )
@@ -535,9 +535,9 @@ static int start_info_x86_64(struct xc_dom_image *dom)
     start_info->mfn_list = dom->p2m_seg.vstart;
 
     start_info->flags = dom->flags;
-    start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn);
+    start_info->store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn);
     start_info->store_evtchn = dom->xenstore_evtchn;
-    start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn);
+    start_info->console.domU.mfn = xc_dom_p2m(dom, dom->console_pfn);
     start_info->console.domU.evtchn = dom->console_evtchn;
 
     if ( dom->ramdisk_blob )
@@ -621,7 +621,7 @@ static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr)
          dom->parms.pae == 3 /* bimodal */ )
         ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
 
-    cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn);
+    cr3_pfn = xc_dom_p2m(dom, dom->pgtables_seg.pfn);
     ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_32(cr3_pfn);
     DOMPRINTF("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "",
               __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn);
@@ -647,7 +647,7 @@ static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr)
     ctxt->user_regs.rflags = 1 << 9; /* Interrupt Enable */
 
     ctxt->flags = VGCF_in_kernel_X86_64 | VGCF_online_X86_64;
-    cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn);
+    cr3_pfn = xc_dom_p2m(dom, dom->pgtables_seg.pfn);
     ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn);
     DOMPRINTF("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "",
               __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn);
@@ -1020,7 +1020,7 @@ int arch_setup_bootlate(struct xc_dom_image *dom)
         /* paravirtualized guest */
         xc_dom_unmap_one(dom, dom->pgtables_seg.pfn);
         rc = pin_table(dom->xch, pgd_type,
-                       xc_dom_p2m_host(dom, dom->pgtables_seg.pfn),
+                       xc_dom_p2m(dom, dom->pgtables_seg.pfn),
                        dom->guest_domid);
         if ( rc != 0 )
         {
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 38fb939..c1d0d8c 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -738,8 +738,8 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
         state->console_mfn = dom->console_pfn;
         state->store_mfn = dom->xenstore_pfn;
     } else {
-        state->console_mfn = xc_dom_p2m_host(dom, dom->console_pfn);
-        state->store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn);
+        state->console_mfn = xc_dom_p2m(dom, dom->console_pfn);
+        state->store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn);
     }
 
     libxl__file_reference_unmap(&state->pv_kernel);
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 04/31] libxc: introduce the notion of a container type
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (2 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 03/31] libxc: unify xc_dom_p2m_{host/guest} Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 05/31] libxc: introduce a domain loader for HVM guest firmware Roger Pau Monne
                   ` (26 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

Introduce the notion of a container type into xc_dom_image. This will be
needed by later changes that will also use xc_dom_image in order to build
HVM guests.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Changes since v3:
 - Add Andrew Cooper Reviewed-by.
 - Add Wei Acked-by.
---
 tools/libxc/include/xc_dom.h | 6 ++++++
 tools/libxc/xc_dom_x86.c     | 4 ++++
 tools/libxl/libxl_dom.c      | 1 +
 3 files changed, 11 insertions(+)

diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 9cf13e2..bc55ec9 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -179,6 +179,12 @@ struct xc_dom_image {
     struct xc_dom_arch *arch_hooks;
     /* allocate up to virt_alloc_end */
     int (*allocate) (struct xc_dom_image * dom, xen_vaddr_t up_to);
+
+    /* Container type (HVM or PV). */
+    enum {
+        XC_DOM_PV_CONTAINER,
+        XC_DOM_HVM_CONTAINER,
+    } container_type;
 };
 
 /* --- pluggable kernel loader ------------------------------------- */
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index dc2f4aa..c7bfc0c 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -1071,6 +1071,10 @@ int arch_setup_bootlate(struct xc_dom_image *dom)
 
 int xc_dom_feature_translated(struct xc_dom_image *dom)
 {
+    /* Guests running inside HVM containers are always auto-translated. */
+    if ( dom->container_type == XC_DOM_HVM_CONTAINER )
+        return 1;
+
     return elf_xen_feature_get(XENFEAT_auto_translated_physmap, dom->f_active);
 }
 
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index c1d0d8c..92c4278 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -619,6 +619,7 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
     }
 
     dom->pvh_enabled = state->pvh_enabled;
+    dom->container_type = XC_DOM_PV_CONTAINER;
 
     LOG(DEBUG, "pv kernel mapped %d path %s", state->pv_kernel.mapped, state->pv_kernel.path);
 
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 05/31] libxc: introduce a domain loader for HVM guest firmware
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (3 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 04/31] libxc: introduce the notion of a container type Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 06/31] libxc: make arch_setup_meminit a xc_dom_arch hook Roger Pau Monne
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

Introduce a very simple (and dummy) domain loader to be used to load the
firmware (hvmloader) into HVM guests. Since hmvloader is just a 32bit elf
executable the loader is fairly simple.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Changes since v3:
 - s/__FUNCTION__/__func__/g
 - Fix style errors in xc_dom_hvmloader.c.
 - Add Andrew Cooper Reviewed-by.
 - Add Wei Acked-by.
---
 tools/libxc/Makefile           |   1 +
 tools/libxc/include/xc_dom.h   |   8 ++
 tools/libxc/xc_dom_hvmloader.c | 313 +++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/libelf.h       |   1 +
 4 files changed, 323 insertions(+)
 create mode 100644 tools/libxc/xc_dom_hvmloader.c

diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index 8ae0ea0..b45380c 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -84,6 +84,7 @@ GUEST_SRCS-y                 += xc_dom_core.c xc_dom_boot.c
 GUEST_SRCS-y                 += xc_dom_elfloader.c
 GUEST_SRCS-$(CONFIG_X86)     += xc_dom_bzimageloader.c
 GUEST_SRCS-$(CONFIG_X86)     += xc_dom_decompress_lz4.c
+GUEST_SRCS-$(CONFIG_X86)     += xc_dom_hvmloader.c
 GUEST_SRCS-$(CONFIG_ARM)     += xc_dom_armzimageloader.c
 GUEST_SRCS-y                 += xc_dom_binloader.c
 GUEST_SRCS-y                 += xc_dom_compat_linux.c
diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index bc55ec9..02d9d5c 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -14,6 +14,7 @@
  */
 
 #include <xen/libelf/libelf.h>
+#include <xenguest.h>
 
 #define INVALID_P2M_ENTRY   ((xen_pfn_t)-1)
 
@@ -185,6 +186,13 @@ struct xc_dom_image {
         XC_DOM_PV_CONTAINER,
         XC_DOM_HVM_CONTAINER,
     } container_type;
+
+    /* HVM specific fields. */
+    /* Extra ACPI tables passed to HVMLOADER */
+    struct xc_hvm_firmware_module acpi_module;
+
+    /* Extra SMBIOS structures passed to HVMLOADER */
+    struct xc_hvm_firmware_module smbios_module;
 };
 
 /* --- pluggable kernel loader ------------------------------------- */
diff --git a/tools/libxc/xc_dom_hvmloader.c b/tools/libxc/xc_dom_hvmloader.c
new file mode 100644
index 0000000..79a3b99
--- /dev/null
+++ b/tools/libxc/xc_dom_hvmloader.c
@@ -0,0 +1,313 @@
+/*
+ * Xen domain builder -- HVM specific bits.
+ *
+ * Parse and load ELF firmware images for HVM domains.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#include "xg_private.h"
+#include "xc_dom.h"
+#include "xc_bitops.h"
+
+/* ------------------------------------------------------------------------ */
+/* parse elf binary                                                         */
+
+static elf_negerrnoval check_elf_kernel(struct xc_dom_image *dom, bool verbose)
+{
+    if ( dom->kernel_blob == NULL )
+    {
+        if ( verbose )
+            xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                         "%s: no kernel image loaded", __func__);
+        return -EINVAL;
+    }
+
+    if ( !elf_is_elfbinary(dom->kernel_blob, dom->kernel_size) )
+    {
+        if ( verbose )
+            xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
+                         "%s: kernel is not an ELF image", __func__);
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static elf_negerrnoval xc_dom_probe_hvm_kernel(struct xc_dom_image *dom)
+{
+    struct elf_binary elf;
+    int rc;
+
+    /* This loader is designed for HVM guest firmware. */
+    if ( dom->container_type != XC_DOM_HVM_CONTAINER )
+        return -EINVAL;
+
+    rc = check_elf_kernel(dom, 0);
+    if ( rc != 0 )
+        return rc;
+
+    rc = elf_init(&elf, dom->kernel_blob, dom->kernel_size);
+    if ( rc != 0 )
+        return rc;
+
+    /*
+     * We need to check that there are no Xen ELFNOTES, or
+     * else we might be trying to load a PV kernel.
+     */
+    elf_parse_binary(&elf);
+    rc = elf_xen_parse(&elf, &dom->parms);
+    if ( rc == 0 )
+        return -EINVAL;
+
+    return 0;
+}
+
+static elf_errorstatus xc_dom_parse_hvm_kernel(struct xc_dom_image *dom)
+    /*
+     * This function sometimes returns -1 for error and sometimes
+     * an errno value.  ?!?!
+     */
+{
+    struct elf_binary *elf;
+    elf_errorstatus rc;
+
+    rc = check_elf_kernel(dom, 1);
+    if ( rc != 0 )
+        return rc;
+
+    elf = xc_dom_malloc(dom, sizeof(*elf));
+    if ( elf == NULL )
+        return -1;
+    dom->private_loader = elf;
+    rc = elf_init(elf, dom->kernel_blob, dom->kernel_size);
+    xc_elf_set_logfile(dom->xch, elf, 1);
+    if ( rc != 0 )
+    {
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: corrupted ELF image",
+                     __func__);
+        return rc;
+    }
+
+    if ( !elf_32bit(elf) )
+    {
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image is not 32bit",
+                     __func__);
+        return -EINVAL;
+    }
+
+    /* parse binary and get xen meta info */
+    elf_parse_binary(elf);
+
+    /* find kernel segment */
+    dom->kernel_seg.vstart = elf->pstart;
+    dom->kernel_seg.vend   = elf->pend;
+
+    dom->guest_type = "hvm-3.0-x86_32";
+
+    if ( elf_check_broken(elf) )
+        DOMPRINTF("%s: ELF broken: %s", __func__, elf_check_broken(elf));
+
+    return rc;
+}
+
+static int modules_init(struct xc_dom_image *dom,
+                        uint64_t vend, struct elf_binary *elf,
+                        uint64_t *mstart_out, uint64_t *mend_out)
+{
+#define MODULE_ALIGN 1UL << 7
+#define MB_ALIGN     1UL << 20
+#define MKALIGN(x, a) (((uint64_t)(x) + (a) - 1) & ~(uint64_t)((a) - 1))
+    uint64_t total_len = 0, offset1 = 0;
+
+    if ( dom->acpi_module.length == 0 && dom->smbios_module.length == 0 )
+        return 0;
+
+    /* Find the total length for the firmware modules with a reasonable large
+     * alignment size to align each the modules.
+     */
+    total_len = MKALIGN(dom->acpi_module.length, MODULE_ALIGN);
+    offset1 = total_len;
+    total_len += MKALIGN(dom->smbios_module.length, MODULE_ALIGN);
+
+    /* Want to place the modules 1Mb+change behind the loader image. */
+    *mstart_out = MKALIGN(elf->pend, MB_ALIGN) + (MB_ALIGN);
+    *mend_out = *mstart_out + total_len;
+
+    if ( *mend_out > vend )
+        return -1;
+
+    if ( dom->acpi_module.length != 0 )
+        dom->acpi_module.guest_addr_out = *mstart_out;
+    if ( dom->smbios_module.length != 0 )
+        dom->smbios_module.guest_addr_out = *mstart_out + offset1;
+
+    return 0;
+}
+
+static int loadmodules(struct xc_dom_image *dom,
+                       uint64_t mstart, uint64_t mend,
+                       uint32_t domid)
+{
+    privcmd_mmap_entry_t *entries = NULL;
+    unsigned long pfn_start;
+    unsigned long pfn_end;
+    size_t pages;
+    uint32_t i;
+    uint8_t *dest;
+    int rc = -1;
+    xc_interface *xch = dom->xch;
+
+    if ( mstart == 0 || mend == 0 )
+        return 0;
+
+    pfn_start = (unsigned long)(mstart >> PAGE_SHIFT);
+    pfn_end = (unsigned long)((mend + PAGE_SIZE - 1) >> PAGE_SHIFT);
+    pages = pfn_end - pfn_start;
+
+    /* Map address space for module list. */
+    entries = calloc(pages, sizeof(privcmd_mmap_entry_t));
+    if ( entries == NULL )
+        goto error_out;
+
+    for ( i = 0; i < pages; i++ )
+        entries[i].mfn = (mstart >> PAGE_SHIFT) + i;
+
+    dest = xc_map_foreign_ranges(
+        xch, domid, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT,
+        entries, pages);
+    if ( dest == NULL )
+        goto error_out;
+
+    /* Zero the range so padding is clear between modules */
+    memset(dest, 0, pages << PAGE_SHIFT);
+
+    /* Load modules into range */
+    if ( dom->acpi_module.length != 0 )
+    {
+        memcpy(dest,
+               dom->acpi_module.data,
+               dom->acpi_module.length);
+    }
+    if ( dom->smbios_module.length != 0 )
+    {
+        memcpy(dest + (dom->smbios_module.guest_addr_out - mstart),
+               dom->smbios_module.data,
+               dom->smbios_module.length);
+    }
+
+    munmap(dest, pages << PAGE_SHIFT);
+    rc = 0;
+
+ error_out:
+    free(entries);
+
+    return rc;
+}
+
+static elf_errorstatus xc_dom_load_hvm_kernel(struct xc_dom_image *dom)
+{
+    struct elf_binary *elf = dom->private_loader;
+    privcmd_mmap_entry_t *entries = NULL;
+    size_t pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT;
+    elf_errorstatus rc;
+    uint64_t m_start = 0, m_end = 0;
+    int i;
+
+    /* Map address space for initial elf image. */
+    entries = calloc(pages, sizeof(privcmd_mmap_entry_t));
+    if ( entries == NULL )
+        return -ENOMEM;
+
+    for ( i = 0; i < pages; i++ )
+        entries[i].mfn = (elf->pstart >> PAGE_SHIFT) + i;
+
+    elf->dest_base = xc_map_foreign_ranges(
+        dom->xch, dom->guest_domid, pages << PAGE_SHIFT,
+        PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT,
+        entries, pages);
+    if ( elf->dest_base == NULL )
+    {
+        DOMPRINTF("%s: unable to map guest memory space", __func__);
+        rc = -EFAULT;
+        goto error;
+    }
+
+    elf->dest_size = pages * XC_DOM_PAGE_SIZE(dom);
+
+    rc = elf_load_binary(elf);
+    if ( rc < 0 )
+    {
+        DOMPRINTF("%s: failed to load elf binary", __func__);
+        return rc;
+    }
+
+    munmap(elf->dest_base, elf->dest_size);
+
+    rc = modules_init(dom, dom->total_pages << PAGE_SHIFT, elf, &m_start,
+                      &m_end);
+    if ( rc != 0 )
+    {
+        DOMPRINTF("%s: insufficient space to load modules.", __func__);
+        return rc;
+    }
+
+    rc = loadmodules(dom, m_start, m_end, dom->guest_domid);
+    if ( rc != 0 )
+    {
+        DOMPRINTF("%s: unable to load modules.", __func__);
+        return rc;
+    }
+
+    dom->parms.phys_entry = elf_uval(elf, elf->ehdr, e_entry);
+
+    free(entries);
+    return 0;
+
+ error:
+    assert(rc != 0);
+    free(entries);
+    return rc;
+}
+
+/* ------------------------------------------------------------------------ */
+
+struct xc_dom_loader hvm_loader = {
+    .name = "HVM-generic",
+    .probe = xc_dom_probe_hvm_kernel,
+    .parser = xc_dom_parse_hvm_kernel,
+    .loader = xc_dom_load_hvm_kernel,
+};
+
+static void __init register_loader(void)
+{
+    xc_dom_register_loader(&hvm_loader);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
index 6393040..03d449e 100644
--- a/xen/include/xen/libelf.h
+++ b/xen/include/xen/libelf.h
@@ -424,6 +424,7 @@ struct elf_dom_parms {
     uint64_t elf_paddr_offset;
     uint32_t f_supported[XENFEAT_NR_SUBMAPS];
     uint32_t f_required[XENFEAT_NR_SUBMAPS];
+    uint32_t phys_entry;
 
     /* calculated */
     uint64_t virt_offset;
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 06/31] libxc: make arch_setup_meminit a xc_dom_arch hook
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (4 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 05/31] libxc: introduce a domain loader for HVM guest firmware Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 07/31] libxc: make arch_setup_boot{init/late} xc_dom_arch hooks Roger Pau Monne
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

This allows having different arch_setup_meminit implementations based on the
guest type. It should not introduce any functional changes.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Changes since v3:
 - Add Andrew Cooper Reviewed-by.
 - Move xc_dom_arch definitions to the end of the xc_dom_<arch>.c files in
   order to reduce the spurious diffs in the comming patches.
 - Add Wei Acked-by.
---
 tools/libxc/include/xc_dom.h |  4 ++-
 tools/libxc/xc_dom_arm.c     | 70 +++++++++++++++++++++++--------------------
 tools/libxc/xc_dom_boot.c    |  2 +-
 tools/libxc/xc_dom_x86.c     | 71 +++++++++++++++++++++++---------------------
 4 files changed, 78 insertions(+), 69 deletions(-)

diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 02d9d5c..c4b994f 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -223,6 +223,9 @@ struct xc_dom_arch {
     int (*shared_info) (struct xc_dom_image * dom, void *shared_info);
     int (*vcpu) (struct xc_dom_image * dom, void *vcpu_ctxt);
 
+    /* arch-specific memory initialization. */
+    int (*meminit) (struct xc_dom_image * dom);
+
     char *guest_type;
     char *native_protocol;
     int page_shift;
@@ -400,7 +403,6 @@ static inline xen_pfn_t xc_dom_p2m(struct xc_dom_image *dom, xen_pfn_t pfn)
 
 /* --- arch bits --------------------------------------------------- */
 
-int arch_setup_meminit(struct xc_dom_image *dom);
 int arch_setup_bootearly(struct xc_dom_image *dom);
 int arch_setup_bootlate(struct xc_dom_image *dom);
 
diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index b00d667..24776ba 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -194,38 +194,6 @@ static int vcpu_arm64(struct xc_dom_image *dom, void *ptr)
 
 /* ------------------------------------------------------------------------ */
 
-static struct xc_dom_arch xc_dom_32 = {
-    .guest_type = "xen-3.0-armv7l",
-    .native_protocol = XEN_IO_PROTO_ABI_ARM,
-    .page_shift = PAGE_SHIFT_ARM,
-    .sizeof_pfn = 8,
-    .alloc_magic_pages = alloc_magic_pages,
-    .count_pgtables = count_pgtables_arm,
-    .setup_pgtables = setup_pgtables_arm,
-    .start_info = start_info_arm,
-    .shared_info = shared_info_arm,
-    .vcpu = vcpu_arm32,
-};
-
-static struct xc_dom_arch xc_dom_64 = {
-    .guest_type = "xen-3.0-aarch64",
-    .native_protocol = XEN_IO_PROTO_ABI_ARM,
-    .page_shift = PAGE_SHIFT_ARM,
-    .sizeof_pfn = 8,
-    .alloc_magic_pages = alloc_magic_pages,
-    .count_pgtables = count_pgtables_arm,
-    .setup_pgtables = setup_pgtables_arm,
-    .start_info = start_info_arm,
-    .shared_info = shared_info_arm,
-    .vcpu = vcpu_arm64,
-};
-
-static void __init register_arch_hooks(void)
-{
-    xc_dom_register_arch_hooks(&xc_dom_32);
-    xc_dom_register_arch_hooks(&xc_dom_64);
-}
-
 static int set_mode(xc_interface *xch, domid_t domid, char *guest_type)
 {
     static const struct {
@@ -384,7 +352,7 @@ out:
     return rc < 0 ? rc : 0;
 }
 
-int arch_setup_meminit(struct xc_dom_image *dom)
+static int meminit(struct xc_dom_image *dom)
 {
     int i, rc;
     xen_pfn_t pfn;
@@ -542,6 +510,42 @@ int xc_dom_feature_translated(struct xc_dom_image *dom)
     return 1;
 }
 
+/* ------------------------------------------------------------------------ */
+
+static struct xc_dom_arch xc_dom_32 = {
+    .guest_type = "xen-3.0-armv7l",
+    .native_protocol = XEN_IO_PROTO_ABI_ARM,
+    .page_shift = PAGE_SHIFT_ARM,
+    .sizeof_pfn = 8,
+    .alloc_magic_pages = alloc_magic_pages,
+    .count_pgtables = count_pgtables_arm,
+    .setup_pgtables = setup_pgtables_arm,
+    .start_info = start_info_arm,
+    .shared_info = shared_info_arm,
+    .vcpu = vcpu_arm32,
+    .meminit = meminit,
+};
+
+static struct xc_dom_arch xc_dom_64 = {
+    .guest_type = "xen-3.0-aarch64",
+    .native_protocol = XEN_IO_PROTO_ABI_ARM,
+    .page_shift = PAGE_SHIFT_ARM,
+    .sizeof_pfn = 8,
+    .alloc_magic_pages = alloc_magic_pages,
+    .count_pgtables = count_pgtables_arm,
+    .setup_pgtables = setup_pgtables_arm,
+    .start_info = start_info_arm,
+    .shared_info = shared_info_arm,
+    .vcpu = vcpu_arm64,
+    .meminit = meminit,
+};
+
+static void __init register_arch_hooks(void)
+{
+    xc_dom_register_arch_hooks(&xc_dom_32);
+    xc_dom_register_arch_hooks(&xc_dom_64);
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index 7c30f96..bf2cd7b 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -146,7 +146,7 @@ int xc_dom_boot_mem_init(struct xc_dom_image *dom)
 
     DOMPRINTF_CALLED(dom->xch);
 
-    rc = arch_setup_meminit(dom);
+    rc = dom->arch_hooks->meminit(dom);
     if ( rc != 0 )
     {
         xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index c7bfc0c..07170c1 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -670,38 +670,6 @@ static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr)
 
 /* ------------------------------------------------------------------------ */
 
-static struct xc_dom_arch xc_dom_32_pae = {
-    .guest_type = "xen-3.0-x86_32p",
-    .native_protocol = XEN_IO_PROTO_ABI_X86_32,
-    .page_shift = PAGE_SHIFT_X86,
-    .sizeof_pfn = 4,
-    .alloc_magic_pages = alloc_magic_pages,
-    .count_pgtables = count_pgtables_x86_32_pae,
-    .setup_pgtables = setup_pgtables_x86_32_pae,
-    .start_info = start_info_x86_32,
-    .shared_info = shared_info_x86_32,
-    .vcpu = vcpu_x86_32,
-};
-
-static struct xc_dom_arch xc_dom_64 = {
-    .guest_type = "xen-3.0-x86_64",
-    .native_protocol = XEN_IO_PROTO_ABI_X86_64,
-    .page_shift = PAGE_SHIFT_X86,
-    .sizeof_pfn = 8,
-    .alloc_magic_pages = alloc_magic_pages,
-    .count_pgtables = count_pgtables_x86_64,
-    .setup_pgtables = setup_pgtables_x86_64,
-    .start_info = start_info_x86_64,
-    .shared_info = shared_info_x86_64,
-    .vcpu = vcpu_x86_64,
-};
-
-static void __init register_arch_hooks(void)
-{
-    xc_dom_register_arch_hooks(&xc_dom_32_pae);
-    xc_dom_register_arch_hooks(&xc_dom_64);
-}
-
 static int x86_compat(xc_interface *xch, domid_t domid, char *guest_type)
 {
     static const struct {
@@ -733,7 +701,6 @@ static int x86_compat(xc_interface *xch, domid_t domid, char *guest_type)
     return rc;
 }
 
-
 static int x86_shadow(xc_interface *xch, domid_t domid)
 {
     int rc, mode;
@@ -757,7 +724,7 @@ static int x86_shadow(xc_interface *xch, domid_t domid)
     return rc;
 }
 
-int arch_setup_meminit(struct xc_dom_image *dom)
+static int meminit_pv(struct xc_dom_image *dom)
 {
     int rc;
     xen_pfn_t pfn, allocsz, mfn, total, pfn_base;
@@ -1078,6 +1045,42 @@ int xc_dom_feature_translated(struct xc_dom_image *dom)
     return elf_xen_feature_get(XENFEAT_auto_translated_physmap, dom->f_active);
 }
 
+/* ------------------------------------------------------------------------ */
+
+static struct xc_dom_arch xc_dom_32_pae = {
+    .guest_type = "xen-3.0-x86_32p",
+    .native_protocol = XEN_IO_PROTO_ABI_X86_32,
+    .page_shift = PAGE_SHIFT_X86,
+    .sizeof_pfn = 4,
+    .alloc_magic_pages = alloc_magic_pages,
+    .count_pgtables = count_pgtables_x86_32_pae,
+    .setup_pgtables = setup_pgtables_x86_32_pae,
+    .start_info = start_info_x86_32,
+    .shared_info = shared_info_x86_32,
+    .vcpu = vcpu_x86_32,
+    .meminit = meminit_pv,
+};
+
+static struct xc_dom_arch xc_dom_64 = {
+    .guest_type = "xen-3.0-x86_64",
+    .native_protocol = XEN_IO_PROTO_ABI_X86_64,
+    .page_shift = PAGE_SHIFT_X86,
+    .sizeof_pfn = 8,
+    .alloc_magic_pages = alloc_magic_pages,
+    .count_pgtables = count_pgtables_x86_64,
+    .setup_pgtables = setup_pgtables_x86_64,
+    .start_info = start_info_x86_64,
+    .shared_info = shared_info_x86_64,
+    .vcpu = vcpu_x86_64,
+    .meminit = meminit_pv,
+};
+
+static void __init register_arch_hooks(void)
+{
+    xc_dom_register_arch_hooks(&xc_dom_32_pae);
+    xc_dom_register_arch_hooks(&xc_dom_64);
+}
+
 /*
  * Local variables:
  * mode: C
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 07/31] libxc: make arch_setup_boot{init/late} xc_dom_arch hooks
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (5 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 06/31] libxc: make arch_setup_meminit a xc_dom_arch hook Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 08/31] libxc: rework BSP initialization Roger Pau Monne
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

This should not introduce any functional change.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Changes since v3:
 - Add Andrew Cooper Reviewed-by.
 - Add Wei Acked-by.
---
 tools/libxc/include/xc_dom.h |  7 ++-----
 tools/libxc/xc_dom_arm.c     | 20 +++++++++++++-------
 tools/libxc/xc_dom_boot.c    |  4 ++--
 tools/libxc/xc_dom_x86.c     | 10 ++++++++--
 4 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index c4b994f..5c1bb0f 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -222,6 +222,8 @@ struct xc_dom_arch {
     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, void *vcpu_ctxt);
+    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);
@@ -401,11 +403,6 @@ static inline xen_pfn_t xc_dom_p2m(struct xc_dom_image *dom, xen_pfn_t pfn)
     return dom->p2m_host[pfn - dom->rambase_pfn];
 }
 
-/* --- arch bits --------------------------------------------------- */
-
-int arch_setup_bootearly(struct xc_dom_image *dom);
-int arch_setup_bootlate(struct xc_dom_image *dom);
-
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index 24776ba..7548dae 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -489,13 +489,20 @@ static int meminit(struct xc_dom_image *dom)
     return 0;
 }
 
-int arch_setup_bootearly(struct xc_dom_image *dom)
+int xc_dom_feature_translated(struct xc_dom_image *dom)
+{
+    return 1;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int bootearly(struct xc_dom_image *dom)
 {
     DOMPRINTF("%s: doing nothing", __FUNCTION__);
     return 0;
 }
 
-int arch_setup_bootlate(struct xc_dom_image *dom)
+static int bootlate(struct xc_dom_image *dom)
 {
     /* XXX
      *   map shared info
@@ -505,11 +512,6 @@ int arch_setup_bootlate(struct xc_dom_image *dom)
     return 0;
 }
 
-int xc_dom_feature_translated(struct xc_dom_image *dom)
-{
-    return 1;
-}
-
 /* ------------------------------------------------------------------------ */
 
 static struct xc_dom_arch xc_dom_32 = {
@@ -524,6 +526,8 @@ static struct xc_dom_arch xc_dom_32 = {
     .shared_info = shared_info_arm,
     .vcpu = vcpu_arm32,
     .meminit = meminit,
+    .bootearly = bootearly,
+    .bootlate = bootlate,
 };
 
 static struct xc_dom_arch xc_dom_64 = {
@@ -538,6 +542,8 @@ static struct xc_dom_arch xc_dom_64 = {
     .shared_info = shared_info_arm,
     .vcpu = vcpu_arm64,
     .meminit = meminit,
+    .bootearly = bootearly,
+    .bootlate = bootlate,
 };
 
 static void __init register_arch_hooks(void)
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index bf2cd7b..e6f7794 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -208,7 +208,7 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
     DOMPRINTF_CALLED(dom->xch);
 
     /* misc stuff*/
-    if ( (rc = arch_setup_bootearly(dom)) != 0 )
+    if ( (rc = dom->arch_hooks->bootearly(dom)) != 0 )
         return rc;
 
     /* collect some info */
@@ -255,7 +255,7 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
     xc_dom_log_memory_footprint(dom);
 
     /* misc x86 stuff */
-    if ( (rc = arch_setup_bootlate(dom)) != 0 )
+    if ( (rc = dom->arch_hooks->bootlate(dom)) != 0 )
         return rc;
 
     /* let the vm run */
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 07170c1..0f49e27 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -924,7 +924,9 @@ static int meminit_pv(struct xc_dom_image *dom)
     return rc;
 }
 
-int arch_setup_bootearly(struct xc_dom_image *dom)
+/* ------------------------------------------------------------------------ */
+
+static int bootearly(struct xc_dom_image *dom)
 {
     DOMPRINTF("%s: doing nothing", __FUNCTION__);
     return 0;
@@ -963,7 +965,7 @@ static int map_grant_table_frames(struct xc_dom_image *dom)
     return 0;
 }
 
-int arch_setup_bootlate(struct xc_dom_image *dom)
+static int bootlate_pv(struct xc_dom_image *dom)
 {
     static const struct {
         char *guest;
@@ -1059,6 +1061,8 @@ static struct xc_dom_arch xc_dom_32_pae = {
     .shared_info = shared_info_x86_32,
     .vcpu = vcpu_x86_32,
     .meminit = meminit_pv,
+    .bootearly = bootearly,
+    .bootlate = bootlate_pv,
 };
 
 static struct xc_dom_arch xc_dom_64 = {
@@ -1073,6 +1077,8 @@ static struct xc_dom_arch xc_dom_64 = {
     .shared_info = shared_info_x86_64,
     .vcpu = vcpu_x86_64,
     .meminit = meminit_pv,
+    .bootearly = bootearly,
+    .bootlate = bootlate_pv,
 };
 
 static void __init register_arch_hooks(void)
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 08/31] libxc: rework BSP initialization
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (6 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 07/31] libxc: make arch_setup_boot{init/late} xc_dom_arch hooks Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 11:31   ` Wei Liu
  2015-08-07 15:22   ` Andrew Cooper
  2015-08-07 10:17 ` [PATCH v4 09/31] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests Roger Pau Monne
                   ` (22 subsequent siblings)
  30 siblings, 2 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

Place the calls to xc_vcpu_setcontext and the allocation of the hypercall
buffer into the arch-specific vcpu hooks. This is needed for the next patch,
so x86 HVM guests can initialize the BSP using XEN_DOMCTL_sethvmcontext
instead of XEN_DOMCTL_setvcpucontext.

This patch should not introduce any functional change.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxc/include/xc_dom.h |  2 +-
 tools/libxc/xc_dom_arm.c     | 22 +++++++++++++++++-----
 tools/libxc/xc_dom_boot.c    | 23 +----------------------
 tools/libxc/xc_dom_x86.c     | 26 ++++++++++++++++++++------
 4 files changed, 39 insertions(+), 34 deletions(-)

diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 5c1bb0f..0245d24 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -221,7 +221,7 @@ struct xc_dom_arch {
     /* arch-specific data structs setup */
     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, void *vcpu_ctxt);
+    int (*vcpu) (struct xc_dom_image * dom);
     int (*bootearly) (struct xc_dom_image * dom);
     int (*bootlate) (struct xc_dom_image * dom);
 
diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index 7548dae..8865097 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -119,9 +119,10 @@ static int shared_info_arm(struct xc_dom_image *dom, void *ptr)
 
 /* ------------------------------------------------------------------------ */
 
-static int vcpu_arm32(struct xc_dom_image *dom, void *ptr)
+static int vcpu_arm32(struct xc_dom_image *dom)
 {
-    vcpu_guest_context_t *ctxt = ptr;
+    vcpu_guest_context_any_t any_ctx;
+    vcpu_guest_context_t *ctxt = &any_ctx.c;
 
     DOMPRINTF_CALLED(dom->xch);
 
@@ -154,12 +155,18 @@ static int vcpu_arm32(struct xc_dom_image *dom, void *ptr)
     DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32,
            ctxt->user_regs.cpsr, ctxt->user_regs.pc32);
 
-    return 0;
+    rc = xc_vcpu_setcontext(dom->xch, dom->guest_domid, 0, &any_ctx);
+    if ( rc != 0 )
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: SETVCPUCONTEXT failed (rc=%d)", __func__, rc);
+
+    return rc;
 }
 
-static int vcpu_arm64(struct xc_dom_image *dom, void *ptr)
+static int vcpu_arm64(struct xc_dom_image *dom)
 {
-    vcpu_guest_context_t *ctxt = ptr;
+    vcpu_guest_context_any_t any_ctx;
+    vcpu_guest_context_t *ctxt = &any_ctx.c;
 
     DOMPRINTF_CALLED(dom->xch);
     /* clear everything */
@@ -189,6 +196,11 @@ static int vcpu_arm64(struct xc_dom_image *dom, void *ptr)
     DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx64,
            ctxt->user_regs.cpsr, ctxt->user_regs.pc64);
 
+    rc = xc_vcpu_setcontext(dom->xch, dom->guest_domid, 0, &any_ctx);
+    if ( rc != 0 )
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: SETVCPUCONTEXT failed (rc=%d)", __func__, rc);
+
     return 0;
 }
 
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index e6f7794..791041b 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -62,19 +62,6 @@ static int setup_hypercall_page(struct xc_dom_image *dom)
     return rc;
 }
 
-static int launch_vm(xc_interface *xch, domid_t domid,
-                     vcpu_guest_context_any_t *ctxt)
-{
-    int rc;
-
-    xc_dom_printf(xch, "%s: called, ctxt=%p", __FUNCTION__, ctxt);
-    rc = xc_vcpu_setcontext(xch, domid, 0, ctxt);
-    if ( rc != 0 )
-        xc_dom_panic(xch, XC_INTERNAL_ERROR,
-                     "%s: SETVCPUCONTEXT failed (rc=%d)", __FUNCTION__, rc);
-    return rc;
-}
-
 static int clear_page(struct xc_dom_image *dom, xen_pfn_t pfn)
 {
     xen_pfn_t dst;
@@ -197,14 +184,9 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn,
 
 int xc_dom_boot_image(struct xc_dom_image *dom)
 {
-    DECLARE_HYPERCALL_BUFFER(vcpu_guest_context_any_t, ctxt);
     xc_dominfo_t info;
     int rc;
 
-    ctxt = xc_hypercall_buffer_alloc(dom->xch, ctxt, sizeof(*ctxt));
-    if ( ctxt == NULL )
-        return -1;
-
     DOMPRINTF_CALLED(dom->xch);
 
     /* misc stuff*/
@@ -259,13 +241,10 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
         return rc;
 
     /* let the vm run */
-    memset(ctxt, 0, sizeof(*ctxt));
-    if ( (rc = dom->arch_hooks->vcpu(dom, ctxt)) != 0 )
+    if ( (rc = dom->arch_hooks->vcpu(dom)) != 0 )
         return rc;
     xc_dom_unmap_all(dom);
-    rc = launch_vm(dom->xch, dom->guest_domid, ctxt);
 
-    xc_hypercall_buffer_free(dom->xch, ctxt);
     return rc;
 }
 
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 0f49e27..ae8187f 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -583,10 +583,12 @@ static int shared_info_x86_64(struct xc_dom_image *dom, void *ptr)
 
 /* ------------------------------------------------------------------------ */
 
-static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr)
+static int vcpu_x86_32(struct xc_dom_image *dom)
 {
-    vcpu_guest_context_x86_32_t *ctxt = ptr;
+    vcpu_guest_context_any_t any_ctx;
+    vcpu_guest_context_x86_32_t *ctxt = &any_ctx.x32;
     xen_pfn_t cr3_pfn;
+    int rc;
 
     DOMPRINTF_CALLED(dom->xch);
 
@@ -626,13 +628,20 @@ static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr)
     DOMPRINTF("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "",
               __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn);
 
-    return 0;
+    rc = xc_vcpu_setcontext(dom->xch, dom->guest_domid, 0, &any_ctx);
+    if ( rc != 0 )
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: SETVCPUCONTEXT failed (rc=%d)", __func__, rc);
+
+    return rc;
 }
 
-static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr)
+static int vcpu_x86_64(struct xc_dom_image *dom)
 {
-    vcpu_guest_context_x86_64_t *ctxt = ptr;
+    vcpu_guest_context_any_t any_ctx;
+    vcpu_guest_context_x86_64_t *ctxt = &any_ctx.x64;
     xen_pfn_t cr3_pfn;
+    int rc;
 
     DOMPRINTF_CALLED(dom->xch);
 
@@ -665,7 +674,12 @@ static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr)
     ctxt->kernel_ss = ctxt->user_regs.ss;
     ctxt->kernel_sp = ctxt->user_regs.esp;
 
-    return 0;
+    rc = xc_vcpu_setcontext(dom->xch, dom->guest_domid, 0, &any_ctx);
+    if ( rc != 0 )
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: SETVCPUCONTEXT failed (rc=%d)", __func__, rc);
+
+    return rc;
 }
 
 /* ------------------------------------------------------------------------ */
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 09/31] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (7 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 08/31] libxc: rework BSP initialization Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 12:00   ` Wei Liu
  2015-08-07 15:58   ` Andrew Cooper
  2015-08-07 10:17 ` [PATCH v4 10/31] libxl: switch HVM domain building to use xc_dom_* helpers Roger Pau Monne
                   ` (21 subsequent siblings)
  30 siblings, 2 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

This xc_dom_arch will be used in order to build HVM domains. The code is
based on the existing xc_hvm_populate_memory and xc_hvm_populate_params
functions.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Changes since v3:
 - Make sure c/s b9dbe33 is not reverted on this patch.
 - Set the initial BSP state using {get/set}hvmcontext.
---
 tools/libxc/include/xc_dom.h |   6 +
 tools/libxc/xc_dom_x86.c     | 619 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 614 insertions(+), 11 deletions(-)

diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 0245d24..cda40d9 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -188,6 +188,12 @@ struct xc_dom_image {
     } container_type;
 
     /* HVM specific fields. */
+    xen_pfn_t target_pages;
+    xen_pfn_t mmio_start;
+    xen_pfn_t mmio_size;
+    xen_pfn_t lowmem_end;
+    xen_pfn_t highmem_end;
+
     /* Extra ACPI tables passed to HVMLOADER */
     struct xc_hvm_firmware_module acpi_module;
 
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index ae8187f..18e3340 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -39,10 +39,32 @@
 
 /* ------------------------------------------------------------------------ */
 
-#define SUPERPAGE_PFN_SHIFT  9
-#define SUPERPAGE_NR_PFNS    (1UL << SUPERPAGE_PFN_SHIFT)
 #define SUPERPAGE_BATCH_SIZE 512
 
+#define SUPERPAGE_2MB_SHIFT   9
+#define SUPERPAGE_2MB_NR_PFNS (1UL << SUPERPAGE_2MB_SHIFT)
+#define SUPERPAGE_1GB_SHIFT   18
+#define SUPERPAGE_1GB_NR_PFNS (1UL << SUPERPAGE_1GB_SHIFT)
+
+#define X86_CR0_PE 0x01
+#define X86_CR0_ET 0x10
+
+#define VGA_HOLE_SIZE (0x20)
+
+#define SPECIALPAGE_PAGING   0
+#define SPECIALPAGE_ACCESS   1
+#define SPECIALPAGE_SHARING  2
+#define SPECIALPAGE_BUFIOREQ 3
+#define SPECIALPAGE_XENSTORE 4
+#define SPECIALPAGE_IOREQ    5
+#define SPECIALPAGE_IDENT_PT 6
+#define SPECIALPAGE_CONSOLE  7
+#define NR_SPECIAL_PAGES     8
+#define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x))
+
+#define NR_IOREQ_SERVER_PAGES 8
+#define ioreq_server_pfn(x) (special_pfn(0) - NR_IOREQ_SERVER_PAGES + (x))
+
 #define bits_to_mask(bits)       (((xen_vaddr_t)1 << (bits))-1)
 #define round_down(addr, mask)   ((addr) & ~(mask))
 #define round_up(addr, mask)     ((addr) | (mask))
@@ -461,6 +483,135 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
     return 0;
 }
 
+static void build_hvm_info(void *hvm_info_page, struct xc_dom_image *dom)
+{
+    struct hvm_info_table *hvm_info = (struct hvm_info_table *)
+        (((unsigned char *)hvm_info_page) + HVM_INFO_OFFSET);
+    uint8_t sum;
+    int i;
+
+    memset(hvm_info_page, 0, PAGE_SIZE);
+
+    /* Fill in the header. */
+    memcpy(hvm_info->signature, "HVM INFO", sizeof(hvm_info->signature));
+    hvm_info->length = sizeof(struct hvm_info_table);
+
+    /* Sensible defaults: these can be overridden by the caller. */
+    hvm_info->apic_mode = 1;
+    hvm_info->nr_vcpus = 1;
+    memset(hvm_info->vcpu_online, 0xff, sizeof(hvm_info->vcpu_online));
+
+    /* Memory parameters. */
+    hvm_info->low_mem_pgend = dom->lowmem_end >> PAGE_SHIFT;
+    hvm_info->high_mem_pgend = dom->highmem_end >> PAGE_SHIFT;
+    hvm_info->reserved_mem_pgstart = ioreq_server_pfn(0);
+
+    /* Finish with the checksum. */
+    for ( i = 0, sum = 0; i < hvm_info->length; i++ )
+        sum += ((uint8_t *)hvm_info)[i];
+    hvm_info->checksum = -sum;
+}
+
+static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
+{
+    unsigned long i;
+    void *hvm_info_page;
+    uint32_t *ident_pt, domid = dom->guest_domid;
+    int rc;
+    xen_pfn_t special_array[NR_SPECIAL_PAGES];
+    xen_pfn_t ioreq_server_array[NR_IOREQ_SERVER_PAGES];
+    xc_interface *xch = dom->xch;
+
+    if ( (hvm_info_page = xc_map_foreign_range(
+              xch, domid, PAGE_SIZE, PROT_READ | PROT_WRITE,
+              HVM_INFO_PFN)) == NULL )
+        goto error_out;
+    build_hvm_info(hvm_info_page, dom);
+    munmap(hvm_info_page, PAGE_SIZE);
+
+    /* Allocate and clear special pages. */
+    for ( i = 0; i < NR_SPECIAL_PAGES; i++ )
+        special_array[i] = special_pfn(i);
+
+    rc = xc_domain_populate_physmap_exact(xch, domid, NR_SPECIAL_PAGES, 0, 0,
+                                          special_array);
+    if ( rc != 0 )
+    {
+        DOMPRINTF("Could not allocate special pages.");
+        goto error_out;
+    }
+
+    if ( xc_clear_domain_pages(xch, domid, special_pfn(0), NR_SPECIAL_PAGES) )
+            goto error_out;
+
+    xc_hvm_param_set(xch, domid, HVM_PARAM_STORE_PFN,
+                     special_pfn(SPECIALPAGE_XENSTORE));
+    xc_hvm_param_set(xch, domid, HVM_PARAM_BUFIOREQ_PFN,
+                     special_pfn(SPECIALPAGE_BUFIOREQ));
+    xc_hvm_param_set(xch, domid, HVM_PARAM_IOREQ_PFN,
+                     special_pfn(SPECIALPAGE_IOREQ));
+    xc_hvm_param_set(xch, domid, HVM_PARAM_CONSOLE_PFN,
+                     special_pfn(SPECIALPAGE_CONSOLE));
+    xc_hvm_param_set(xch, domid, HVM_PARAM_PAGING_RING_PFN,
+                     special_pfn(SPECIALPAGE_PAGING));
+    xc_hvm_param_set(xch, domid, HVM_PARAM_MONITOR_RING_PFN,
+                     special_pfn(SPECIALPAGE_ACCESS));
+    xc_hvm_param_set(xch, domid, HVM_PARAM_SHARING_RING_PFN,
+                     special_pfn(SPECIALPAGE_SHARING));
+
+    /*
+     * Allocate and clear additional ioreq server pages. The default
+     * server will use the IOREQ and BUFIOREQ special pages above.
+     */
+    for ( i = 0; i < NR_IOREQ_SERVER_PAGES; i++ )
+        ioreq_server_array[i] = ioreq_server_pfn(i);
+
+    rc = xc_domain_populate_physmap_exact(xch, domid, NR_IOREQ_SERVER_PAGES, 0,
+                                          0, ioreq_server_array);
+    if ( rc != 0 )
+    {
+        DOMPRINTF("Could not allocate ioreq server pages.");
+        goto error_out;
+    }
+
+    if ( xc_clear_domain_pages(xch, domid, ioreq_server_pfn(0),
+                               NR_IOREQ_SERVER_PAGES) )
+            goto error_out;
+
+    /* Tell the domain where the pages are and how many there are */
+    xc_hvm_param_set(xch, domid, HVM_PARAM_IOREQ_SERVER_PFN,
+                     ioreq_server_pfn(0));
+    xc_hvm_param_set(xch, domid, HVM_PARAM_NR_IOREQ_SERVER_PAGES,
+                     NR_IOREQ_SERVER_PAGES);
+
+    /*
+     * Identity-map page table is required for running with CR0.PG=0 when
+     * using Intel EPT. Create a 32-bit non-PAE page directory of superpages.
+     */
+    if ( (ident_pt = xc_map_foreign_range(
+              xch, domid, PAGE_SIZE, PROT_READ | PROT_WRITE,
+              special_pfn(SPECIALPAGE_IDENT_PT))) == NULL )
+        goto error_out;
+    for ( i = 0; i < PAGE_SIZE / sizeof(*ident_pt); i++ )
+        ident_pt[i] = ((i << 22) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER |
+                       _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE);
+    munmap(ident_pt, PAGE_SIZE);
+    xc_hvm_param_set(xch, domid, HVM_PARAM_IDENT_PT,
+                     special_pfn(SPECIALPAGE_IDENT_PT) << PAGE_SHIFT);
+
+    dom->console_pfn = special_pfn(SPECIALPAGE_CONSOLE);
+    dom->xenstore_pfn = special_pfn(SPECIALPAGE_XENSTORE);
+    dom->parms.virt_hypercall = -1;
+
+    rc = 0;
+    goto out;
+ error_out:
+    rc = -1;
+ out:
+
+    return rc;
+}
+
 /* ------------------------------------------------------------------------ */
 
 static int start_info_x86_32(struct xc_dom_image *dom)
@@ -682,6 +833,103 @@ static int vcpu_x86_64(struct xc_dom_image *dom)
     return rc;
 }
 
+static int vcpu_hvm(struct xc_dom_image *dom)
+{
+    struct {
+        struct hvm_save_descriptor header_d;
+        HVM_SAVE_TYPE(HEADER) header;
+        struct hvm_save_descriptor cpu_d;
+        HVM_SAVE_TYPE(CPU) cpu;
+        struct hvm_save_descriptor end_d;
+        HVM_SAVE_TYPE(END) end;
+    } bsp_ctx;
+    uint8_t *full_ctx = NULL;
+    int rc;
+
+    DOMPRINTF_CALLED(dom->xch);
+
+    /*
+     * Get the full HVM context in order to have the header, it is not
+     * possible to get the header with getcontext_partial, and crafting one
+     * from userspace is also not an option since cpuid is trapped and
+     * modified by Xen.
+     */
+
+    rc = xc_domain_hvm_getcontext(dom->xch, dom->guest_domid, NULL, 0);
+    if ( rc <= 0 )
+    {
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: unable to fetch HVM context size (rc=%d)",
+                     __func__, rc);
+        return rc;
+    }
+    full_ctx = malloc(rc);
+    if ( full_ctx == NULL )
+    {
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: unable to allocate memory for HVM context (rc=%d)",
+                     __func__, rc);
+        return -ENOMEM;
+    }
+
+    memset(full_ctx, 0, rc);
+
+    rc = xc_domain_hvm_getcontext(dom->xch, dom->guest_domid, full_ctx, rc);
+    if ( rc <= 0 )
+    {
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: unable to fetch HVM context (rc=%d)",
+                     __func__, rc);
+        goto out;
+    }
+
+    /* Copy the header to our partial context. */
+    memset(&bsp_ctx, 0, sizeof(bsp_ctx));
+    memcpy(&bsp_ctx, full_ctx,
+           sizeof(struct hvm_save_descriptor) + HVM_SAVE_LENGTH(HEADER));
+
+    /* Set the CPU descriptor. */
+    bsp_ctx.cpu_d.typecode = HVM_SAVE_CODE(CPU);
+    bsp_ctx.cpu_d.instance = 0;
+    bsp_ctx.cpu_d.length = HVM_SAVE_LENGTH(CPU);
+
+    /* Set the cached part of the relevant segment registers. */
+    bsp_ctx.cpu.cs_base = 0;
+    bsp_ctx.cpu.ds_base = 0;
+    bsp_ctx.cpu.ss_base = 0;
+    bsp_ctx.cpu.tr_base = 0;
+    bsp_ctx.cpu.cs_limit = ~0u;
+    bsp_ctx.cpu.ds_limit = ~0u;
+    bsp_ctx.cpu.ss_limit = ~0u;
+    bsp_ctx.cpu.tr_limit = 0xff;
+    bsp_ctx.cpu.cs_arbytes = 0xc9b;
+    bsp_ctx.cpu.ds_arbytes = 0xc93;
+    bsp_ctx.cpu.ss_arbytes = 0xc93;
+    bsp_ctx.cpu.tr_arbytes = 0x8b;
+
+    /* Set the control registers. */
+    bsp_ctx.cpu.cr0 = X86_CR0_PE | X86_CR0_ET;
+
+    /* Set the IP. */
+    bsp_ctx.cpu.rip = dom->parms.phys_entry;
+
+    /* Set the end descriptor. */
+    bsp_ctx.end_d.typecode = HVM_SAVE_CODE(END);
+    bsp_ctx.end_d.instance = 0;
+    bsp_ctx.end_d.length = HVM_SAVE_LENGTH(END);
+
+    rc = xc_domain_hvm_setcontext(dom->xch, dom->guest_domid,
+                                  (uint8_t *)&bsp_ctx, sizeof(bsp_ctx));
+    if ( rc != 0 )
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: SETHVMCONTEXT failed (rc=%d)", __func__, rc);
+
+ out:
+    if ( full_ctx != NULL )
+        free(full_ctx);
+    return rc;
+}
+
 /* ------------------------------------------------------------------------ */
 
 static int x86_compat(xc_interface *xch, domid_t domid, char *guest_type)
@@ -762,7 +1010,7 @@ static int meminit_pv(struct xc_dom_image *dom)
 
     if ( dom->superpages )
     {
-        int count = dom->total_pages >> SUPERPAGE_PFN_SHIFT;
+        int count = dom->total_pages >> SUPERPAGE_2MB_SHIFT;
         xen_pfn_t extents[count];
 
         dom->p2m_size = dom->total_pages;
@@ -773,9 +1021,9 @@ static int meminit_pv(struct xc_dom_image *dom)
 
         DOMPRINTF("Populating memory with %d superpages", count);
         for ( pfn = 0; pfn < count; pfn++ )
-            extents[pfn] = pfn << SUPERPAGE_PFN_SHIFT;
+            extents[pfn] = pfn << SUPERPAGE_2MB_SHIFT;
         rc = xc_domain_populate_physmap_exact(dom->xch, dom->guest_domid,
-                                               count, SUPERPAGE_PFN_SHIFT, 0,
+                                               count, SUPERPAGE_2MB_SHIFT, 0,
                                                extents);
         if ( rc )
             return rc;
@@ -785,7 +1033,7 @@ static int meminit_pv(struct xc_dom_image *dom)
         for ( i = 0; i < count; i++ )
         {
             mfn = extents[i];
-            for ( j = 0; j < SUPERPAGE_NR_PFNS; j++, pfn++ )
+            for ( j = 0; j < SUPERPAGE_2MB_NR_PFNS; j++, pfn++ )
                 dom->p2m_host[pfn] = mfn + j;
         }
     }
@@ -870,7 +1118,7 @@ static int meminit_pv(struct xc_dom_image *dom)
 
             pages = (vmemranges[i].end - vmemranges[i].start)
                 >> PAGE_SHIFT;
-            super_pages = pages >> SUPERPAGE_PFN_SHIFT;
+            super_pages = pages >> SUPERPAGE_2MB_SHIFT;
             pfn_base = vmemranges[i].start >> PAGE_SHIFT;
 
             for ( pfn = pfn_base; pfn < pfn_base+pages; pfn++ )
@@ -883,11 +1131,11 @@ static int meminit_pv(struct xc_dom_image *dom)
                 super_pages -= count;
 
                 for ( pfn = pfn_base_idx, j = 0;
-                      pfn < pfn_base_idx + (count << SUPERPAGE_PFN_SHIFT);
-                      pfn += SUPERPAGE_NR_PFNS, j++ )
+                      pfn < pfn_base_idx + (count << SUPERPAGE_2MB_SHIFT);
+                      pfn += SUPERPAGE_2MB_NR_PFNS, j++ )
                     extents[j] = dom->p2m_host[pfn];
                 rc = xc_domain_populate_physmap(dom->xch, dom->guest_domid, count,
-                                                SUPERPAGE_PFN_SHIFT, memflags,
+                                                SUPERPAGE_2MB_SHIFT, memflags,
                                                 extents);
                 if ( rc < 0 )
                     return rc;
@@ -897,7 +1145,7 @@ static int meminit_pv(struct xc_dom_image *dom)
                 for ( j = 0; j < rc; j++ )
                 {
                     mfn = extents[j];
-                    for ( k = 0; k < SUPERPAGE_NR_PFNS; k++, pfn++ )
+                    for ( k = 0; k < SUPERPAGE_2MB_NR_PFNS; k++, pfn++ )
                         dom->p2m_host[pfn] = mfn + k;
                 }
                 pfn_base_idx = pfn;
@@ -938,6 +1186,332 @@ static int meminit_pv(struct xc_dom_image *dom)
     return rc;
 }
 
+/*
+ * Check whether there exists mmio hole in the specified memory range.
+ * Returns 1 if exists, else returns 0.
+ */
+static int check_mmio_hole(uint64_t start, uint64_t memsize,
+                           uint64_t mmio_start, uint64_t mmio_size)
+{
+    if ( start + memsize <= mmio_start || start >= mmio_start + mmio_size )
+        return 0;
+    else
+        return 1;
+}
+
+static int meminit_hvm(struct xc_dom_image *dom)
+{
+    unsigned long i, vmemid, nr_pages = dom->total_pages;
+    unsigned long p2m_size;
+    unsigned long target_pages = dom->target_pages;
+    unsigned long cur_pages, cur_pfn;
+    int rc;
+    xen_capabilities_info_t caps;
+    unsigned long stat_normal_pages = 0, stat_2mb_pages = 0, 
+        stat_1gb_pages = 0;
+    unsigned int memflags = 0;
+    int claim_enabled = dom->claim_enabled;
+    uint64_t total_pages;
+    xen_vmemrange_t dummy_vmemrange[2];
+    unsigned int dummy_vnode_to_pnode[1];
+    xen_vmemrange_t *vmemranges;
+    unsigned int *vnode_to_pnode;
+    unsigned int nr_vmemranges, nr_vnodes;
+    xc_interface *xch = dom->xch;
+    uint32_t domid = dom->guest_domid;
+
+    if ( nr_pages > target_pages )
+        memflags |= XENMEMF_populate_on_demand;
+
+    if ( dom->nr_vmemranges == 0 )
+    {
+        /* Build dummy vnode information
+         *
+         * Guest physical address space layout:
+         * [0, hole_start) [hole_start, 4G) [4G, highmem_end)
+         *
+         * Of course if there is no high memory, the second vmemrange
+         * has no effect on the actual result.
+         */
+
+        dummy_vmemrange[0].start = 0;
+        dummy_vmemrange[0].end   = dom->lowmem_end;
+        dummy_vmemrange[0].flags = 0;
+        dummy_vmemrange[0].nid   = 0;
+        nr_vmemranges = 1;
+
+        if ( dom->highmem_end > (1ULL << 32) )
+        {
+            dummy_vmemrange[1].start = 1ULL << 32;
+            dummy_vmemrange[1].end   = dom->highmem_end;
+            dummy_vmemrange[1].flags = 0;
+            dummy_vmemrange[1].nid   = 0;
+
+            nr_vmemranges++;
+        }
+
+        dummy_vnode_to_pnode[0] = XC_NUMA_NO_NODE;
+        nr_vnodes = 1;
+        vmemranges = dummy_vmemrange;
+        vnode_to_pnode = dummy_vnode_to_pnode;
+    }
+    else
+    {
+        if ( nr_pages > target_pages )
+        {
+            DOMPRINTF("Cannot enable vNUMA and PoD at the same time");
+            goto error_out;
+        }
+
+        nr_vmemranges = dom->nr_vmemranges;
+        nr_vnodes = dom->nr_vnodes;
+        vmemranges = dom->vmemranges;
+        vnode_to_pnode = dom->vnode_to_pnode;
+    }
+
+    total_pages = 0;
+    p2m_size = 0;
+    for ( i = 0; i < nr_vmemranges; i++ )
+    {
+        total_pages += ((vmemranges[i].end - vmemranges[i].start)
+                        >> PAGE_SHIFT);
+        p2m_size = p2m_size > (vmemranges[i].end >> PAGE_SHIFT) ?
+            p2m_size : (vmemranges[i].end >> PAGE_SHIFT);
+    }
+
+    if ( total_pages != nr_pages )
+    {
+        DOMPRINTF("vNUMA memory pages mismatch (0x%"PRIx64" != 0x%"PRIx64")",
+               total_pages, nr_pages);
+        goto error_out;
+    }
+
+    if ( xc_version(xch, XENVER_capabilities, &caps) != 0 )
+    {
+        DOMPRINTF("Could not get Xen capabilities");
+        goto error_out;
+    }
+
+    dom->p2m_size = p2m_size;
+    dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) *
+                                      dom->p2m_size);
+    if ( dom->p2m_host == NULL )
+    {
+        DOMPRINTF("Could not allocate p2m");
+        goto error_out;
+    }
+
+    for ( i = 0; i < p2m_size; i++ )
+        dom->p2m_host[i] = ((xen_pfn_t)-1);
+    for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
+    {
+        uint64_t pfn;
+
+        for ( pfn = vmemranges[vmemid].start >> PAGE_SHIFT;
+              pfn < vmemranges[vmemid].end >> PAGE_SHIFT;
+              pfn++ )
+            dom->p2m_host[pfn] = pfn;
+    }
+
+    /*
+     * Try to claim pages for early warning of insufficient memory available.
+     * This should go before xc_domain_set_pod_target, becuase that function
+     * actually allocates memory for the guest. Claiming after memory has been
+     * allocated is pointless.
+     */
+    if ( claim_enabled ) {
+        rc = xc_domain_claim_pages(xch, domid, target_pages - VGA_HOLE_SIZE);
+        if ( rc != 0 )
+        {
+            DOMPRINTF("Could not allocate memory for HVM guest as we cannot claim memory!");
+            goto error_out;
+        }
+    }
+
+    if ( memflags & XENMEMF_populate_on_demand )
+    {
+        /*
+         * Subtract VGA_HOLE_SIZE from target_pages for the VGA
+         * "hole".  Xen will adjust the PoD cache size so that domain
+         * tot_pages will be target_pages - VGA_HOLE_SIZE after
+         * this call.
+         */
+        rc = xc_domain_set_pod_target(xch, domid, target_pages - VGA_HOLE_SIZE,
+                                      NULL, NULL, NULL);
+        if ( rc != 0 )
+        {
+            DOMPRINTF("Could not set PoD target for HVM guest.\n");
+            goto error_out;
+        }
+    }
+
+    /*
+     * Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000.
+     *
+     * We attempt to allocate 1GB pages if possible. It falls back on 2MB
+     * pages if 1GB allocation fails. 4KB pages will be used eventually if
+     * both fail.
+     * 
+     * Under 2MB mode, we allocate pages in batches of no more than 8MB to 
+     * ensure that we can be preempted and hence dom0 remains responsive.
+     */
+    rc = xc_domain_populate_physmap_exact(
+        xch, domid, 0xa0, 0, memflags, &dom->p2m_host[0x00]);
+
+    stat_normal_pages = 0;
+    for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
+    {
+        unsigned int new_memflags = memflags;
+        uint64_t end_pages;
+        unsigned int vnode = vmemranges[vmemid].nid;
+        unsigned int pnode = vnode_to_pnode[vnode];
+
+        if ( pnode != XC_NUMA_NO_NODE )
+            new_memflags |= XENMEMF_exact_node(pnode);
+
+        end_pages = vmemranges[vmemid].end >> PAGE_SHIFT;
+        /*
+         * Consider vga hole belongs to the vmemrange that covers
+         * 0xA0000-0xC0000. Note that 0x00000-0xA0000 is populated just
+         * before this loop.
+         */
+        if ( vmemranges[vmemid].start == 0 )
+        {
+            cur_pages = 0xc0;
+            stat_normal_pages += 0xc0;
+        }
+        else
+            cur_pages = vmemranges[vmemid].start >> PAGE_SHIFT;
+
+        while ( (rc == 0) && (end_pages > cur_pages) )
+        {
+            /* Clip count to maximum 1GB extent. */
+            unsigned long count = end_pages - cur_pages;
+            unsigned long max_pages = SUPERPAGE_1GB_NR_PFNS;
+
+            if ( count > max_pages )
+                count = max_pages;
+
+            cur_pfn = dom->p2m_host[cur_pages];
+
+            /* Take care the corner cases of super page tails */
+            if ( ((cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1)) != 0) &&
+                 (count > (-cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1))) )
+                count = -cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1);
+            else if ( ((count & (SUPERPAGE_1GB_NR_PFNS-1)) != 0) &&
+                      (count > SUPERPAGE_1GB_NR_PFNS) )
+                count &= ~(SUPERPAGE_1GB_NR_PFNS - 1);
+
+            /* Attemp to allocate 1GB super page. Because in each pass
+             * we only allocate at most 1GB, we don't have to clip
+             * super page boundaries.
+             */
+            if ( ((count | cur_pfn) & (SUPERPAGE_1GB_NR_PFNS - 1)) == 0 &&
+                 /* Check if there exists MMIO hole in the 1GB memory
+                  * range */
+                 !check_mmio_hole(cur_pfn << PAGE_SHIFT,
+                                  SUPERPAGE_1GB_NR_PFNS << PAGE_SHIFT,
+                                  dom->mmio_start, dom->mmio_size) )
+            {
+                long done;
+                unsigned long nr_extents = count >> SUPERPAGE_1GB_SHIFT;
+                xen_pfn_t sp_extents[nr_extents];
+
+                for ( i = 0; i < nr_extents; i++ )
+                    sp_extents[i] =
+                        dom->p2m_host[cur_pages+(i<<SUPERPAGE_1GB_SHIFT)];
+
+                done = xc_domain_populate_physmap(xch, domid, nr_extents,
+                                                  SUPERPAGE_1GB_SHIFT,
+                                                  memflags, sp_extents);
+
+                if ( done > 0 )
+                {
+                    stat_1gb_pages += done;
+                    done <<= SUPERPAGE_1GB_SHIFT;
+                    cur_pages += done;
+                    count -= done;
+                }
+            }
+
+            if ( count != 0 )
+            {
+                /* Clip count to maximum 8MB extent. */
+                max_pages = SUPERPAGE_2MB_NR_PFNS * 4;
+                if ( count > max_pages )
+                    count = max_pages;
+
+                /* Clip partial superpage extents to superpage
+                 * boundaries. */
+                if ( ((cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1)) != 0) &&
+                     (count > (-cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1))) )
+                    count = -cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1);
+                else if ( ((count & (SUPERPAGE_2MB_NR_PFNS-1)) != 0) &&
+                          (count > SUPERPAGE_2MB_NR_PFNS) )
+                    count &= ~(SUPERPAGE_2MB_NR_PFNS - 1); /* clip non-s.p. tail */
+
+                /* Attempt to allocate superpage extents. */
+                if ( ((count | cur_pfn) & (SUPERPAGE_2MB_NR_PFNS - 1)) == 0 )
+                {
+                    long done;
+                    unsigned long nr_extents = count >> SUPERPAGE_2MB_SHIFT;
+                    xen_pfn_t sp_extents[nr_extents];
+
+                    for ( i = 0; i < nr_extents; i++ )
+                        sp_extents[i] =
+                            dom->p2m_host[cur_pages+(i<<SUPERPAGE_2MB_SHIFT)];
+
+                    done = xc_domain_populate_physmap(xch, domid, nr_extents,
+                                                      SUPERPAGE_2MB_SHIFT,
+                                                      memflags, sp_extents);
+
+                    if ( done > 0 )
+                    {
+                        stat_2mb_pages += done;
+                        done <<= SUPERPAGE_2MB_SHIFT;
+                        cur_pages += done;
+                        count -= done;
+                    }
+                }
+            }
+
+            /* Fall back to 4kB extents. */
+            if ( count != 0 )
+            {
+                rc = xc_domain_populate_physmap_exact(
+                    xch, domid, count, 0, new_memflags, &dom->p2m_host[cur_pages]);
+                cur_pages += count;
+                stat_normal_pages += count;
+            }
+        }
+
+        if ( rc != 0 )
+            break;
+    }
+
+    if ( rc != 0 )
+    {
+        DOMPRINTF("Could not allocate memory for HVM guest.");
+        goto error_out;
+    }
+
+    DPRINTF("PHYSICAL MEMORY ALLOCATION:\n");
+    DPRINTF("  4KB PAGES: 0x%016lx\n", stat_normal_pages);
+    DPRINTF("  2MB PAGES: 0x%016lx\n", stat_2mb_pages);
+    DPRINTF("  1GB PAGES: 0x%016lx\n", stat_1gb_pages);
+
+    rc = 0;
+    goto out;
+ error_out:
+    rc = -1;
+ out:
+
+    /* ensure no unclaimed pages are left unused */
+    xc_domain_claim_pages(xch, domid, 0 /* cancels the claim */);
+
+    return rc;
+}
+
 /* ------------------------------------------------------------------------ */
 
 static int bootearly(struct xc_dom_image *dom)
@@ -1052,6 +1626,12 @@ static int bootlate_pv(struct xc_dom_image *dom)
     return 0;
 }
 
+static int bootlate_hvm(struct xc_dom_image *dom)
+{
+    DOMPRINTF("%s: doing nothing", __func__);
+    return 0;
+}
+
 int xc_dom_feature_translated(struct xc_dom_image *dom)
 {
     /* Guests running inside HVM containers are always auto-translated. */
@@ -1095,10 +1675,27 @@ static struct xc_dom_arch xc_dom_64 = {
     .bootlate = bootlate_pv,
 };
 
+static struct xc_dom_arch xc_hvm_32 = {
+    .guest_type = "hvm-3.0-x86_32",
+    .native_protocol = XEN_IO_PROTO_ABI_X86_32,
+    .page_shift = PAGE_SHIFT_X86,
+    .sizeof_pfn = 4,
+    .alloc_magic_pages = alloc_magic_pages_hvm,
+    .count_pgtables = NULL,
+    .setup_pgtables = NULL,
+    .start_info = NULL,
+    .shared_info = NULL,
+    .vcpu = vcpu_hvm,
+    .meminit = meminit_hvm,
+    .bootearly = bootearly,
+    .bootlate = bootlate_hvm,
+};
+
 static void __init register_arch_hooks(void)
 {
     xc_dom_register_arch_hooks(&xc_dom_32_pae);
     xc_dom_register_arch_hooks(&xc_dom_64);
+    xc_dom_register_arch_hooks(&xc_hvm_32);
 }
 
 /*
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 10/31] libxl: switch HVM domain building to use xc_dom_* helpers
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (8 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 09/31] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 12:12   ` Wei Liu
  2015-08-07 10:17 ` [PATCH v4 11/31] libxc: remove dead HVM building code Roger Pau Monne
                   ` (20 subsequent siblings)
  30 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

Now that we have all the code in place HVM domain building in libxl can be
switched to use the xc_dom_* family of functions, just like they are used in
order to build PV guests.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxl/libxl_arch.h     |   2 +-
 tools/libxl/libxl_dm.c       |  18 ++--
 tools/libxl/libxl_dom.c      | 227 +++++++++++++++++++++++++------------------
 tools/libxl/libxl_internal.h |   4 +-
 tools/libxl/libxl_vnuma.c    |  12 ++-
 tools/libxl/libxl_x86.c      |   8 +-
 6 files changed, 155 insertions(+), 116 deletions(-)

diff --git a/tools/libxl/libxl_arch.h b/tools/libxl/libxl_arch.h
index bd030b6..34a853c 100644
--- a/tools/libxl/libxl_arch.h
+++ b/tools/libxl/libxl_arch.h
@@ -60,6 +60,6 @@ _hidden
 int libxl__arch_domain_construct_memmap(libxl__gc *gc,
                                         libxl_domain_config *d_config,
                                         uint32_t domid,
-                                        struct xc_hvm_build_args *args);
+                                        struct xc_dom_image *dom);
 
 #endif
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 02c0162..f6b4c89 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -18,6 +18,8 @@
 #include "libxl_osdeps.h" /* must come before any other headers */
 
 #include "libxl_internal.h"
+
+#include <xc_dom.h>
 #include <xen/hvm/e820.h>
 
 static const char *libxl_tapif_script(libxl__gc *gc)
@@ -181,7 +183,7 @@ add_rdm_entry(libxl__gc *gc, libxl_domain_config *d_config,
 int libxl__domain_device_construct_rdm(libxl__gc *gc,
                                        libxl_domain_config *d_config,
                                        uint64_t rdm_mem_boundary,
-                                       struct xc_hvm_build_args *args)
+                                       struct xc_dom_image *dom)
 {
     int i, j, conflict, rc;
     struct xen_reserved_device_memory *xrdm = NULL;
@@ -189,7 +191,7 @@ int libxl__domain_device_construct_rdm(libxl__gc *gc,
     uint16_t seg;
     uint8_t bus, devfn;
     uint64_t rdm_start, rdm_size;
-    uint64_t highmem_end = args->highmem_end ? args->highmem_end : (1ull<<32);
+    uint64_t highmem_end = dom->highmem_end ? dom->highmem_end : (1ull<<32);
 
     /*
      * We just want to construct RDM once since RDM is specific to the
@@ -303,7 +305,7 @@ int libxl__domain_device_construct_rdm(libxl__gc *gc,
     for (i = 0; i < d_config->num_rdms; i++) {
         rdm_start = d_config->rdms[i].start;
         rdm_size = d_config->rdms[i].size;
-        conflict = overlaps_rdm(0, args->lowmem_end, rdm_start, rdm_size);
+        conflict = overlaps_rdm(0, dom->lowmem_end, rdm_start, rdm_size);
 
         if (!conflict)
             continue;
@@ -314,14 +316,14 @@ int libxl__domain_device_construct_rdm(libxl__gc *gc,
              * We will move downwards lowmem_end so we have to expand
              * highmem_end.
              */
-            highmem_end += (args->lowmem_end - rdm_start);
+            highmem_end += (dom->lowmem_end - rdm_start);
             /* Now move downwards lowmem_end. */
-            args->lowmem_end = rdm_start;
+            dom->lowmem_end = rdm_start;
         }
     }
 
     /* Sync highmem_end. */
-    args->highmem_end = highmem_end;
+    dom->highmem_end = highmem_end;
 
     /*
      * Finally we can take same policy to check lowmem(< 2G) and
@@ -331,11 +333,11 @@ int libxl__domain_device_construct_rdm(libxl__gc *gc,
         rdm_start = d_config->rdms[i].start;
         rdm_size = d_config->rdms[i].size;
         /* Does this entry conflict with lowmem? */
-        conflict = overlaps_rdm(0, args->lowmem_end,
+        conflict = overlaps_rdm(0, dom->lowmem_end,
                                 rdm_start, rdm_size);
         /* Does this entry conflict with highmem? */
         conflict |= overlaps_rdm((1ULL<<32),
-                                 args->highmem_end - (1ULL<<32),
+                                 dom->highmem_end - (1ULL<<32),
                                  rdm_start, rdm_size);
 
         if (!conflict)
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 92c4278..bf9b65f 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -602,6 +602,63 @@ static int set_vnuma_info(libxl__gc *gc, uint32_t domid,
     return rc;
 }
 
+static int libxl__build_dom(libxl__gc *gc, uint32_t domid,
+             libxl_domain_build_info *info, libxl__domain_build_state *state,
+             struct xc_dom_image *dom)
+{
+    uint64_t mem_kb;
+    int ret;
+
+    if ( (ret = xc_dom_boot_xen_init(dom, CTX->xch, domid)) != 0 ) {
+        LOGE(ERROR, "xc_dom_boot_xen_init failed");
+        goto out;
+    }
+#ifdef GUEST_RAM_BASE
+    if ( (ret = xc_dom_rambase_init(dom, GUEST_RAM_BASE)) != 0 ) {
+        LOGE(ERROR, "xc_dom_rambase failed");
+        goto out;
+    }
+#endif
+    if ( (ret = xc_dom_parse_image(dom)) != 0 ) {
+        LOGE(ERROR, "xc_dom_parse_image failed");
+        goto out;
+    }
+    if ( (ret = libxl__arch_domain_init_hw_description(gc, info, state, dom)) != 0 ) {
+        LOGE(ERROR, "libxl__arch_domain_init_hw_description failed");
+        goto out;
+    }
+
+    mem_kb = dom->container_type == XC_DOM_HVM_CONTAINER ?
+             (info->max_memkb - info->video_memkb) : info->target_memkb;
+    if ( (ret = xc_dom_mem_init(dom, mem_kb / 1024)) != 0 ) {
+        LOGE(ERROR, "xc_dom_mem_init failed");
+        goto out;
+    }
+    if ( (ret = xc_dom_boot_mem_init(dom)) != 0 ) {
+        LOGE(ERROR, "xc_dom_boot_mem_init failed");
+        goto out;
+    }
+    if ( (ret = libxl__arch_domain_finalise_hw_description(gc, info, dom)) != 0 ) {
+        LOGE(ERROR, "libxl__arch_domain_finalise_hw_description failed");
+        goto out;
+    }
+    if ( (ret = xc_dom_build_image(dom)) != 0 ) {
+        LOGE(ERROR, "xc_dom_build_image failed");
+        goto out;
+    }
+    if ( (ret = xc_dom_boot_image(dom)) != 0 ) {
+        LOGE(ERROR, "xc_dom_boot_image failed");
+        goto out;
+    }
+    if ( (ret = xc_dom_gnttab_init(dom)) != 0 ) {
+        LOGE(ERROR, "xc_dom_gnttab_init failed");
+        goto out;
+    }
+
+out:
+    return ret != 0 ? ERROR_FAIL : 0;
+}
+
 int libxl__build_pv(libxl__gc *gc, uint32_t domid,
              libxl_domain_build_info *info, libxl__domain_build_state *state)
 {
@@ -692,48 +749,9 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
             dom->vnode_to_pnode[i] = info->vnuma_nodes[i].pnode;
     }
 
-    if ( (ret = xc_dom_boot_xen_init(dom, ctx->xch, domid)) != 0 ) {
-        LOGE(ERROR, "xc_dom_boot_xen_init failed");
-        goto out;
-    }
-#ifdef GUEST_RAM_BASE
-    if ( (ret = xc_dom_rambase_init(dom, GUEST_RAM_BASE)) != 0 ) {
-        LOGE(ERROR, "xc_dom_rambase failed");
-        goto out;
-    }
-#endif
-    if ( (ret = xc_dom_parse_image(dom)) != 0 ) {
-        LOGE(ERROR, "xc_dom_parse_image failed");
-        goto out;
-    }
-    if ( (ret = libxl__arch_domain_init_hw_description(gc, info, state, dom)) != 0 ) {
-        LOGE(ERROR, "libxl__arch_domain_init_hw_description failed");
-        goto out;
-    }
-    if ( (ret = xc_dom_mem_init(dom, info->target_memkb / 1024)) != 0 ) {
-        LOGE(ERROR, "xc_dom_mem_init failed");
-        goto out;
-    }
-    if ( (ret = xc_dom_boot_mem_init(dom)) != 0 ) {
-        LOGE(ERROR, "xc_dom_boot_mem_init failed");
-        goto out;
-    }
-    if ( (ret = libxl__arch_domain_finalise_hw_description(gc, info, dom)) != 0 ) {
-        LOGE(ERROR, "libxl__arch_domain_finalise_hw_description failed");
-        goto out;
-    }
-    if ( (ret = xc_dom_build_image(dom)) != 0 ) {
-        LOGE(ERROR, "xc_dom_build_image failed");
-        goto out;
-    }
-    if ( (ret = xc_dom_boot_image(dom)) != 0 ) {
-        LOGE(ERROR, "xc_dom_boot_image failed");
+    ret = libxl__build_dom(gc, domid, info, state, dom);
+    if (ret != 0)
         goto out;
-    }
-    if ( (ret = xc_dom_gnttab_init(dom)) != 0 ) {
-        LOGE(ERROR, "xc_dom_gnttab_init failed");
-        goto out;
-    }
 
     if (xc_dom_feature_translated(dom)) {
         state->console_mfn = dom->console_pfn;
@@ -793,39 +811,39 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
 
 static int hvm_build_set_xs_values(libxl__gc *gc,
                                    uint32_t domid,
-                                   struct xc_hvm_build_args *args)
+                                   struct xc_dom_image *dom)
 {
     char *path = NULL;
     int ret = 0;
 
-    if (args->smbios_module.guest_addr_out) {
+    if (dom->smbios_module.guest_addr_out) {
         path = GCSPRINTF("/local/domain/%d/"HVM_XS_SMBIOS_PT_ADDRESS, domid);
 
         ret = libxl__xs_write(gc, XBT_NULL, path, "0x%"PRIx64,
-                              args->smbios_module.guest_addr_out);
+                              dom->smbios_module.guest_addr_out);
         if (ret)
             goto err;
 
         path = GCSPRINTF("/local/domain/%d/"HVM_XS_SMBIOS_PT_LENGTH, domid);
 
         ret = libxl__xs_write(gc, XBT_NULL, path, "0x%x",
-                              args->smbios_module.length);
+                              dom->smbios_module.length);
         if (ret)
             goto err;
     }
 
-    if (args->acpi_module.guest_addr_out) {
+    if (dom->acpi_module.guest_addr_out) {
         path = GCSPRINTF("/local/domain/%d/"HVM_XS_ACPI_PT_ADDRESS, domid);
 
         ret = libxl__xs_write(gc, XBT_NULL, path, "0x%"PRIx64,
-                              args->acpi_module.guest_addr_out);
+                              dom->acpi_module.guest_addr_out);
         if (ret)
             goto err;
 
         path = GCSPRINTF("/local/domain/%d/"HVM_XS_ACPI_PT_LENGTH, domid);
 
         ret = libxl__xs_write(gc, XBT_NULL, path, "0x%x",
-                              args->acpi_module.length);
+                              dom->acpi_module.length);
         if (ret)
             goto err;
     }
@@ -839,7 +857,7 @@ err:
 
 static int libxl__domain_firmware(libxl__gc *gc,
                                   libxl_domain_build_info *info,
-                                  struct xc_hvm_build_args *args)
+                                  struct xc_dom_image *dom)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     const char *firmware;
@@ -865,8 +883,13 @@ static int libxl__domain_firmware(libxl__gc *gc,
             break;
         }
     }
-    args->image_file_name = libxl__abs_path(gc, firmware,
-                                            libxl__xenfirmwaredir_path());
+
+    rc = xc_dom_kernel_file(dom, libxl__abs_path(gc, firmware,
+                                                 libxl__xenfirmwaredir_path()));
+    if (rc != 0) {
+        LOGE(ERROR, "xc_dom_kernel_file failed");
+        goto out;
+    }
 
     if (info->u.hvm.smbios_firmware) {
         data = NULL;
@@ -880,8 +903,8 @@ static int libxl__domain_firmware(libxl__gc *gc,
         libxl__ptr_add(gc, data);
         if (datalen) {
             /* Only accept non-empty files */
-            args->smbios_module.data = data;
-            args->smbios_module.length = (uint32_t)datalen;
+            dom->smbios_module.data = data;
+            dom->smbios_module.length = (uint32_t)datalen;
         }
     }
 
@@ -897,8 +920,8 @@ static int libxl__domain_firmware(libxl__gc *gc,
         libxl__ptr_add(gc, data);
         if (datalen) {
             /* Only accept non-empty files */
-            args->acpi_module.data = data;
-            args->acpi_module.length = (uint32_t)datalen;
+            dom->acpi_module.data = data;
+            dom->acpi_module.length = (uint32_t)datalen;
         }
     }
 
@@ -912,52 +935,62 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
               libxl__domain_build_state *state)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    struct xc_hvm_build_args args = {};
-    int ret, rc;
-    uint64_t mmio_start, lowmem_end, highmem_end;
+    int rc;
+    uint64_t mmio_start, lowmem_end, highmem_end, mem_size;
     libxl_domain_build_info *const info = &d_config->b_info;
+    struct xc_dom_image *dom = NULL;
+
+    xc_dom_loginit(ctx->xch);
+
+    dom = xc_dom_allocate(ctx->xch, NULL, NULL);
+    if (!dom) {
+        LOGE(ERROR, "xc_dom_allocate failed");
+        goto out;
+    }
+
+    dom->container_type = XC_DOM_HVM_CONTAINER;
 
-    memset(&args, 0, sizeof(struct xc_hvm_build_args));
     /* The params from the configuration file are in Mb, which are then
      * multiplied by 1 Kb. This was then divided off when calling
      * the old xc_hvm_build_target_mem() which then turned them to bytes.
      * Do all this in one step here...
      */
-    args.mem_size = (uint64_t)(info->max_memkb - info->video_memkb) << 10;
-    args.mem_target = (uint64_t)(info->target_memkb - info->video_memkb) << 10;
-    args.claim_enabled = libxl_defbool_val(info->claim_mode);
+    mem_size = (uint64_t)(info->max_memkb - info->video_memkb) << 10;
+    dom->target_pages = (uint64_t)(info->target_memkb - info->video_memkb) >> 2;
+    dom->claim_enabled = libxl_defbool_val(info->claim_mode);
     if (info->u.hvm.mmio_hole_memkb) {
         uint64_t max_ram_below_4g = (1ULL << 32) -
             (info->u.hvm.mmio_hole_memkb << 10);
 
         if (max_ram_below_4g < HVM_BELOW_4G_MMIO_START)
-            args.mmio_size = info->u.hvm.mmio_hole_memkb << 10;
+            dom->mmio_size = info->u.hvm.mmio_hole_memkb << 10;
     }
 
-    rc = libxl__domain_firmware(gc, info, &args);
+    rc = libxl__domain_firmware(gc, info, dom);
     if (rc != 0) {
         LOG(ERROR, "initializing domain firmware failed");
         goto out;
     }
-    if (args.mem_target == 0)
-        args.mem_target = args.mem_size;
-    if (args.mmio_size == 0)
-        args.mmio_size = HVM_BELOW_4G_MMIO_LENGTH;
-    lowmem_end = args.mem_size;
+
+    if (dom->target_pages == 0)
+        dom->target_pages = mem_size >> XC_PAGE_SHIFT;
+    if (dom->mmio_size == 0)
+        dom->mmio_size = HVM_BELOW_4G_MMIO_LENGTH;
+    lowmem_end = mem_size;
     highmem_end = 0;
-    mmio_start = (1ull << 32) - args.mmio_size;
+    mmio_start = (1ull << 32) - dom->mmio_size;
     if (lowmem_end > mmio_start)
     {
         highmem_end = (1ull << 32) + (lowmem_end - mmio_start);
         lowmem_end = mmio_start;
     }
-    args.lowmem_end = lowmem_end;
-    args.highmem_end = highmem_end;
-    args.mmio_start = mmio_start;
+    dom->lowmem_end = lowmem_end;
+    dom->highmem_end = highmem_end;
+    dom->mmio_start = mmio_start;
 
     rc = libxl__domain_device_construct_rdm(gc, d_config,
                                             info->u.hvm.rdm_mem_boundary_memkb*1024,
-                                            &args);
+                                            dom);
     if (rc) {
         LOG(ERROR, "checking reserved device memory failed");
         goto out;
@@ -966,7 +999,7 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
     if (info->num_vnuma_nodes != 0) {
         int i;
 
-        rc = libxl__vnuma_build_vmemrange_hvm(gc, domid, info, state, &args);
+        rc = libxl__vnuma_build_vmemrange_hvm(gc, domid, info, state, dom);
         if (rc != 0) {
             LOG(ERROR, "hvm build vmemranges failed");
             goto out;
@@ -976,37 +1009,34 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
         rc = set_vnuma_info(gc, domid, info, state);
         if (rc != 0) goto out;
 
-        args.nr_vmemranges = state->num_vmemranges;
-        args.vmemranges = libxl__malloc(gc, sizeof(*args.vmemranges) *
-                                        args.nr_vmemranges);
+        dom->nr_vmemranges = state->num_vmemranges;
+        dom->vmemranges = libxl__malloc(gc, sizeof(*dom->vmemranges) *
+                                        dom->nr_vmemranges);
 
-        for (i = 0; i < args.nr_vmemranges; i++) {
-            args.vmemranges[i].start = state->vmemranges[i].start;
-            args.vmemranges[i].end   = state->vmemranges[i].end;
-            args.vmemranges[i].flags = state->vmemranges[i].flags;
-            args.vmemranges[i].nid   = state->vmemranges[i].nid;
+        for (i = 0; i < dom->nr_vmemranges; i++) {
+            dom->vmemranges[i].start = state->vmemranges[i].start;
+            dom->vmemranges[i].end   = state->vmemranges[i].end;
+            dom->vmemranges[i].flags = state->vmemranges[i].flags;
+            dom->vmemranges[i].nid   = state->vmemranges[i].nid;
         }
 
-        args.nr_vnodes = info->num_vnuma_nodes;
-        args.vnode_to_pnode = libxl__malloc(gc, sizeof(*args.vnode_to_pnode) *
-                                            args.nr_vnodes);
-        for (i = 0; i < args.nr_vnodes; i++)
-            args.vnode_to_pnode[i] = info->vnuma_nodes[i].pnode;
-    }
-
-    ret = xc_hvm_build(ctx->xch, domid, &args);
-    if (ret) {
-        LOGEV(ERROR, ret, "hvm building failed");
-        rc = ERROR_FAIL;
-        goto out;
+        dom->nr_vnodes = info->num_vnuma_nodes;
+        dom->vnode_to_pnode = libxl__malloc(gc, sizeof(*dom->vnode_to_pnode) *
+                                            dom->nr_vnodes);
+        for (i = 0; i < dom->nr_vnodes; i++)
+            dom->vnode_to_pnode[i] = info->vnuma_nodes[i].pnode;
     }
 
-    rc = libxl__arch_domain_construct_memmap(gc, d_config, domid, &args);
+    rc = libxl__arch_domain_construct_memmap(gc, d_config, domid, dom);
     if (rc != 0) {
         LOG(ERROR, "setting domain memory map failed");
         goto out;
     }
 
+    rc = libxl__build_dom(gc, domid, info, state, dom);
+    if (rc != 0)
+        goto out;
+
     rc = hvm_build_set_params(ctx->xch, domid, info, state->store_port,
                                &state->store_mfn, state->console_port,
                                &state->console_mfn, state->store_domid,
@@ -1016,15 +1046,18 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
         goto out;
     }
 
-    rc = hvm_build_set_xs_values(gc, domid, &args);
+    rc = hvm_build_set_xs_values(gc, domid, dom);
     if (rc != 0) {
         LOG(ERROR, "hvm build set xenstore values failed");
         goto out;
     }
 
+    xc_dom_release(dom);
     return 0;
+
 out:
     assert(rc != 0);
+    if (dom != NULL) xc_dom_release(dom);
     return rc;
 }
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 6ea6c83..ea89f1f 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1594,7 +1594,7 @@ _hidden int libxl__need_xenpv_qemu(libxl__gc *gc,
 _hidden int libxl__domain_device_construct_rdm(libxl__gc *gc,
                                    libxl_domain_config *d_config,
                                    uint64_t rdm_mem_guard,
-                                   struct xc_hvm_build_args *args);
+                                   struct xc_dom_image *dom);
 
 /*
  * This function will cause the whole libxl process to hang
@@ -3752,7 +3752,7 @@ int libxl__vnuma_build_vmemrange_hvm(libxl__gc *gc,
                                      uint32_t domid,
                                      libxl_domain_build_info *b_info,
                                      libxl__domain_build_state *state,
-                                     struct xc_hvm_build_args *args);
+                                     struct xc_dom_image *dom);
 bool libxl__vnuma_configured(const libxl_domain_build_info *b_info);
 
 _hidden int libxl__ms_vm_genid_set(libxl__gc *gc, uint32_t domid,
diff --git a/tools/libxl/libxl_vnuma.c b/tools/libxl/libxl_vnuma.c
index 56856d2..db22799 100644
--- a/tools/libxl/libxl_vnuma.c
+++ b/tools/libxl/libxl_vnuma.c
@@ -17,6 +17,8 @@
 #include "libxl_arch.h"
 #include <stdlib.h>
 
+#include <xc_dom.h>
+
 bool libxl__vnuma_configured(const libxl_domain_build_info *b_info)
 {
     return b_info->num_vnuma_nodes != 0;
@@ -252,7 +254,7 @@ int libxl__vnuma_build_vmemrange_hvm(libxl__gc *gc,
                                      uint32_t domid,
                                      libxl_domain_build_info *b_info,
                                      libxl__domain_build_state *state,
-                                     struct xc_hvm_build_args *args)
+                                     struct xc_dom_image *dom)
 {
     uint64_t hole_start, hole_end, next;
     int nid, nr_vmemrange;
@@ -264,10 +266,10 @@ int libxl__vnuma_build_vmemrange_hvm(libxl__gc *gc,
      * Guest physical address space layout:
      * [0, hole_start) [hole_start, hole_end) [hole_end, highmem_end)
      */
-    hole_start = args->lowmem_end < args->mmio_start ?
-        args->lowmem_end : args->mmio_start;
-    hole_end = (args->mmio_start + args->mmio_size) > (1ULL << 32) ?
-        (args->mmio_start + args->mmio_size) : (1ULL << 32);
+    hole_start = dom->lowmem_end < dom->mmio_start ?
+        dom->lowmem_end : dom->mmio_start;
+    hole_end = (dom->mmio_start + dom->mmio_size) > (1ULL << 32) ?
+        (dom->mmio_start + dom->mmio_size) : (1ULL << 32);
 
     assert(state->vmemranges == NULL);
 
diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
index b379e09..b887411 100644
--- a/tools/libxl/libxl_x86.c
+++ b/tools/libxl/libxl_x86.c
@@ -1,6 +1,8 @@
 #include "libxl_internal.h"
 #include "libxl_arch.h"
 
+#include <xc_dom.h>
+
 int libxl__arch_domain_prepare_config(libxl__gc *gc,
                                       libxl_domain_config *d_config,
                                       xc_domain_configuration_t *xc_config)
@@ -473,7 +475,7 @@ int libxl__arch_domain_map_irq(libxl__gc *gc, uint32_t domid, int irq)
 int libxl__arch_domain_construct_memmap(libxl__gc *gc,
                                         libxl_domain_config *d_config,
                                         uint32_t domid,
-                                        struct xc_hvm_build_args *args)
+                                        struct xc_dom_image *dom)
 {
     int rc = 0;
     unsigned int nr = 0, i;
@@ -481,7 +483,7 @@ int libxl__arch_domain_construct_memmap(libxl__gc *gc,
     unsigned int e820_entries = 1;
     struct e820entry *e820 = NULL;
     uint64_t highmem_size =
-                    args->highmem_end ? args->highmem_end - (1ull << 32) : 0;
+                    dom->highmem_end ? dom->highmem_end - (1ull << 32) : 0;
 
     /* Add all rdm entries. */
     for (i = 0; i < d_config->num_rdms; i++)
@@ -503,7 +505,7 @@ int libxl__arch_domain_construct_memmap(libxl__gc *gc,
 
     /* Low memory */
     e820[nr].addr = GUEST_LOW_MEM_START_DEFAULT;
-    e820[nr].size = args->lowmem_end - GUEST_LOW_MEM_START_DEFAULT;
+    e820[nr].size = dom->lowmem_end - GUEST_LOW_MEM_START_DEFAULT;
     e820[nr].type = E820_RAM;
     nr++;
 
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 11/31] libxc: remove dead HVM building code
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (9 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 10/31] libxl: switch HVM domain building to use xc_dom_* helpers Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 12:12   ` Wei Liu
  2015-08-07 15:59   ` Andrew Cooper
  2015-08-07 10:17 ` [PATCH v4 12/31] xen/x86: add bitmap of enabled emulated devices Roger Pau Monne
                   ` (19 subsequent siblings)
  30 siblings, 2 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

Remove xc_hvm_build_x86.c and xc_hvm_build_arm.c since xc_hvm_build is not
longer used in order to create HVM guests.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxc/Makefile              |   2 -
 tools/libxc/include/xenguest.h    |  44 ---
 tools/libxc/xc_hvm_build_arm.c    |  48 ---
 tools/libxc/xc_hvm_build_x86.c    | 806 --------------------------------------
 tools/libxc/xg_private.c          |   9 -
 tools/python/xen/lowlevel/xc/xc.c |  81 ----
 6 files changed, 990 deletions(-)
 delete mode 100644 tools/libxc/xc_hvm_build_arm.c
 delete mode 100644 tools/libxc/xc_hvm_build_x86.c

diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index b45380c..efffb8d 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -91,9 +91,7 @@ GUEST_SRCS-y                 += xc_dom_compat_linux.c
 
 GUEST_SRCS-$(CONFIG_X86)     += xc_dom_x86.c
 GUEST_SRCS-$(CONFIG_X86)     += xc_cpuid_x86.c
-GUEST_SRCS-$(CONFIG_X86)     += xc_hvm_build_x86.c
 GUEST_SRCS-$(CONFIG_ARM)     += xc_dom_arm.c
-GUEST_SRCS-$(CONFIG_ARM)     += xc_hvm_build_arm.c
 
 ifeq ($(CONFIG_LIBXC_MINIOS),y)
 GUEST_SRCS-y                 += xc_dom_decompress_unsafe.c
diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index 1a1a185..ec67fbd 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -205,50 +205,6 @@ struct xc_hvm_firmware_module {
     uint64_t  guest_addr_out;
 };
 
-struct xc_hvm_build_args {
-    uint64_t mem_size;           /* Memory size in bytes. */
-    uint64_t mem_target;         /* Memory target in bytes. */
-    uint64_t mmio_size;          /* Size of the MMIO hole in bytes. */
-    const char *image_file_name; /* File name of the image to load. */
-
-    /* Extra ACPI tables passed to HVMLOADER */
-    struct xc_hvm_firmware_module acpi_module;
-
-    /* Extra SMBIOS structures passed to HVMLOADER */
-    struct xc_hvm_firmware_module smbios_module;
-    /* Whether to use claim hypercall (1 - enable, 0 - disable). */
-    int claim_enabled;
-
-    /* vNUMA information*/
-    xen_vmemrange_t *vmemranges;
-    unsigned int nr_vmemranges;
-    unsigned int *vnode_to_pnode;
-    unsigned int nr_vnodes;
-
-    /* Out parameters  */
-    uint64_t lowmem_end;
-    uint64_t highmem_end;
-    uint64_t mmio_start;
-};
-
-/**
- * Build a HVM domain.
- * @parm xch      libxc context handle.
- * @parm domid    domain ID for the new domain.
- * @parm hvm_args parameters for the new domain.
- *
- * The memory size and image file parameters are required, the rest
- * are optional.
- */
-int xc_hvm_build(xc_interface *xch, uint32_t domid,
-                 struct xc_hvm_build_args *hvm_args);
-
-int xc_hvm_build_target_mem(xc_interface *xch,
-                            uint32_t domid,
-                            int memsize,
-                            int target,
-                            const char *image_name);
-
 /*
  * Sets *lockfd to -1.
  * Has deallocated everything even on error.
diff --git a/tools/libxc/xc_hvm_build_arm.c b/tools/libxc/xc_hvm_build_arm.c
deleted file mode 100644
index 14f7c45..0000000
--- a/tools/libxc/xc_hvm_build_arm.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/******************************************************************************
- * 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/>.
- *
- * Copyright (c) 2011, Citrix Systems
- */
-
-#include <inttypes.h>
-#include <errno.h>
-#include <xenctrl.h>
-#include <xenguest.h>
-
-int xc_hvm_build(xc_interface *xch, uint32_t domid,
-                 struct xc_hvm_build_args *hvm_args)
-{
-    errno = ENOSYS;
-    return -1;
-}
-
-int xc_hvm_build_target_mem(xc_interface *xch,
-                           uint32_t domid,
-                           int memsize,
-                           int target,
-                           const char *image_name)
-{
-    errno = ENOSYS;
-    return -1;
-}
-
-/*
- * 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_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
deleted file mode 100644
index 6f79686..0000000
--- a/tools/libxc/xc_hvm_build_x86.c
+++ /dev/null
@@ -1,806 +0,0 @@
-/******************************************************************************
- * xc_hvm_build.c
- *
- * 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/>.
- */
-
-#include <stddef.h>
-#include <inttypes.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <zlib.h>
-
-#include "xg_private.h"
-#include "xc_private.h"
-
-#include <xen/foreign/x86_32.h>
-#include <xen/foreign/x86_64.h>
-#include <xen/hvm/hvm_info_table.h>
-#include <xen/hvm/params.h>
-#include <xen/hvm/e820.h>
-
-#include <xen/libelf/libelf.h>
-
-#define SUPERPAGE_2MB_SHIFT   9
-#define SUPERPAGE_2MB_NR_PFNS (1UL << SUPERPAGE_2MB_SHIFT)
-#define SUPERPAGE_1GB_SHIFT   18
-#define SUPERPAGE_1GB_NR_PFNS (1UL << SUPERPAGE_1GB_SHIFT)
-
-#define SPECIALPAGE_PAGING   0
-#define SPECIALPAGE_ACCESS   1
-#define SPECIALPAGE_SHARING  2
-#define SPECIALPAGE_BUFIOREQ 3
-#define SPECIALPAGE_XENSTORE 4
-#define SPECIALPAGE_IOREQ    5
-#define SPECIALPAGE_IDENT_PT 6
-#define SPECIALPAGE_CONSOLE  7
-#define NR_SPECIAL_PAGES     8
-#define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x))
-
-#define NR_IOREQ_SERVER_PAGES 8
-#define ioreq_server_pfn(x) (special_pfn(0) - NR_IOREQ_SERVER_PAGES + (x))
-
-#define VGA_HOLE_SIZE (0x20)
-
-static int modules_init(struct xc_hvm_build_args *args,
-                        uint64_t vend, struct elf_binary *elf,
-                        uint64_t *mstart_out, uint64_t *mend_out)
-{
-#define MODULE_ALIGN 1UL << 7
-#define MB_ALIGN     1UL << 20
-#define MKALIGN(x, a) (((uint64_t)(x) + (a) - 1) & ~(uint64_t)((a) - 1))
-    uint64_t total_len = 0, offset1 = 0;
-
-    if ( (args->acpi_module.length == 0)&&(args->smbios_module.length == 0) )
-        return 0;
-
-    /* Find the total length for the firmware modules with a reasonable large
-     * alignment size to align each the modules.
-     */
-    total_len = MKALIGN(args->acpi_module.length, MODULE_ALIGN);
-    offset1 = total_len;
-    total_len += MKALIGN(args->smbios_module.length, MODULE_ALIGN);
-
-    /* Want to place the modules 1Mb+change behind the loader image. */
-    *mstart_out = MKALIGN(elf->pend, MB_ALIGN) + (MB_ALIGN);
-    *mend_out = *mstart_out + total_len;
-
-    if ( *mend_out > vend )    
-        return -1;
-
-    if ( args->acpi_module.length != 0 )
-        args->acpi_module.guest_addr_out = *mstart_out;
-    if ( args->smbios_module.length != 0 )
-        args->smbios_module.guest_addr_out = *mstart_out + offset1;
-
-    return 0;
-}
-
-static void build_hvm_info(void *hvm_info_page,
-                           struct xc_hvm_build_args *args)
-{
-    struct hvm_info_table *hvm_info = (struct hvm_info_table *)
-        (((unsigned char *)hvm_info_page) + HVM_INFO_OFFSET);
-    uint8_t sum;
-    int i;
-
-    memset(hvm_info_page, 0, PAGE_SIZE);
-
-    /* Fill in the header. */
-    memcpy(hvm_info->signature, "HVM INFO", sizeof(hvm_info->signature));
-    hvm_info->length = sizeof(struct hvm_info_table);
-
-    /* Sensible defaults: these can be overridden by the caller. */
-    hvm_info->apic_mode = 1;
-    hvm_info->nr_vcpus = 1;
-    memset(hvm_info->vcpu_online, 0xff, sizeof(hvm_info->vcpu_online));
-
-    /* Memory parameters. */
-    hvm_info->low_mem_pgend = args->lowmem_end >> PAGE_SHIFT;
-    hvm_info->high_mem_pgend = args->highmem_end >> PAGE_SHIFT;
-    hvm_info->reserved_mem_pgstart = ioreq_server_pfn(0);
-
-    /* Finish with the checksum. */
-    for ( i = 0, sum = 0; i < hvm_info->length; i++ )
-        sum += ((uint8_t *)hvm_info)[i];
-    hvm_info->checksum = -sum;
-}
-
-static int loadelfimage(xc_interface *xch, struct elf_binary *elf,
-                        uint32_t dom, unsigned long *parray)
-{
-    privcmd_mmap_entry_t *entries = NULL;
-    unsigned long pfn_start = elf->pstart >> PAGE_SHIFT;
-    unsigned long pfn_end = (elf->pend + PAGE_SIZE - 1) >> PAGE_SHIFT;
-    size_t pages = pfn_end - pfn_start;
-    int i, rc = -1;
-
-    /* Map address space for initial elf image. */
-    entries = calloc(pages, sizeof(privcmd_mmap_entry_t));
-    if ( entries == NULL )
-        goto err;
-
-    for ( i = 0; i < pages; i++ )
-        entries[i].mfn = parray[(elf->pstart >> PAGE_SHIFT) + i];
-
-    elf->dest_base = xc_map_foreign_ranges(
-        xch, dom, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT,
-        entries, pages);
-    if ( elf->dest_base == NULL )
-        goto err;
-    elf->dest_size = pages * PAGE_SIZE;
-
-    ELF_ADVANCE_DEST(elf, elf->pstart & (PAGE_SIZE - 1));
-
-    /* Load the initial elf image. */
-    rc = elf_load_binary(elf);
-    if ( rc < 0 )
-        PERROR("Failed to load elf binary\n");
-
-    munmap(elf->dest_base, pages << PAGE_SHIFT);
-    elf->dest_base = NULL;
-    elf->dest_size = 0;
-
- err:
-    free(entries);
-
-    return rc;
-}
-
-static int loadmodules(xc_interface *xch,
-                       struct xc_hvm_build_args *args,
-                       uint64_t mstart, uint64_t mend,
-                       uint32_t dom, unsigned long *parray)
-{
-    privcmd_mmap_entry_t *entries = NULL;
-    unsigned long pfn_start;
-    unsigned long pfn_end;
-    size_t pages;
-    uint32_t i;
-    uint8_t *dest;
-    int rc = -1;
-
-    if ( (mstart == 0)||(mend == 0) )
-        return 0;
-
-    pfn_start = (unsigned long)(mstart >> PAGE_SHIFT);
-    pfn_end = (unsigned long)((mend + PAGE_SIZE - 1) >> PAGE_SHIFT);
-    pages = pfn_end - pfn_start;
-
-    /* Map address space for module list. */
-    entries = calloc(pages, sizeof(privcmd_mmap_entry_t));
-    if ( entries == NULL )
-        goto error_out;
-
-    for ( i = 0; i < pages; i++ )
-        entries[i].mfn = parray[(mstart >> PAGE_SHIFT) + i];
-
-    dest = xc_map_foreign_ranges(
-        xch, dom, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT,
-        entries, pages);
-    if ( dest == NULL )
-        goto error_out;
-
-    /* Zero the range so padding is clear between modules */
-    memset(dest, 0, pages << PAGE_SHIFT);
-
-    /* Load modules into range */    
-    if ( args->acpi_module.length != 0 )
-    {
-        memcpy(dest,
-               args->acpi_module.data,
-               args->acpi_module.length);
-    }
-    if ( args->smbios_module.length != 0 )
-    {
-        memcpy(dest + (args->smbios_module.guest_addr_out - mstart),
-               args->smbios_module.data,
-               args->smbios_module.length);
-    }
-
-    munmap(dest, pages << PAGE_SHIFT);
-    rc = 0;
-
- error_out:
-    free(entries);
-
-    return rc;
-}
-
-/*
- * Check whether there exists mmio hole in the specified memory range.
- * Returns 1 if exists, else returns 0.
- */
-static int check_mmio_hole(uint64_t start, uint64_t memsize,
-                           uint64_t mmio_start, uint64_t mmio_size)
-{
-    if ( start + memsize <= mmio_start || start >= mmio_start + mmio_size )
-        return 0;
-    else
-        return 1;
-}
-
-static int xc_hvm_populate_memory(xc_interface *xch, uint32_t dom,
-                                  struct xc_hvm_build_args *args,
-                                  xen_pfn_t *page_array)
-{
-    unsigned long i, vmemid, nr_pages = args->mem_size >> PAGE_SHIFT;
-    unsigned long p2m_size;
-    unsigned long target_pages = args->mem_target >> PAGE_SHIFT;
-    unsigned long cur_pages, cur_pfn;
-    int rc;
-    xen_capabilities_info_t caps;
-    unsigned long stat_normal_pages = 0, stat_2mb_pages = 0, 
-        stat_1gb_pages = 0;
-    unsigned int memflags = 0;
-    int claim_enabled = args->claim_enabled;
-    uint64_t total_pages;
-    xen_vmemrange_t dummy_vmemrange[2];
-    unsigned int dummy_vnode_to_pnode[1];
-    xen_vmemrange_t *vmemranges;
-    unsigned int *vnode_to_pnode;
-    unsigned int nr_vmemranges, nr_vnodes;
-
-    if ( nr_pages > target_pages )
-        memflags |= XENMEMF_populate_on_demand;
-
-    if ( args->nr_vmemranges == 0 )
-    {
-        /* Build dummy vnode information
-         *
-         * Guest physical address space layout:
-         * [0, hole_start) [hole_start, 4G) [4G, highmem_end)
-         *
-         * Of course if there is no high memory, the second vmemrange
-         * has no effect on the actual result.
-         */
-
-        dummy_vmemrange[0].start = 0;
-        dummy_vmemrange[0].end   = args->lowmem_end;
-        dummy_vmemrange[0].flags = 0;
-        dummy_vmemrange[0].nid   = 0;
-        nr_vmemranges = 1;
-
-        if ( args->highmem_end > (1ULL << 32) )
-        {
-            dummy_vmemrange[1].start = 1ULL << 32;
-            dummy_vmemrange[1].end   = args->highmem_end;
-            dummy_vmemrange[1].flags = 0;
-            dummy_vmemrange[1].nid   = 0;
-
-            nr_vmemranges++;
-        }
-
-        dummy_vnode_to_pnode[0] = XC_NUMA_NO_NODE;
-        nr_vnodes = 1;
-        vmemranges = dummy_vmemrange;
-        vnode_to_pnode = dummy_vnode_to_pnode;
-    }
-    else
-    {
-        if ( nr_pages > target_pages )
-        {
-            PERROR("Cannot enable vNUMA and PoD at the same time");
-            goto error_out;
-        }
-
-        nr_vmemranges = args->nr_vmemranges;
-        nr_vnodes = args->nr_vnodes;
-        vmemranges = args->vmemranges;
-        vnode_to_pnode = args->vnode_to_pnode;
-    }
-
-    total_pages = 0;
-    p2m_size = 0;
-    for ( i = 0; i < nr_vmemranges; i++ )
-    {
-        total_pages += ((vmemranges[i].end - vmemranges[i].start)
-                        >> PAGE_SHIFT);
-        p2m_size = p2m_size > (vmemranges[i].end >> PAGE_SHIFT) ?
-            p2m_size : (vmemranges[i].end >> PAGE_SHIFT);
-    }
-
-    if ( total_pages != (args->mem_size >> PAGE_SHIFT) )
-    {
-        PERROR("vNUMA memory pages mismatch (0x%"PRIx64" != 0x%"PRIx64")",
-               total_pages, args->mem_size >> PAGE_SHIFT);
-        goto error_out;
-    }
-
-    if ( xc_version(xch, XENVER_capabilities, &caps) != 0 )
-    {
-        PERROR("Could not get Xen capabilities");
-        goto error_out;
-    }
-
-    for ( i = 0; i < p2m_size; i++ )
-        page_array[i] = ((xen_pfn_t)-1);
-    for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
-    {
-        uint64_t pfn;
-
-        for ( pfn = vmemranges[vmemid].start >> PAGE_SHIFT;
-              pfn < vmemranges[vmemid].end >> PAGE_SHIFT;
-              pfn++ )
-            page_array[pfn] = pfn;
-    }
-
-    /*
-     * Try to claim pages for early warning of insufficient memory available.
-     * This should go before xc_domain_set_pod_target, becuase that function
-     * actually allocates memory for the guest. Claiming after memory has been
-     * allocated is pointless.
-     */
-    if ( claim_enabled ) {
-        rc = xc_domain_claim_pages(xch, dom, target_pages - VGA_HOLE_SIZE);
-        if ( rc != 0 )
-        {
-            PERROR("Could not allocate memory for HVM guest as we cannot claim memory!");
-            goto error_out;
-        }
-    }
-
-    if ( memflags & XENMEMF_populate_on_demand )
-    {
-        /*
-         * Subtract VGA_HOLE_SIZE from target_pages for the VGA
-         * "hole".  Xen will adjust the PoD cache size so that domain
-         * tot_pages will be target_pages - VGA_HOLE_SIZE after
-         * this call.
-         */
-        rc = xc_domain_set_pod_target(xch, dom,
-                                      target_pages - VGA_HOLE_SIZE,
-                                      NULL, NULL, NULL);
-        if ( rc != 0 )
-        {
-            PERROR("Could not set PoD target for HVM guest.\n");
-            goto error_out;
-        }
-    }
-
-    /*
-     * Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000.
-     *
-     * We attempt to allocate 1GB pages if possible. It falls back on 2MB
-     * pages if 1GB allocation fails. 4KB pages will be used eventually if
-     * both fail.
-     * 
-     * Under 2MB mode, we allocate pages in batches of no more than 8MB to 
-     * ensure that we can be preempted and hence dom0 remains responsive.
-     */
-    rc = xc_domain_populate_physmap_exact(
-        xch, dom, 0xa0, 0, memflags, &page_array[0x00]);
-
-    stat_normal_pages = 0;
-    for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
-    {
-        unsigned int new_memflags = memflags;
-        uint64_t end_pages;
-        unsigned int vnode = vmemranges[vmemid].nid;
-        unsigned int pnode = vnode_to_pnode[vnode];
-
-        if ( pnode != XC_NUMA_NO_NODE )
-            new_memflags |= XENMEMF_exact_node(pnode);
-
-        end_pages = vmemranges[vmemid].end >> PAGE_SHIFT;
-        /*
-         * Consider vga hole belongs to the vmemrange that covers
-         * 0xA0000-0xC0000. Note that 0x00000-0xA0000 is populated just
-         * before this loop.
-         */
-        if ( vmemranges[vmemid].start == 0 )
-        {
-            cur_pages = 0xc0;
-            stat_normal_pages += 0xc0;
-        }
-        else
-            cur_pages = vmemranges[vmemid].start >> PAGE_SHIFT;
-
-        while ( (rc == 0) && (end_pages > cur_pages) )
-        {
-            /* Clip count to maximum 1GB extent. */
-            unsigned long count = end_pages - cur_pages;
-            unsigned long max_pages = SUPERPAGE_1GB_NR_PFNS;
-
-            if ( count > max_pages )
-                count = max_pages;
-
-            cur_pfn = page_array[cur_pages];
-
-            /* Take care the corner cases of super page tails */
-            if ( ((cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1)) != 0) &&
-                 (count > (-cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1))) )
-                count = -cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1);
-            else if ( ((count & (SUPERPAGE_1GB_NR_PFNS-1)) != 0) &&
-                      (count > SUPERPAGE_1GB_NR_PFNS) )
-                count &= ~(SUPERPAGE_1GB_NR_PFNS - 1);
-
-            /* Attemp to allocate 1GB super page. Because in each pass
-             * we only allocate at most 1GB, we don't have to clip
-             * super page boundaries.
-             */
-            if ( ((count | cur_pfn) & (SUPERPAGE_1GB_NR_PFNS - 1)) == 0 &&
-                 /* Check if there exists MMIO hole in the 1GB memory
-                  * range */
-                 !check_mmio_hole(cur_pfn << PAGE_SHIFT,
-                                  SUPERPAGE_1GB_NR_PFNS << PAGE_SHIFT,
-                                  args->mmio_start, args->mmio_size) )
-            {
-                long done;
-                unsigned long nr_extents = count >> SUPERPAGE_1GB_SHIFT;
-                xen_pfn_t sp_extents[nr_extents];
-
-                for ( i = 0; i < nr_extents; i++ )
-                    sp_extents[i] =
-                        page_array[cur_pages+(i<<SUPERPAGE_1GB_SHIFT)];
-
-                done = xc_domain_populate_physmap(xch, dom, nr_extents,
-                                                  SUPERPAGE_1GB_SHIFT,
-                                                  memflags, sp_extents);
-
-                if ( done > 0 )
-                {
-                    stat_1gb_pages += done;
-                    done <<= SUPERPAGE_1GB_SHIFT;
-                    cur_pages += done;
-                    count -= done;
-                }
-            }
-
-            if ( count != 0 )
-            {
-                /* Clip count to maximum 8MB extent. */
-                max_pages = SUPERPAGE_2MB_NR_PFNS * 4;
-                if ( count > max_pages )
-                    count = max_pages;
-
-                /* Clip partial superpage extents to superpage
-                 * boundaries. */
-                if ( ((cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1)) != 0) &&
-                     (count > (-cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1))) )
-                    count = -cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1);
-                else if ( ((count & (SUPERPAGE_2MB_NR_PFNS-1)) != 0) &&
-                          (count > SUPERPAGE_2MB_NR_PFNS) )
-                    count &= ~(SUPERPAGE_2MB_NR_PFNS - 1); /* clip non-s.p. tail */
-
-                /* Attempt to allocate superpage extents. */
-                if ( ((count | cur_pfn) & (SUPERPAGE_2MB_NR_PFNS - 1)) == 0 )
-                {
-                    long done;
-                    unsigned long nr_extents = count >> SUPERPAGE_2MB_SHIFT;
-                    xen_pfn_t sp_extents[nr_extents];
-
-                    for ( i = 0; i < nr_extents; i++ )
-                        sp_extents[i] =
-                            page_array[cur_pages+(i<<SUPERPAGE_2MB_SHIFT)];
-
-                    done = xc_domain_populate_physmap(xch, dom, nr_extents,
-                                                      SUPERPAGE_2MB_SHIFT,
-                                                      memflags, sp_extents);
-
-                    if ( done > 0 )
-                    {
-                        stat_2mb_pages += done;
-                        done <<= SUPERPAGE_2MB_SHIFT;
-                        cur_pages += done;
-                        count -= done;
-                    }
-                }
-            }
-
-            /* Fall back to 4kB extents. */
-            if ( count != 0 )
-            {
-                rc = xc_domain_populate_physmap_exact(
-                    xch, dom, count, 0, new_memflags, &page_array[cur_pages]);
-                cur_pages += count;
-                stat_normal_pages += count;
-            }
-        }
-
-        if ( rc != 0 )
-            break;
-    }
-
-    if ( rc != 0 )
-    {
-        PERROR("Could not allocate memory for HVM guest.");
-        goto error_out;
-    }
-
-    DPRINTF("PHYSICAL MEMORY ALLOCATION:\n");
-    DPRINTF("  4KB PAGES: 0x%016lx\n", stat_normal_pages);
-    DPRINTF("  2MB PAGES: 0x%016lx\n", stat_2mb_pages);
-    DPRINTF("  1GB PAGES: 0x%016lx\n", stat_1gb_pages);
-
-    rc = 0;
-    goto out;
- error_out:
-    rc = -1;
- out:
-
-    /* ensure no unclaimed pages are left unused */
-    xc_domain_claim_pages(xch, dom, 0 /* cancels the claim */);
-
-    return rc;
-}
-
-static int xc_hvm_load_image(xc_interface *xch,
-                       uint32_t dom, struct xc_hvm_build_args *args,
-                       xen_pfn_t *page_array)
-{
-    unsigned long entry_eip, image_size;
-    struct elf_binary elf;
-    uint64_t v_start, v_end;
-    uint64_t m_start = 0, m_end = 0;
-    char *image;
-    int rc;
-
-    image = xc_read_image(xch, args->image_file_name, &image_size);
-    if ( image == NULL )
-        return -1;
-
-    memset(&elf, 0, sizeof(elf));
-    if ( elf_init(&elf, image, image_size) != 0 )
-        goto error_out;
-
-    xc_elf_set_logfile(xch, &elf, 1);
-
-    elf_parse_binary(&elf);
-    v_start = 0;
-    v_end = args->mem_size;
-
-    if ( modules_init(args, v_end, &elf, &m_start, &m_end) != 0 )
-    {
-        ERROR("Insufficient space to load modules.");
-        goto error_out;
-    }
-
-    DPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
-    DPRINTF("  Loader:   %016"PRIx64"->%016"PRIx64"\n", elf.pstart, elf.pend);
-    DPRINTF("  Modules:  %016"PRIx64"->%016"PRIx64"\n", m_start, m_end);
-
-    if ( loadelfimage(xch, &elf, dom, page_array) != 0 )
-    {
-        PERROR("Could not load ELF image");
-        goto error_out;
-    }
-
-    if ( loadmodules(xch, args, m_start, m_end, dom, page_array) != 0 )
-    {
-        PERROR("Could not load ACPI modules");
-        goto error_out;
-    }
-
-    /* Insert JMP <rel32> instruction at address 0x0 to reach entry point. */
-    entry_eip = elf_uval(&elf, elf.ehdr, e_entry);
-    if ( entry_eip != 0 )
-    {
-        char *page0 = xc_map_foreign_range(
-            xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, 0);
-        if ( page0 == NULL )
-            goto error_out;
-        page0[0] = 0xe9;
-        *(uint32_t *)&page0[1] = entry_eip - 5;
-        munmap(page0, PAGE_SIZE);
-    }
-
-    rc = 0;
-    goto out;
- error_out:
-    rc = -1;
- out:
-    if ( elf_check_broken(&elf) )
-        ERROR("HVM ELF broken: %s", elf_check_broken(&elf));
-    free(image);
-
-    return rc;
-}
-
-static int xc_hvm_populate_params(xc_interface *xch, uint32_t dom,
-                                  struct xc_hvm_build_args *args)
-{
-    unsigned long i;
-    void *hvm_info_page;
-    uint32_t *ident_pt;
-    uint64_t v_end;
-    int rc;
-    xen_pfn_t special_array[NR_SPECIAL_PAGES];
-    xen_pfn_t ioreq_server_array[NR_IOREQ_SERVER_PAGES];
-
-    v_end = args->mem_size;
-
-    if ( (hvm_info_page = xc_map_foreign_range(
-              xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
-              HVM_INFO_PFN)) == NULL )
-    {
-        PERROR("Could not map hvm info page");
-        goto error_out;
-    }
-    build_hvm_info(hvm_info_page, args);
-    munmap(hvm_info_page, PAGE_SIZE);
-
-    /* Allocate and clear special pages. */
-    for ( i = 0; i < NR_SPECIAL_PAGES; i++ )
-        special_array[i] = special_pfn(i);
-
-    rc = xc_domain_populate_physmap_exact(xch, dom, NR_SPECIAL_PAGES, 0, 0,
-                                          special_array);
-    if ( rc != 0 )
-    {
-        PERROR("Could not allocate special pages.");
-        goto error_out;
-    }
-
-    if ( xc_clear_domain_pages(xch, dom, special_pfn(0), NR_SPECIAL_PAGES) )
-    {
-        PERROR("Could not clear special pages");
-        goto error_out;
-    }
-
-    xc_hvm_param_set(xch, dom, HVM_PARAM_STORE_PFN,
-                     special_pfn(SPECIALPAGE_XENSTORE));
-    xc_hvm_param_set(xch, dom, HVM_PARAM_BUFIOREQ_PFN,
-                     special_pfn(SPECIALPAGE_BUFIOREQ));
-    xc_hvm_param_set(xch, dom, HVM_PARAM_IOREQ_PFN,
-                     special_pfn(SPECIALPAGE_IOREQ));
-    xc_hvm_param_set(xch, dom, HVM_PARAM_CONSOLE_PFN,
-                     special_pfn(SPECIALPAGE_CONSOLE));
-    xc_hvm_param_set(xch, dom, HVM_PARAM_PAGING_RING_PFN,
-                     special_pfn(SPECIALPAGE_PAGING));
-    xc_hvm_param_set(xch, dom, HVM_PARAM_MONITOR_RING_PFN,
-                     special_pfn(SPECIALPAGE_ACCESS));
-    xc_hvm_param_set(xch, dom, HVM_PARAM_SHARING_RING_PFN,
-                     special_pfn(SPECIALPAGE_SHARING));
-
-    /*
-     * Allocate and clear additional ioreq server pages. The default
-     * server will use the IOREQ and BUFIOREQ special pages above.
-     */
-    for ( i = 0; i < NR_IOREQ_SERVER_PAGES; i++ )
-        ioreq_server_array[i] = ioreq_server_pfn(i);
-
-    rc = xc_domain_populate_physmap_exact(xch, dom, NR_IOREQ_SERVER_PAGES, 0, 0,
-                                          ioreq_server_array);
-    if ( rc != 0 )
-    {
-        PERROR("Could not allocate ioreq server pages.");
-        goto error_out;
-    }
-
-    if ( xc_clear_domain_pages(xch, dom, ioreq_server_pfn(0), NR_IOREQ_SERVER_PAGES) )
-    {
-        PERROR("Could not clear ioreq page");
-        goto error_out;
-    }
-
-    /* Tell the domain where the pages are and how many there are */
-    xc_hvm_param_set(xch, dom, HVM_PARAM_IOREQ_SERVER_PFN,
-                     ioreq_server_pfn(0));
-    xc_hvm_param_set(xch, dom, HVM_PARAM_NR_IOREQ_SERVER_PAGES,
-                     NR_IOREQ_SERVER_PAGES);
-
-    /*
-     * Identity-map page table is required for running with CR0.PG=0 when
-     * using Intel EPT. Create a 32-bit non-PAE page directory of superpages.
-     */
-    if ( (ident_pt = xc_map_foreign_range(
-              xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
-              special_pfn(SPECIALPAGE_IDENT_PT))) == NULL )
-    {
-        PERROR("Could not map special page ident_pt");
-        goto error_out;
-    }
-    for ( i = 0; i < PAGE_SIZE / sizeof(*ident_pt); i++ )
-        ident_pt[i] = ((i << 22) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER |
-                       _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE);
-    munmap(ident_pt, PAGE_SIZE);
-    xc_hvm_param_set(xch, dom, HVM_PARAM_IDENT_PT,
-                     special_pfn(SPECIALPAGE_IDENT_PT) << PAGE_SHIFT);
-
-    rc = 0;
-    goto out;
- error_out:
-    rc = -1;
- out:
-
-    return rc;
-}
-
-/* xc_hvm_build:
- * Create a domain for a virtualized Linux, using files/filenames.
- */
-int xc_hvm_build(xc_interface *xch, uint32_t domid,
-                 struct xc_hvm_build_args *hvm_args)
-{
-    struct xc_hvm_build_args args = *hvm_args;
-    xen_pfn_t *parray = NULL;
-    int rc;
-
-    if ( domid == 0 )
-        return -1;
-    if ( args.image_file_name == NULL )
-        return -1;
-
-    /* An HVM guest must be initialised with at least 2MB memory. */
-    if ( args.mem_size < (2ull << 20) || args.mem_target < (2ull << 20) )
-        return -1;
-
-    parray = malloc((args.mem_size >> PAGE_SHIFT) * sizeof(xen_pfn_t));
-    if ( parray == NULL )
-        return -1;
-
-    rc = xc_hvm_populate_memory(xch, domid, &args, parray);
-    if ( rc != 0 )
-    {
-        PERROR("xc_hvm_populate_memory failed");
-        goto out;
-    }
-    rc = xc_hvm_load_image(xch, domid, &args, parray);
-    if ( rc != 0 )
-    {
-        PERROR("xc_hvm_load_image failed");
-        goto out;
-    }
-    rc = xc_hvm_populate_params(xch, domid, &args);
-    if ( rc != 0 )
-    {
-        PERROR("xc_hvm_populate_params failed");
-        goto out;
-    }
-
-    /* Return module load addresses to caller */
-    hvm_args->acpi_module.guest_addr_out = args.acpi_module.guest_addr_out;
-    hvm_args->smbios_module.guest_addr_out = args.smbios_module.guest_addr_out;
-
-out:
-    free(parray);
-
-    return rc;
-}
-
-/* xc_hvm_build_target_mem: 
- * Create a domain for a pre-ballooned virtualized Linux, using
- * files/filenames.  If target < memsize, domain is created with
- * memsize pages marked populate-on-demand, 
- * calculating pod cache size based on target.
- * If target == memsize, pages are populated normally.
- */
-int xc_hvm_build_target_mem(xc_interface *xch,
-                           uint32_t domid,
-                           int memsize,
-                           int target,
-                           const char *image_name)
-{
-    struct xc_hvm_build_args args = {};
-
-    memset(&args, 0, sizeof(struct xc_hvm_build_args));
-    args.mem_size = (uint64_t)memsize << 20;
-    args.mem_target = (uint64_t)target << 20;
-    args.image_file_name = image_name;
-    if ( args.mmio_size == 0 )
-        args.mmio_size = HVM_BELOW_4G_MMIO_LENGTH;
-
-    return xc_hvm_build(xch, domid, &args);
-}
-
-/*
- * 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_private.c b/tools/libxc/xg_private.c
index 67946e1..d98f282 100644
--- a/tools/libxc/xg_private.c
+++ b/tools/libxc/xg_private.c
@@ -187,15 +187,6 @@ unsigned long csum_page(void *page)
     return sum ^ (sum>>32);
 }
 
-__attribute__((weak)) 
-    int xc_hvm_build(xc_interface *xch,
-                     uint32_t domid,
-                     struct xc_hvm_build_args *hvm_args)
-{
-    errno = ENOSYS;
-    return -1;
-}
-
 /*
  * Local variables:
  * mode: C
diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c
index 2c36eb2..1fb364c 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -910,77 +910,6 @@ static PyObject *pyxc_dom_suppress_spurious_page_faults(XcObject *self,
 }
 #endif /* __i386__ || __x86_64__ */
 
-static PyObject *pyxc_hvm_build(XcObject *self,
-                                PyObject *args,
-                                PyObject *kwds)
-{
-    uint32_t dom;
-    struct hvm_info_table *va_hvm;
-    uint8_t *va_map, sum;
-    int i;
-    char *image;
-    int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1;
-    PyObject *vcpu_avail_handle = NULL;
-    uint8_t vcpu_avail[(HVM_MAX_VCPUS + 7)/8];
-
-    static char *kwd_list[] = { "domid",
-                                "memsize", "image", "target", "vcpus", 
-                                "vcpu_avail", "acpi", "apic", NULL };
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiOii", kwd_list,
-                                      &dom, &memsize, &image, &target, &vcpus,
-                                      &vcpu_avail_handle, &acpi, &apic) )
-        return NULL;
-
-    memset(vcpu_avail, 0, sizeof(vcpu_avail));
-    vcpu_avail[0] = 1;
-    if ( vcpu_avail_handle != NULL )
-    {
-        if ( PyInt_Check(vcpu_avail_handle) )
-        {
-            unsigned long v = PyInt_AsLong(vcpu_avail_handle);
-            for ( i = 0; i < sizeof(long); i++ )
-                vcpu_avail[i] = (uint8_t)(v>>(i*8));
-        }
-        else if ( PyLong_Check(vcpu_avail_handle) )
-        {
-            if ( _PyLong_AsByteArray((PyLongObject *)vcpu_avail_handle,
-                                     (unsigned char *)vcpu_avail,
-                                     sizeof(vcpu_avail), 1, 0) )
-                return NULL;
-        }
-        else
-        {
-            errno = EINVAL;
-            PyErr_SetFromErrno(xc_error_obj);
-            return NULL;
-        }
-    }
-
-    if ( target == -1 )
-        target = memsize;
-
-    if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize,
-                                 target, image) != 0 )
-        return pyxc_error_to_exception(self->xc_handle);
-
-    /* Fix up the HVM info table. */
-    va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
-                                  PROT_READ | PROT_WRITE,
-                                  HVM_INFO_PFN);
-    if ( va_map == NULL )
-        return PyErr_SetFromErrno(xc_error_obj);
-    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
-    va_hvm->apic_mode    = apic;
-    va_hvm->nr_vcpus     = vcpus;
-    memcpy(va_hvm->vcpu_online, vcpu_avail, sizeof(vcpu_avail));
-    for ( i = 0, sum = 0; i < va_hvm->length; i++ )
-        sum += ((uint8_t *)va_hvm)[i];
-    va_hvm->checksum -= sum;
-    munmap(va_map, XC_PAGE_SIZE);
-
-    return Py_BuildValue("{}");
-}
-
 static PyObject *pyxc_gnttab_hvm_seed(XcObject *self,
 				      PyObject *args,
 				      PyObject *kwds)
@@ -2366,16 +2295,6 @@ static PyMethodDef pyxc_methods[] = {
       " image   [str]:      Name of kernel image file. May be gzipped.\n"
       " cmdline [str, n/a]: Kernel parameters, if any.\n\n"},
 
-    { "hvm_build", 
-      (PyCFunction)pyxc_hvm_build, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
-      "Build a new HVM guest OS.\n"
-      " dom     [int]:      Identifier of domain to build into.\n"
-      " image   [str]:      Name of HVM loader image file.\n"
-      " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
-      " vcpu_avail [long, 1]: Which Virtual CPUS available.\n\n"
-      "Returns: [int] 0 on success; -1 on error.\n" },
-
     { "gnttab_hvm_seed",
       (PyCFunction)pyxc_gnttab_hvm_seed,
       METH_KEYWORDS, "\n"
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 12/31] xen/x86: add bitmap of enabled emulated devices
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (10 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 11/31] libxc: remove dead HVM building code Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 16:08   ` Andrew Cooper
  2015-08-07 10:17 ` [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic Roger Pau Monne
                   ` (18 subsequent siblings)
  30 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
	Ian Jackson, Jan Beulich, Roger Pau Monne

Introduce a bitmap in x86 xen_arch_domainconfig that allows enabling or
disabling specific devices emulated inside of Xen for HVM guests.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v3:
 - Return EOPNOTSUPP instead of ENOPERM if an invalid emulation mask is
   used.
 - Fix error messages (prefix them with d%d and use %#x instead of 0x%x).
 - Clearly state in the public header that emulation_flags should only be
   used with HVM guests.
 - Add a XEN_X86 prefix to the emulation flags defines.
 - Properly parenthese the has_* marcos.
---
 tools/libxl/libxl_x86.c           |  8 ++++++--
 xen/arch/x86/domain.c             | 18 ++++++++++++++++++
 xen/include/asm-x86/domain.h      | 13 +++++++++++++
 xen/include/public/arch-x86/xen.h | 21 ++++++++++++++++++++-
 4 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
index b887411..270f3cf 100644
--- a/tools/libxl/libxl_x86.c
+++ b/tools/libxl/libxl_x86.c
@@ -7,8 +7,12 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
                                       libxl_domain_config *d_config,
                                       xc_domain_configuration_t *xc_config)
 {
-    /* No specific configuration right now */
-
+    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM)
+        xc_config->emulation_flags = (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET |
+                                      XEN_X86_EMU_PMTIMER | XEN_X86_EMU_RTC |
+                                      XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC |
+                                      XEN_X86_EMU_PMU | XEN_X86_EMU_VGA |
+                                      XEN_X86_EMU_IOMMU);
     return 0;
 }
 
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 045f6ff..c508074 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -533,6 +533,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
 {
     int i, paging_initialised = 0;
     int rc = -ENOMEM;
+    uint32_t emulation_mask;
 
     d->arch.s3_integrity = !!(domcr_flags & DOMCRF_s3_integrity);
 
@@ -555,6 +556,23 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
                d->domain_id);
     }
 
+    if ( is_hvm_domain(d) )
+    {
+        emulation_mask = (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET |
+                          XEN_X86_EMU_PMTIMER | XEN_X86_EMU_RTC |
+                          XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC |
+                          XEN_X86_EMU_PMU | XEN_X86_EMU_VGA |
+                          XEN_X86_EMU_IOMMU);
+        if ( (config->emulation_flags & emulation_mask) != emulation_mask )
+        {
+            printk(XENLOG_G_ERR "d%d: Xen does not allow HVM creation with the "
+                   "current selection of emulators: %#x.\n", d->domain_id,
+                   config->emulation_flags);
+            return -EOPNOTSUPP;
+        }
+        d->arch.emulation_flags = config->emulation_flags;
+    }
+
     if ( has_hvm_container_domain(d) )
     {
         d->arch.hvm_domain.hap_enabled =
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 0fce09e..2527637 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -387,8 +387,21 @@ struct arch_domain
     bool_t mem_access_emulate_enabled;
 
     struct monitor_write_data *event_write_data;
+
+    /* Emulated devices enabled bitmap. */
+    uint32_t emulation_flags;
 } __cacheline_aligned;
 
+#define has_vlapic(d)       ((d)->arch.emulation_flags & XEN_X86_EMU_LAPIC)
+#define has_vhpet(d)        ((d)->arch.emulation_flags & XEN_X86_EMU_HPET)
+#define has_vpmtimer(d)     ((d)->arch.emulation_flags & XEN_X86_EMU_PMTIMER)
+#define has_vrtc(d)         ((d)->arch.emulation_flags & XEN_X86_EMU_RTC)
+#define has_vioapic(d)      ((d)->arch.emulation_flags & XEN_X86_EMU_IOAPIC)
+#define has_vpic(d)         ((d)->arch.emulation_flags & XEN_X86_EMU_PIC)
+#define has_vpmu(d)         ((d)->arch.emulation_flags & XEN_X86_EMU_PMU)
+#define has_vvga(d)         ((d)->arch.emulation_flags & XEN_X86_EMU_VGA)
+#define has_viommu(d)       ((d)->arch.emulation_flags & XEN_X86_EMU_IOMMU)
+
 #define has_arch_pdevs(d)    (!list_empty(&(d)->arch.pdev_list))
 
 #define gdt_ldt_pt_idx(v) \
diff --git a/xen/include/public/arch-x86/xen.h b/xen/include/public/arch-x86/xen.h
index 2ecc9c9..98cae41 100644
--- a/xen/include/public/arch-x86/xen.h
+++ b/xen/include/public/arch-x86/xen.h
@@ -268,7 +268,26 @@ typedef struct arch_shared_info arch_shared_info_t;
  * XEN_DOMCTL_INTERFACE_VERSION.
  */
 struct xen_arch_domainconfig {
-    char dummy;
+#define _XEN_X86_EMU_LAPIC              0
+#define XEN_X86_EMU_LAPIC               (1U<<_XEN_X86_EMU_LAPIC)
+#define _XEN_X86_EMU_HPET               1
+#define XEN_X86_EMU_HPET                (1U<<_XEN_X86_EMU_HPET)
+#define _XEN_X86_EMU_PMTIMER            2
+#define XEN_X86_EMU_PMTIMER             (1U<<_XEN_X86_EMU_PMTIMER)
+#define _XEN_X86_EMU_RTC                3
+#define XEN_X86_EMU_RTC                 (1U<<_XEN_X86_EMU_RTC)
+#define _XEN_X86_EMU_IOAPIC             4
+#define XEN_X86_EMU_IOAPIC              (1U<<_XEN_X86_EMU_IOAPIC)
+#define _XEN_X86_EMU_PIC                5
+#define XEN_X86_EMU_PIC                 (1U<<_XEN_X86_EMU_PIC)
+#define _XEN_X86_EMU_PMU                6
+#define XEN_X86_EMU_PMU                 (1U<<_XEN_X86_EMU_PMU)
+#define _XEN_X86_EMU_VGA                7
+#define XEN_X86_EMU_VGA                 (1U<<_XEN_X86_EMU_VGA)
+#define _XEN_X86_EMU_IOMMU              8
+#define XEN_X86_EMU_IOMMU               (1U<<_XEN_X86_EMU_IOMMU)
+    /* For HVM guests only, this field is ignored for PV guests. */
+    uint32_t emulation_flags;
 };
 #endif
 
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (11 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 12/31] xen/x86: add bitmap of enabled emulated devices Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 14:09   ` Boris Ostrovsky
  2015-08-07 16:29   ` Andrew Cooper
  2015-08-07 10:17 ` [PATCH v4 14/31] xen/x86: allow disabling the emulated HPET Roger Pau Monne
                   ` (17 subsequent siblings)
  30 siblings, 2 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Suravee Suthikulpanit, Jun Nakajima, Andrew Cooper,
	Eddie Dong, Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Roger Pau Monne

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jun Nakajima <jun.nakajima@intel.com>
Cc: Eddie Dong <eddie.dong@intel.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
 xen/arch/x86/hvm/svm/svm.c  | 16 +++++++++-------
 xen/arch/x86/hvm/vlapic.c   | 30 +++++++++++++++++++++++++-----
 xen/arch/x86/hvm/vmsi.c     |  6 ++++++
 xen/arch/x86/hvm/vmx/vmcs.c | 14 ++++++++++++++
 xen/arch/x86/hvm/vmx/vmx.c  |  9 ++++++++-
 5 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 8de41fa..97dc507 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1035,6 +1035,7 @@ static void noreturn svm_do_resume(struct vcpu *v)
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     bool_t debug_state = v->domain->debugger_attached;
     bool_t vcpu_guestmode = 0;
+    struct vlapic *vlapic = vcpu_vlapic(v);
 
     if ( nestedhvm_enabled(v->domain) && nestedhvm_vcpu_in_guestmode(v) )
         vcpu_guestmode = 1;
@@ -1058,14 +1059,14 @@ static void noreturn svm_do_resume(struct vcpu *v)
         hvm_asid_flush_vcpu(v);
     }
 
-    if ( !vcpu_guestmode )
+    if ( !vcpu_guestmode && !vlapic_hw_disabled(vlapic) )
     {
         vintr_t intr;
 
         /* Reflect the vlapic's TPR in the hardware vtpr */
         intr = vmcb_get_vintr(vmcb);
         intr.fields.tpr =
-            (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4;
+            (vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xFF) >> 4;
         vmcb_set_vintr(vmcb, intr);
     }
 
@@ -2294,6 +2295,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
     int inst_len, rc;
     vintr_t intr;
     bool_t vcpu_guestmode = 0;
+    struct vlapic *vlapic = vcpu_vlapic(v);
 
     hvm_invalidate_regs_fields(regs);
 
@@ -2311,11 +2313,11 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
      * NB. We need to preserve the low bits of the TPR to make checked builds
      * of Windows work, even though they don't actually do anything.
      */
-    if ( !vcpu_guestmode ) {
+    if ( !vcpu_guestmode && !vlapic_hw_disabled(vlapic) ) {
         intr = vmcb_get_vintr(vmcb);
-        vlapic_set_reg(vcpu_vlapic(v), APIC_TASKPRI,
+        vlapic_set_reg(vlapic, APIC_TASKPRI,
                    ((intr.fields.tpr & 0x0F) << 4) |
-                   (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0x0F));
+                   (vlapic_get_reg(vlapic, APIC_TASKPRI) & 0x0F));
     }
 
     exit_reason = vmcb->exitcode;
@@ -2697,14 +2699,14 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
     }
 
   out:
-    if ( vcpu_guestmode )
+    if ( vcpu_guestmode || vlapic_hw_disabled(vlapic) )
         /* Don't clobber TPR of the nested guest. */
         return;
 
     /* The exit may have updated the TPR: reflect this in the hardware vtpr */
     intr = vmcb_get_vintr(vmcb);
     intr.fields.tpr =
-        (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4;
+        (vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xFF) >> 4;
     vmcb_set_vintr(vmcb, intr);
 }
 
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index b893b40..e355679 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -993,6 +993,9 @@ static void set_x2apic_id(struct vlapic *vlapic)
 
 bool_t vlapic_msr_set(struct vlapic *vlapic, uint64_t value)
 {
+    if ( !has_vlapic(vlapic_domain(vlapic)) )
+        return 0;
+
     if ( (vlapic->hw.apic_base_msr ^ value) & MSR_IA32_APICBASE_ENABLE )
     {
         if ( unlikely(value & MSR_IA32_APICBASE_EXTD) )
@@ -1042,8 +1045,7 @@ void vlapic_tdt_msr_set(struct vlapic *vlapic, uint64_t value)
     uint64_t guest_tsc;
     struct vcpu *v = vlapic_vcpu(vlapic);
 
-    /* may need to exclude some other conditions like vlapic->hw.disabled */
-    if ( !vlapic_lvtt_tdt(vlapic) )
+    if ( !vlapic_lvtt_tdt(vlapic) || vlapic_hw_disabled(vlapic) )
     {
         HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "ignore tsc deadline msr write");
         return;
@@ -1118,6 +1120,9 @@ static int __vlapic_accept_pic_intr(struct vcpu *v)
 
 int vlapic_accept_pic_intr(struct vcpu *v)
 {
+    if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
+        return 0;
+
     TRACE_2D(TRC_HVM_EMUL_LAPIC_PIC_INTR,
              (v == v->domain->arch.hvm_domain.i8259_target),
              v ? __vlapic_accept_pic_intr(v) : -1);
@@ -1265,6 +1270,9 @@ static int lapic_save_hidden(struct domain *d, hvm_domain_context_t *h)
     struct vlapic *s;
     int rc = 0;
 
+    if ( !has_vlapic(d) )
+        return 0;
+
     for_each_vcpu ( d, v )
     {
         s = vcpu_vlapic(v);
@@ -1281,6 +1289,9 @@ static int lapic_save_regs(struct domain *d, hvm_domain_context_t *h)
     struct vlapic *s;
     int rc = 0;
 
+    if ( !has_vlapic(d) )
+        return 0;
+
     for_each_vcpu ( d, v )
     {
         if ( hvm_funcs.sync_pir_to_irr )
@@ -1328,7 +1339,10 @@ static int lapic_load_hidden(struct domain *d, hvm_domain_context_t *h)
     uint16_t vcpuid;
     struct vcpu *v;
     struct vlapic *s;
-    
+
+    if ( !has_vlapic(d) )
+        return 0;
+
     /* Which vlapic to load? */
     vcpuid = hvm_load_instance(h); 
     if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
@@ -1360,7 +1374,10 @@ static int lapic_load_regs(struct domain *d, hvm_domain_context_t *h)
     uint16_t vcpuid;
     struct vcpu *v;
     struct vlapic *s;
-    
+
+    if ( !has_vlapic(d) )
+        return 0;
+
     /* Which vlapic to load? */
     vcpuid = hvm_load_instance(h); 
     if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
@@ -1399,7 +1416,7 @@ int vlapic_init(struct vcpu *v)
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id);
 
-    if ( is_pvh_vcpu(v) )
+    if ( is_pvh_vcpu(v) || !has_vlapic(v->domain) )
     {
         vlapic->hw.disabled = VLAPIC_HW_DISABLED;
         return 0;
@@ -1452,6 +1469,9 @@ void vlapic_destroy(struct vcpu *v)
 {
     struct vlapic *vlapic = vcpu_vlapic(v);
 
+    if ( !has_vlapic(vlapic_domain(vlapic)) )
+        return;
+
     tasklet_kill(&vlapic->init_sipi.tasklet);
     TRACE_0D(TRC_HVM_EMUL_LAPIC_STOP_TIMER);
     destroy_periodic_time(&vlapic->pt);
diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index ac838a9..e6a145d 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -482,6 +482,9 @@ found:
 
 void msixtbl_init(struct domain *d)
 {
+    if ( !has_vlapic(d) )
+        return;
+
     INIT_LIST_HEAD(&d->arch.hvm_domain.msixtbl_list);
     spin_lock_init(&d->arch.hvm_domain.msixtbl_list_lock);
 
@@ -493,6 +496,9 @@ void msixtbl_pt_cleanup(struct domain *d)
     struct msixtbl_entry *entry, *temp;
     unsigned long flags;
 
+    if ( !has_vlapic(d) )
+        return;
+
     /* msixtbl_list_lock must be acquired with irq_disabled for check_lock() */
     local_irq_save(flags); 
     spin_lock(&d->arch.hvm_domain.msixtbl_list_lock);
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index a0a97e7..5acb246 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1027,6 +1027,20 @@ static int construct_vmcs(struct vcpu *v)
         ASSERT(!(v->arch.hvm_vmx.exec_control & CPU_BASED_RDTSC_EXITING));
     }
 
+    if ( !has_vlapic(d) )
+    {
+        /* Disable virtual apics, TPR */
+        v->arch.hvm_vmx.secondary_exec_control &=
+            ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES
+              | SECONDARY_EXEC_APIC_REGISTER_VIRT
+              | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
+        v->arch.hvm_vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
+
+        /* In turn, disable posted interrupts. */
+        __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
+                  vmx_pin_based_exec_control & ~PIN_BASED_POSTED_INTERRUPT);
+    }
+
     vmx_update_cpu_exec_control(v);
 
     __vmwrite(VM_EXIT_CONTROLS, vmexit_ctl);
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index c32d863..3d242fd 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -89,6 +89,9 @@ static int vmx_domain_initialise(struct domain *d)
 {
     int rc;
 
+    if ( !has_vlapic(d) )
+        return 0;
+
     if ( (rc = vmx_alloc_vlapic_mapping(d)) != 0 )
         return rc;
 
@@ -97,6 +100,9 @@ static int vmx_domain_initialise(struct domain *d)
 
 static void vmx_domain_destroy(struct domain *d)
 {
+    if ( !has_vlapic(d) )
+        return;
+
     vmx_free_vlapic_mapping(d);
 }
 
@@ -2390,7 +2396,8 @@ static void vmx_install_vlapic_mapping(struct vcpu *v)
 {
     paddr_t virt_page_ma, apic_page_ma;
 
-    if ( !cpu_has_vmx_virtualize_apic_accesses )
+    if ( !cpu_has_vmx_virtualize_apic_accesses ||
+         v->domain->arch.hvm_domain.vmx.apic_access_mfn == 0 )
         return;
 
     virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page);
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 14/31] xen/x86: allow disabling the emulated HPET
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (12 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 15/31] xen/x86: allow disabling the pmtimer Roger Pau Monne
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/hpet.c | 13 +++++++++++++
 xen/arch/x86/hvm/hvm.c  |  1 -
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c
index edf9a17..266b587 100644
--- a/xen/arch/x86/hvm/hpet.c
+++ b/xen/arch/x86/hvm/hpet.c
@@ -516,6 +516,9 @@ static int hpet_save(struct domain *d, hvm_domain_context_t *h)
     int rc;
     uint64_t guest_time;
 
+    if ( !has_vhpet(d) )
+        return 0;
+
     write_lock(&hp->lock);
     guest_time = guest_time_hpet(hp);
 
@@ -575,6 +578,9 @@ static int hpet_load(struct domain *d, hvm_domain_context_t *h)
     uint64_t guest_time;
     int i;
 
+    if ( !has_vhpet(d) )
+        return 0;
+
     write_lock(&hp->lock);
 
     /* Reload the HPET registers */
@@ -633,6 +639,9 @@ void hpet_init(struct domain *d)
     HPETState *h = domain_vhpet(d);
     int i;
 
+    if ( !has_vhpet(d) )
+        return;
+
     memset(h, 0, sizeof(HPETState));
 
     rwlock_init(&h->lock);
@@ -660,6 +669,7 @@ void hpet_init(struct domain *d)
     }
 
     register_mmio_handler(d, &hpet_mmio_ops);
+    d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1;
 }
 
 void hpet_deinit(struct domain *d)
@@ -667,6 +677,9 @@ void hpet_deinit(struct domain *d)
     int i;
     HPETState *h = domain_vhpet(d);
 
+    if ( !has_vhpet(d) )
+        return;
+
     write_lock(&h->lock);
 
     if ( hpet_enabled(h) )
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c957610..c778a20 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1594,7 +1594,6 @@ int hvm_domain_initialise(struct domain *d)
 
     hvm_init_guest_time(d);
 
-    d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1;
     d->arch.hvm_domain.params[HVM_PARAM_TRIPLE_FAULT_REASON] = SHUTDOWN_reboot;
 
     vpic_init(d);
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 15/31] xen/x86: allow disabling the pmtimer
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (13 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 14/31] xen/x86: allow disabling the emulated HPET Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 16/31] xen/x86: allow disabling the emulated RTC Roger Pau Monne
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/pmtimer.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c
index 07594e1..199a15e 100644
--- a/xen/arch/x86/hvm/pmtimer.c
+++ b/xen/arch/x86/hvm/pmtimer.c
@@ -247,6 +247,9 @@ static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
     uint32_t x, msb = s->pm.tmr_val & TMR_VAL_MSB;
     int rc;
 
+    if ( !has_vpmtimer(d) )
+        return 0;
+
     spin_lock(&s->lock);
 
     /* Update the counter to the guest's current time.  We always save
@@ -271,6 +274,9 @@ static int pmtimer_load(struct domain *d, hvm_domain_context_t *h)
 {
     PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
 
+    if ( !has_vpmtimer(d) )
+        return 0;
+
     spin_lock(&s->lock);
 
     /* Reload the registers */
@@ -328,6 +334,9 @@ void pmtimer_init(struct vcpu *v)
 {
     PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
 
+    if ( !has_vpmtimer(v->domain) )
+        return;
+
     spin_lock_init(&s->lock);
 
     s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / SYSTEM_TIME_HZ;
@@ -348,6 +357,10 @@ void pmtimer_init(struct vcpu *v)
 void pmtimer_deinit(struct domain *d)
 {
     PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+
+    if ( !has_vpmtimer(d) )
+        return;
+
     kill_timer(&s->timer);
 }
 
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 16/31] xen/x86: allow disabling the emulated RTC
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (14 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 15/31] xen/x86: allow disabling the pmtimer Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 17/31] xen/x86: allow disabling the emulated IO APIC Roger Pau Monne
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/rtc.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/xen/arch/x86/hvm/rtc.c b/xen/arch/x86/hvm/rtc.c
index a9efeaf..bc93f66 100644
--- a/xen/arch/x86/hvm/rtc.c
+++ b/xen/arch/x86/hvm/rtc.c
@@ -726,6 +726,9 @@ void rtc_migrate_timers(struct vcpu *v)
 {
     RTCState *s = vcpu_vrtc(v);
 
+    if ( !has_vrtc(v->domain) )
+        return;
+
     if ( v->vcpu_id == 0 )
     {
         migrate_timer(&s->update_timer, v->processor);;
@@ -739,6 +742,10 @@ static int rtc_save(struct domain *d, hvm_domain_context_t *h)
 {
     RTCState *s = domain_vrtc(d);
     int rc;
+
+    if ( !has_vrtc(d) )
+        return 0;
+
     spin_lock(&s->lock);
     rc = hvm_save_entry(RTC, 0, h, &s->hw);
     spin_unlock(&s->lock);
@@ -750,6 +757,9 @@ static int rtc_load(struct domain *d, hvm_domain_context_t *h)
 {
     RTCState *s = domain_vrtc(d);
 
+    if ( !has_vrtc(d) )
+        return 0;
+
     spin_lock(&s->lock);
 
     /* Restore the registers */
@@ -790,6 +800,9 @@ void rtc_init(struct domain *d)
 {
     RTCState *s = domain_vrtc(d);
 
+    if ( !has_vrtc(d) )
+        return;
+
     spin_lock_init(&s->lock);
 
     init_timer(&s->update_timer, rtc_update_timer, s, smp_processor_id());
@@ -820,6 +833,9 @@ void rtc_deinit(struct domain *d)
 {
     RTCState *s = domain_vrtc(d);
 
+    if ( !has_vrtc(d) )
+        return;
+
     spin_barrier(&s->lock);
 
     TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 17/31] xen/x86: allow disabling the emulated IO APIC
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (15 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 16/31] xen/x86: allow disabling the emulated RTC Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 18/31] xen/x86: allow disabling the emulated PIC Roger Pau Monne
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/vioapic.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index d348235..30a4a0f 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -424,12 +424,20 @@ void vioapic_update_EOI(struct domain *d, u8 vector)
 static int ioapic_save(struct domain *d, hvm_domain_context_t *h)
 {
     struct hvm_hw_vioapic *s = domain_vioapic(d);
+
+    if ( !has_vioapic(d) )
+        return 0;
+
     return hvm_save_entry(IOAPIC, 0, h, s);
 }
 
 static int ioapic_load(struct domain *d, hvm_domain_context_t *h)
 {
     struct hvm_hw_vioapic *s = domain_vioapic(d);
+
+    if ( !has_vioapic(d) )
+        return 0;
+
     return hvm_load_entry(IOAPIC, h, s);
 }
 
@@ -448,6 +456,9 @@ void vioapic_reset(struct domain *d)
 
 int vioapic_init(struct domain *d)
 {
+    if ( !has_vioapic(d) )
+        return 0;
+
     if ( (d->arch.hvm_domain.vioapic == NULL) &&
          ((d->arch.hvm_domain.vioapic = xmalloc(struct hvm_vioapic)) == NULL) )
         return -ENOMEM;
@@ -462,6 +473,9 @@ int vioapic_init(struct domain *d)
 
 void vioapic_deinit(struct domain *d)
 {
+    if ( !has_vioapic(d) )
+        return;
+
     xfree(d->arch.hvm_domain.vioapic);
     d->arch.hvm_domain.vioapic = NULL;
 }
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 18/31] xen/x86: allow disabling the emulated PIC
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (16 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 17/31] xen/x86: allow disabling the emulated IO APIC Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 19/31] xen/x86: allow disabling the emulated pmu Roger Pau Monne
                   ` (12 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/vpic.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vpic.c b/xen/arch/x86/hvm/vpic.c
index 7c2edc8..5938f40 100644
--- a/xen/arch/x86/hvm/vpic.c
+++ b/xen/arch/x86/hvm/vpic.c
@@ -377,6 +377,9 @@ static int vpic_save(struct domain *d, hvm_domain_context_t *h)
     struct hvm_hw_vpic *s;
     int i;
 
+    if ( !has_vpic(d) )
+        return 0;
+
     /* Save the state of both PICs */
     for ( i = 0; i < 2 ; i++ )
     {
@@ -392,7 +395,10 @@ static int vpic_load(struct domain *d, hvm_domain_context_t *h)
 {
     struct hvm_hw_vpic *s;
     uint16_t inst;
-    
+
+    if ( !has_vpic(d) )
+        return 0;
+
     /* Which PIC is this? */
     inst = hvm_load_instance(h);
     if ( inst > 1 )
@@ -425,6 +431,9 @@ void vpic_reset(struct domain *d)
 
 void vpic_init(struct domain *d)
 {
+    if ( !has_vpic(d) )
+        return;
+
     vpic_reset(d);
 
     register_portio_handler(d, 0x20, 2, vpic_intercept_pic_io);
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 19/31] xen/x86: allow disabling the emulated pmu
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (17 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 18/31] xen/x86: allow disabling the emulated PIC Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 20/31] xen/x86: allow disabling the emulated VGA Roger Pau Monne
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/cpu/vpmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
index 8af3df1..d5bb77d 100644
--- a/xen/arch/x86/cpu/vpmu.c
+++ b/xen/arch/x86/cpu/vpmu.c
@@ -439,6 +439,9 @@ void vpmu_initialise(struct vcpu *v)
     int ret;
     bool_t is_priv_vpmu = is_hardware_domain(v->domain);
 
+    if ( !has_vpmu(v->domain) )
+        return;
+
     BUILD_BUG_ON(sizeof(struct xen_pmu_intel_ctxt) > XENPMU_CTXT_PAD_SZ);
     BUILD_BUG_ON(sizeof(struct xen_pmu_amd_ctxt) > XENPMU_CTXT_PAD_SZ);
     BUILD_BUG_ON(sizeof(struct xen_pmu_regs) > XENPMU_REGS_PAD_SZ);
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 20/31] xen/x86: allow disabling the emulated VGA
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (18 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 19/31] xen/x86: allow disabling the emulated pmu Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 21/31] xen/x86: allow disabling the emulated IOMMU Roger Pau Monne
                   ` (10 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/stdvga.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/xen/arch/x86/hvm/stdvga.c b/xen/arch/x86/hvm/stdvga.c
index f50bff7..a3296bd 100644
--- a/xen/arch/x86/hvm/stdvga.c
+++ b/xen/arch/x86/hvm/stdvga.c
@@ -555,6 +555,9 @@ void stdvga_init(struct domain *d)
     void *p;
     int i;
 
+    if ( !has_vvga(d) )
+        return;
+
     memset(s, 0, sizeof(*s));
     spin_lock_init(&s->lock);
     
@@ -594,6 +597,9 @@ void stdvga_deinit(struct domain *d)
     struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
     int i;
 
+    if ( !has_vvga(d) )
+        return;
+
     for ( i = 0; i != ARRAY_SIZE(s->vram_page); i++ )
     {
         if ( s->vram_page[i] == NULL )
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 21/31] xen/x86: allow disabling the emulated IOMMU
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (19 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 20/31] xen/x86: allow disabling the emulated VGA Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 10:17 ` [PATCH v4 22/31] xen/x86: allow disabling all emulated devices inside of Xen Roger Pau Monne
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Aravind Gopalakrishnan, Suravee Suthikulpanit, Roger Pau Monne

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
---
 xen/drivers/passthrough/amd/iommu_guest.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/xen/drivers/passthrough/amd/iommu_guest.c b/xen/drivers/passthrough/amd/iommu_guest.c
index e74f469..b4e75ac 100644
--- a/xen/drivers/passthrough/amd/iommu_guest.c
+++ b/xen/drivers/passthrough/amd/iommu_guest.c
@@ -887,7 +887,8 @@ int guest_iommu_init(struct domain* d)
     struct guest_iommu *iommu;
     struct hvm_iommu *hd  = domain_hvm_iommu(d);
 
-    if ( !is_hvm_domain(d) || !iommu_enabled || !iommuv2_enabled )
+    if ( !is_hvm_domain(d) || !iommu_enabled || !iommuv2_enabled ||
+         !has_viommu(d) )
         return 0;
 
     iommu = xzalloc(struct guest_iommu);
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 22/31] xen/x86: allow disabling all emulated devices inside of Xen
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (20 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 21/31] xen/x86: allow disabling the emulated IOMMU Roger Pau Monne
@ 2015-08-07 10:17 ` Roger Pau Monne
  2015-08-07 16:32   ` Andrew Cooper
  2015-08-07 10:18 ` [PATCH v4 23/31] elfnotes: intorduce a new PHYS_ENTRY elfnote Roger Pau Monne
                   ` (8 subsequent siblings)
  30 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Only allow enabling or disabling all the emulated devices inside of Xen,
right now Xen doesn't support enabling specific emulated devices only.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/domain.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index c508074..432fe43 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -563,7 +563,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
                           XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC |
                           XEN_X86_EMU_PMU | XEN_X86_EMU_VGA |
                           XEN_X86_EMU_IOMMU);
-        if ( (config->emulation_flags & emulation_mask) != emulation_mask )
+        if ( (config->emulation_flags & emulation_mask) != emulation_mask &&
+             (config->emulation_flags & emulation_mask) != 0 )
         {
             printk(XENLOG_G_ERR "d%d: Xen does not allow HVM creation with the "
                    "current selection of emulators: %#x.\n", d->domain_id,
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 23/31] elfnotes: intorduce a new PHYS_ENTRY elfnote
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (21 preceding siblings ...)
  2015-08-07 10:17 ` [PATCH v4 22/31] xen/x86: allow disabling all emulated devices inside of Xen Roger Pau Monne
@ 2015-08-07 10:18 ` Roger Pau Monne
  2015-08-07 16:37   ` Andrew Cooper
  2015-08-07 16:44   ` Wei Liu
  2015-08-07 10:18 ` [PATCH v4 24/31] libxc: allow creating domains without emulated devices Roger Pau Monne
                   ` (7 subsequent siblings)
  30 siblings, 2 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:18 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

This new elfnote contains the 32bit entry point into the kernel. Xen will
use this entry point in order to launch the guest kernel in 32bit protected
mode with paging disabled.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 tools/xcutils/readnotes.c          |  3 +++
 xen/common/libelf/libelf-dominfo.c |  4 ++++
 xen/include/public/elfnote.h       | 11 ++++++++++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
index 5fa445e..e682dd1 100644
--- a/tools/xcutils/readnotes.c
+++ b/tools/xcutils/readnotes.c
@@ -159,6 +159,9 @@ static unsigned print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) st
 		case XEN_ELFNOTE_L1_MFN_VALID:
 			print_l1_mfn_valid_note("L1_MFN_VALID", elf , note);
 			break;
+		case XEN_ELFNOTE_PHYS32_ENTRY:
+			print_numeric_note("PHYS32_ENTRY", elf , note);
+			break;
 		default:
 			printf("unknown note type %#x\n",
 			       (unsigned)elf_uval(elf, note, type));
diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
index f929968..365e058 100644
--- a/xen/common/libelf/libelf-dominfo.c
+++ b/xen/common/libelf/libelf-dominfo.c
@@ -119,6 +119,7 @@ elf_errorstatus elf_xen_parse_note(struct elf_binary *elf,
         [XEN_ELFNOTE_BSD_SYMTAB] = { "BSD_SYMTAB", 1},
         [XEN_ELFNOTE_SUSPEND_CANCEL] = { "SUSPEND_CANCEL", 0 },
         [XEN_ELFNOTE_MOD_START_PFN] = { "MOD_START_PFN", 0 },
+        [XEN_ELFNOTE_PHYS32_ENTRY] = { "PHYS32_ENTRY", 0 },
     };
 /* *INDENT-ON* */
 
@@ -212,6 +213,9 @@ elf_errorstatus elf_xen_parse_note(struct elf_binary *elf,
                 elf, note, sizeof(*parms->f_supported), i);
         break;
 
+    case XEN_ELFNOTE_PHYS32_ENTRY:
+        parms->phys_entry = val;
+        break;
     }
     return 0;
 }
diff --git a/xen/include/public/elfnote.h b/xen/include/public/elfnote.h
index 3824a94..e6fc596 100644
--- a/xen/include/public/elfnote.h
+++ b/xen/include/public/elfnote.h
@@ -200,9 +200,18 @@
 #define XEN_ELFNOTE_SUPPORTED_FEATURES 17
 
 /*
+ * Physical entry point into the kernel.
+ *
+ * 32bit entry point into the kernel. Xen will use this entry point
+ * in order to launch the guest kernel in 32bit protected mode
+ * with paging disabled.
+ */
+#define XEN_ELFNOTE_PHYS32_ENTRY 18
+
+/*
  * The number of the highest elfnote defined.
  */
-#define XEN_ELFNOTE_MAX XEN_ELFNOTE_SUPPORTED_FEATURES
+#define XEN_ELFNOTE_MAX XEN_ELFNOTE_PHYS32_ENTRY
 
 /*
  * System information exported through crash notes.
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 24/31] libxc: allow creating domains without emulated devices.
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (22 preceding siblings ...)
  2015-08-07 10:18 ` [PATCH v4 23/31] elfnotes: intorduce a new PHYS_ENTRY elfnote Roger Pau Monne
@ 2015-08-07 10:18 ` Roger Pau Monne
  2015-08-07 12:18   ` Wei Liu
  2015-08-07 16:36   ` Andrew Cooper
  2015-08-07 10:18 ` [PATCH v4 25/31] xen: allow HVM guests to use XENMEM_memory_map Roger Pau Monne
                   ` (6 subsequent siblings)
  30 siblings, 2 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:18 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

Introduce a new flag in xc_dom_image that turns on and off the emulated
devices. This prevents creating the VGA hole, the hvm_info page and the
ioreq server pages. libxl unconditionally sets it to true for all HVM
domains at the moment.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Changes since v3:
 - Explain the meaning of the "emulation" xc_dom_image field.
---
 tools/libxc/include/xc_dom.h |  3 ++
 tools/libxc/xc_dom_x86.c     | 71 +++++++++++++++++++++++++-------------------
 tools/libxl/libxl_dom.c      |  1 +
 3 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index cda40d9..99225cf 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -194,6 +194,9 @@ struct xc_dom_image {
     xen_pfn_t lowmem_end;
     xen_pfn_t highmem_end;
 
+    /* If set disables the setup of the IOREQ pages and the VGA MMIO hole. */
+    bool emulation;
+
     /* Extra ACPI tables passed to HVMLOADER */
     struct xc_hvm_firmware_module acpi_module;
 
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 18e3340..b587b12 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -522,12 +522,15 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
     xen_pfn_t ioreq_server_array[NR_IOREQ_SERVER_PAGES];
     xc_interface *xch = dom->xch;
 
-    if ( (hvm_info_page = xc_map_foreign_range(
-              xch, domid, PAGE_SIZE, PROT_READ | PROT_WRITE,
-              HVM_INFO_PFN)) == NULL )
-        goto error_out;
-    build_hvm_info(hvm_info_page, dom);
-    munmap(hvm_info_page, PAGE_SIZE);
+    if ( dom->emulation )
+    {
+        if ( (hvm_info_page = xc_map_foreign_range(
+                  xch, domid, PAGE_SIZE, PROT_READ | PROT_WRITE,
+                  HVM_INFO_PFN)) == NULL )
+            goto error_out;
+        build_hvm_info(hvm_info_page, dom);
+        munmap(hvm_info_page, PAGE_SIZE);
+    }
 
     /* Allocate and clear special pages. */
     for ( i = 0; i < NR_SPECIAL_PAGES; i++ )
@@ -559,30 +562,33 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
     xc_hvm_param_set(xch, domid, HVM_PARAM_SHARING_RING_PFN,
                      special_pfn(SPECIALPAGE_SHARING));
 
-    /*
-     * Allocate and clear additional ioreq server pages. The default
-     * server will use the IOREQ and BUFIOREQ special pages above.
-     */
-    for ( i = 0; i < NR_IOREQ_SERVER_PAGES; i++ )
-        ioreq_server_array[i] = ioreq_server_pfn(i);
-
-    rc = xc_domain_populate_physmap_exact(xch, domid, NR_IOREQ_SERVER_PAGES, 0,
-                                          0, ioreq_server_array);
-    if ( rc != 0 )
+    if ( dom->emulation )
     {
-        DOMPRINTF("Could not allocate ioreq server pages.");
-        goto error_out;
-    }
+        /*
+         * Allocate and clear additional ioreq server pages. The default
+         * server will use the IOREQ and BUFIOREQ special pages above.
+         */
+        for ( i = 0; i < NR_IOREQ_SERVER_PAGES; i++ )
+            ioreq_server_array[i] = ioreq_server_pfn(i);
 
-    if ( xc_clear_domain_pages(xch, domid, ioreq_server_pfn(0),
-                               NR_IOREQ_SERVER_PAGES) )
+        rc = xc_domain_populate_physmap_exact(xch, domid, NR_IOREQ_SERVER_PAGES, 0,
+                                              0, ioreq_server_array);
+        if ( rc != 0 )
+        {
+            DOMPRINTF("Could not allocate ioreq server pages.");
             goto error_out;
+        }
 
-    /* Tell the domain where the pages are and how many there are */
-    xc_hvm_param_set(xch, domid, HVM_PARAM_IOREQ_SERVER_PFN,
-                     ioreq_server_pfn(0));
-    xc_hvm_param_set(xch, domid, HVM_PARAM_NR_IOREQ_SERVER_PAGES,
-                     NR_IOREQ_SERVER_PAGES);
+        if ( xc_clear_domain_pages(xch, domid, ioreq_server_pfn(0),
+                                   NR_IOREQ_SERVER_PAGES) )
+                goto error_out;
+
+        /* Tell the domain where the pages are and how many there are */
+        xc_hvm_param_set(xch, domid, HVM_PARAM_IOREQ_SERVER_PFN,
+                         ioreq_server_pfn(0));
+        xc_hvm_param_set(xch, domid, HVM_PARAM_NR_IOREQ_SERVER_PAGES,
+                         NR_IOREQ_SERVER_PAGES);
+    }
 
     /*
      * Identity-map page table is required for running with CR0.PG=0 when
@@ -1320,7 +1326,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
      * allocated is pointless.
      */
     if ( claim_enabled ) {
-        rc = xc_domain_claim_pages(xch, domid, target_pages - VGA_HOLE_SIZE);
+        rc = xc_domain_claim_pages(xch, domid, target_pages -
+                                   dom->emulation ? VGA_HOLE_SIZE : 0);
         if ( rc != 0 )
         {
             DOMPRINTF("Could not allocate memory for HVM guest as we cannot claim memory!");
@@ -1336,7 +1343,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
          * tot_pages will be target_pages - VGA_HOLE_SIZE after
          * this call.
          */
-        rc = xc_domain_set_pod_target(xch, domid, target_pages - VGA_HOLE_SIZE,
+        rc = xc_domain_set_pod_target(xch, domid, target_pages -
+                                      dom->emulation ? VGA_HOLE_SIZE : 0,
                                       NULL, NULL, NULL);
         if ( rc != 0 )
         {
@@ -1355,8 +1363,9 @@ static int meminit_hvm(struct xc_dom_image *dom)
      * Under 2MB mode, we allocate pages in batches of no more than 8MB to 
      * ensure that we can be preempted and hence dom0 remains responsive.
      */
-    rc = xc_domain_populate_physmap_exact(
-        xch, domid, 0xa0, 0, memflags, &dom->p2m_host[0x00]);
+    if ( dom->emulation )
+        rc = xc_domain_populate_physmap_exact(
+            xch, domid, 0xa0, 0, memflags, &dom->p2m_host[0x00]);
 
     stat_normal_pages = 0;
     for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
@@ -1375,7 +1384,7 @@ static int meminit_hvm(struct xc_dom_image *dom)
          * 0xA0000-0xC0000. Note that 0x00000-0xA0000 is populated just
          * before this loop.
          */
-        if ( vmemranges[vmemid].start == 0 )
+        if ( vmemranges[vmemid].start == 0 && dom->emulation )
         {
             cur_pages = 0xc0;
             stat_normal_pages += 0xc0;
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index bf9b65f..8b8e079 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -987,6 +987,7 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
     dom->lowmem_end = lowmem_end;
     dom->highmem_end = highmem_end;
     dom->mmio_start = mmio_start;
+    dom->emulation = true;
 
     rc = libxl__domain_device_construct_rdm(gc, d_config,
                                             info->u.hvm.rdm_mem_boundary_memkb*1024,
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 25/31] xen: allow HVM guests to use XENMEM_memory_map
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (23 preceding siblings ...)
  2015-08-07 10:18 ` [PATCH v4 24/31] libxc: allow creating domains without emulated devices Roger Pau Monne
@ 2015-08-07 10:18 ` Roger Pau Monne
  2015-08-07 12:22   ` Wei Liu
  2015-08-07 10:18 ` [PATCH v4 26/31] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs Roger Pau Monne
                   ` (5 subsequent siblings)
  30 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:18 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
	Ian Jackson, Jan Beulich, Roger Pau Monne

Enable this hypercall for HVM guests in order to fetch the e820 memory
map in the absence of an emulated BIOS. The memory map is populated and
notified to Xen in arch_setup_meminit_hvm.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/libxc/xc_dom_x86.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index b587b12..87bce6e 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -1205,6 +1205,7 @@ static int check_mmio_hole(uint64_t start, uint64_t memsize,
         return 1;
 }
 
+#define MAX_E820_ENTRIES    128
 static int meminit_hvm(struct xc_dom_image *dom)
 {
     unsigned long i, vmemid, nr_pages = dom->total_pages;
@@ -1225,6 +1226,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
     unsigned int nr_vmemranges, nr_vnodes;
     xc_interface *xch = dom->xch;
     uint32_t domid = dom->guest_domid;
+    struct e820entry entries[MAX_E820_ENTRIES];
+    int e820_index = 0;
 
     if ( nr_pages > target_pages )
         memflags |= XENMEMF_populate_on_demand;
@@ -1275,6 +1278,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
         vnode_to_pnode = dom->vnode_to_pnode;
     }
 
+    /* Add one additional memory range to account for the VGA hole */
+    if ( (nr_vmemranges + (dom->emulation ? 1 : 0)) > MAX_E820_ENTRIES )
+    {
+        DOMPRINTF("Too many memory ranges");
+        goto error_out;
+    }
+
     total_pages = 0;
     p2m_size = 0;
     for ( i = 0; i < nr_vmemranges; i++ )
@@ -1363,9 +1373,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
      * Under 2MB mode, we allocate pages in batches of no more than 8MB to 
      * ensure that we can be preempted and hence dom0 remains responsive.
      */
-    if ( dom->emulation )
+    if ( dom->emulation ) {
         rc = xc_domain_populate_physmap_exact(
             xch, domid, 0xa0, 0, memflags, &dom->p2m_host[0x00]);
+        entries[e820_index].addr = 0;
+        entries[e820_index].size = 0xa0 << PAGE_SHIFT;
+        entries[e820_index++].type = E820_RAM;
+    }
 
     stat_normal_pages = 0;
     for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
@@ -1392,6 +1406,12 @@ static int meminit_hvm(struct xc_dom_image *dom)
         else
             cur_pages = vmemranges[vmemid].start >> PAGE_SHIFT;
 
+        /* Build an e820 map. */
+        entries[e820_index].addr = cur_pages << PAGE_SHIFT;
+        entries[e820_index].size = vmemranges[vmemid].end -
+                                   entries[e820_index].addr;
+        entries[e820_index++].type = E820_RAM;
+
         while ( (rc == 0) && (end_pages > cur_pages) )
         {
             /* Clip count to maximum 1GB extent. */
@@ -1509,6 +1529,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
     DPRINTF("  2MB PAGES: 0x%016lx\n", stat_2mb_pages);
     DPRINTF("  1GB PAGES: 0x%016lx\n", stat_1gb_pages);
 
+    rc = xc_domain_set_memory_map(xch, domid, entries, e820_index);
+    if ( rc != 0 )
+    {
+        DOMPRINTF("unable to set memory map.");
+        goto error_out;
+    }
+
     rc = 0;
     goto out;
  error_out:
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 26/31] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (24 preceding siblings ...)
  2015-08-07 10:18 ` [PATCH v4 25/31] xen: allow HVM guests to use XENMEM_memory_map Roger Pau Monne
@ 2015-08-07 10:18 ` Roger Pau Monne
  2015-08-07 19:03   ` Andrew Cooper
  2015-08-07 10:18 ` [PATCH v4 27/31] xenconsole: try to attach to PV console if HVM fails Roger Pau Monne
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:18 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Ian Campbell, Jan Beulich,
	Roger Pau Monne

Allow the usage of the VCPUOP_initialise, VCPUOP_up, VCPUOP_down and
VCPUOP_is_up hypercalls from HVM guests.

This patch introduces a new structure (vcpu_hvm_context) that should be used
in conjuction with the VCPUOP_initialise hypercall in order to initialize
vCPUs for HVM guests.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
---
 xen/arch/arm/domain.c             |  24 ++++++
 xen/arch/x86/domain.c             | 156 +++++++++++++++++++++++++++++++++++
 xen/arch/x86/hvm/hvm.c            |   8 ++
 xen/common/domain.c               |  16 +---
 xen/include/public/hvm/hvm_vcpu.h | 168 ++++++++++++++++++++++++++++++++++++++
 xen/include/xen/domain.h          |   2 +
 6 files changed, 359 insertions(+), 15 deletions(-)
 create mode 100644 xen/include/public/hvm/hvm_vcpu.h

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index b2bfc7d..b20035d 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -752,6 +752,30 @@ int arch_set_info_guest(
     return 0;
 }
 
+int arch_initialize_vcpu(struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg)
+{
+    struct vcpu_guest_context *ctxt;
+    struct domain *d = current->domain;
+    int rc;
+
+    if ( (ctxt = alloc_vcpu_guest_context()) == NULL )
+        return -ENOMEM;
+
+    if ( copy_from_guest(ctxt, arg, 1) )
+    {
+        free_vcpu_guest_context(ctxt);
+        return -EFAULT;
+    }
+
+    domain_lock(d);
+    rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, ctxt);
+    domain_unlock(d);
+
+    free_vcpu_guest_context(ctxt);
+
+    return rc;
+}
+
 int arch_vcpu_reset(struct vcpu *v)
 {
     vcpu_end_shutdown_deferral(v);
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 432fe43..4a7f8d9 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -37,6 +37,7 @@
 #include <xen/wait.h>
 #include <xen/guest_access.h>
 #include <public/sysctl.h>
+#include <public/hvm/hvm_vcpu.h>
 #include <asm/regs.h>
 #include <asm/mc146818rtc.h>
 #include <asm/system.h>
@@ -1135,6 +1136,161 @@ int arch_set_info_guest(
 #undef c
 }
 
+/* Called by VCPUOP_initialise for HVM guests. */
+static int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx)
+{
+    struct segment_register seg;
+
+#define get_context_seg(ctx, seg, f)                                        \
+    (ctx)->mode == VCPU_HVM_MODE_16B ? (ctx)->cpu_regs.x86_16.seg##_##f :   \
+    (ctx)->mode == VCPU_HVM_MODE_32B ? (ctx)->cpu_regs.x86_32.seg##_##f :   \
+    (ctx)->cpu_regs.x86_64.seg##_##f
+
+#define get_context_gpr(ctx, gpr)                                           \
+    (ctx)->mode == VCPU_HVM_MODE_16B ? (ctx)->cpu_regs.x86_16.gpr :         \
+    (ctx)->mode == VCPU_HVM_MODE_32B ? (ctx)->cpu_regs.x86_32.e##gpr :      \
+    (ctx)->cpu_regs.x86_64.r##gpr
+
+#define get_context_field(ctx, field)                                       \
+    (ctx)->mode == VCPU_HVM_MODE_16B ? (ctx)->cpu_regs.x86_16.field :       \
+    (ctx)->mode == VCPU_HVM_MODE_32B ? (ctx)->cpu_regs.x86_32.field :       \
+    (ctx)->cpu_regs.x86_64.field
+
+    memset(&seg, 0, sizeof(seg));
+
+    if ( !paging_mode_hap(v->domain) )
+        v->arch.guest_table = pagetable_null();
+
+    v->arch.user_regs.rax = get_context_gpr(ctx, ax);
+    v->arch.user_regs.rcx = get_context_gpr(ctx, cx);
+    v->arch.user_regs.rdx = get_context_gpr(ctx, dx);
+    v->arch.user_regs.rbx = get_context_gpr(ctx, bx);
+    v->arch.user_regs.rsp = get_context_gpr(ctx, sp);
+    v->arch.user_regs.rbp = get_context_gpr(ctx, bp);
+    v->arch.user_regs.rsi = get_context_gpr(ctx, si);
+    v->arch.user_regs.rdi = get_context_gpr(ctx, di);
+    v->arch.user_regs.rip = get_context_gpr(ctx, ip);
+    v->arch.user_regs.rflags = get_context_gpr(ctx, flags);
+
+    v->arch.hvm_vcpu.guest_cr[0] = get_context_field(ctx, cr0) | X86_CR0_ET;
+    hvm_update_guest_cr(v, 0);
+    v->arch.hvm_vcpu.guest_cr[4] = get_context_field(ctx, cr4);
+    hvm_update_guest_cr(v, 4);
+
+    switch ( ctx->mode )
+    {
+    case VCPU_HVM_MODE_32B:
+        v->arch.hvm_vcpu.guest_efer = ctx->cpu_regs.x86_32.efer;
+        hvm_update_guest_efer(v);
+        v->arch.hvm_vcpu.guest_cr[3] = ctx->cpu_regs.x86_32.cr3;
+        hvm_update_guest_cr(v, 3);
+        break;
+    case VCPU_HVM_MODE_64B:
+        v->arch.user_regs.r8 = ctx->cpu_regs.x86_64.r8;
+        v->arch.user_regs.r9 = ctx->cpu_regs.x86_64.r9;
+        v->arch.user_regs.r10 = ctx->cpu_regs.x86_64.r10;
+        v->arch.user_regs.r11 = ctx->cpu_regs.x86_64.r11;
+        v->arch.user_regs.r12 = ctx->cpu_regs.x86_64.r12;
+        v->arch.user_regs.r13 = ctx->cpu_regs.x86_64.r13;
+        v->arch.user_regs.r14 = ctx->cpu_regs.x86_64.r14;
+        v->arch.user_regs.r15 = ctx->cpu_regs.x86_64.r15;
+        v->arch.hvm_vcpu.guest_efer = ctx->cpu_regs.x86_64.efer;
+        hvm_update_guest_efer(v);
+        v->arch.hvm_vcpu.guest_cr[3] = ctx->cpu_regs.x86_64.cr3;
+        hvm_update_guest_cr(v, 3);
+        break;
+    default:
+        break;
+    }
+
+    if ( hvm_paging_enabled(v) && !paging_mode_hap(v->domain) )
+    {
+        /* Shadow-mode CR3 change. Check PDBR and update refcounts. */
+        struct page_info *page = get_page_from_gfn(v->domain,
+                                 v->arch.hvm_vcpu.guest_cr[3] >> PAGE_SHIFT,
+                                 NULL, P2M_ALLOC);
+        if ( !page )
+        {
+            gdprintk(XENLOG_ERR, "Invalid CR3\n");
+            domain_crash(v->domain);
+            return -EINVAL;
+        }
+
+        v->arch.guest_table = pagetable_from_page(page);
+    }
+
+    seg.base = get_context_seg(ctx, cs, base);
+    seg.limit = get_context_seg(ctx, cs, limit);
+    seg.attr.bytes = get_context_seg(ctx, cs, ar);
+    hvm_set_segment_register(v, x86_seg_cs, &seg);
+    seg.base = get_context_seg(ctx, ds, base);
+    seg.limit = get_context_seg(ctx, ds, limit);
+    seg.attr.bytes = get_context_seg(ctx, ds, ar);
+    hvm_set_segment_register(v, x86_seg_ds, &seg);
+    seg.base = get_context_seg(ctx, ss, base);
+    seg.limit = get_context_seg(ctx, ss, limit);
+    seg.attr.bytes = get_context_seg(ctx, ss, ar);
+    hvm_set_segment_register(v, x86_seg_ss, &seg);
+    seg.base = get_context_seg(ctx, tr, base);
+    seg.limit = get_context_seg(ctx, tr, limit);
+    seg.attr.bytes = get_context_seg(ctx, tr, ar);
+    hvm_set_segment_register(v, x86_seg_tr, &seg);
+
+    /* Sync AP's TSC with BSP's. */
+    v->arch.hvm_vcpu.cache_tsc_offset =
+        v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
+    hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset,
+                             v->domain->arch.hvm_domain.sync_tsc);
+
+    v->arch.hvm_vcpu.msr_tsc_adjust = 0;
+
+    paging_update_paging_modes(v);
+
+    v->arch.flags |= TF_kernel_mode;
+    v->is_initialised = 1;
+    set_bit(_VPF_down, &v->pause_flags);
+
+    return 0;
+#undef get_context_field
+#undef get_context_gpr
+#undef get_context_seg
+}
+
+int arch_initialize_vcpu(struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg)
+{
+    struct vcpu_guest_context *ctxt;
+    struct vcpu_hvm_context hvm_ctx;
+    struct domain *d = current->domain;
+    int rc;
+
+    if ( is_hvm_vcpu(v) )
+    {
+        if ( copy_from_guest(&hvm_ctx, arg, 1) )
+            return -EFAULT;
+
+        domain_lock(d);
+        rc = v->is_initialised ? -EEXIST : arch_set_info_hvm_guest(v, &hvm_ctx);
+        domain_unlock(d);
+    } else {
+        if ( (ctxt = alloc_vcpu_guest_context()) == NULL )
+            return -ENOMEM;
+
+        if ( copy_from_guest(ctxt, arg, 1) )
+        {
+            free_vcpu_guest_context(ctxt);
+            return -EFAULT;
+        }
+
+        domain_lock(d);
+        rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, ctxt);
+        domain_unlock(d);
+
+        free_vcpu_guest_context(ctxt);
+    }
+
+    return rc;
+}
+
 int arch_vcpu_reset(struct vcpu *v)
 {
     if ( is_pv_vcpu(v) )
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c778a20..15ea5e2 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4972,6 +4972,10 @@ static long hvm_vcpu_op(
     case VCPUOP_stop_singleshot_timer:
     case VCPUOP_register_vcpu_info:
     case VCPUOP_register_vcpu_time_memory_area:
+    case VCPUOP_initialise:
+    case VCPUOP_up:
+    case VCPUOP_down:
+    case VCPUOP_is_up:
         rc = do_vcpu_op(cmd, vcpuid, arg);
         break;
     default:
@@ -5030,6 +5034,10 @@ static long hvm_vcpu_op_compat32(
     case VCPUOP_stop_singleshot_timer:
     case VCPUOP_register_vcpu_info:
     case VCPUOP_register_vcpu_time_memory_area:
+    case VCPUOP_initialise:
+    case VCPUOP_up:
+    case VCPUOP_down:
+    case VCPUOP_is_up:
         rc = compat_vcpu_op(cmd, vcpuid, arg);
         break;
     default:
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 1b9fcfc..f97e7f4 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -1173,7 +1173,6 @@ long do_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg)
 {
     struct domain *d = current->domain;
     struct vcpu *v;
-    struct vcpu_guest_context *ctxt;
     long rc = 0;
 
     if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
@@ -1185,20 +1184,7 @@ long do_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( v->vcpu_info == &dummy_vcpu_info )
             return -EINVAL;
 
-        if ( (ctxt = alloc_vcpu_guest_context()) == NULL )
-            return -ENOMEM;
-
-        if ( copy_from_guest(ctxt, arg, 1) )
-        {
-            free_vcpu_guest_context(ctxt);
-            return -EFAULT;
-        }
-
-        domain_lock(d);
-        rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, ctxt);
-        domain_unlock(d);
-
-        free_vcpu_guest_context(ctxt);
+        rc = arch_initialize_vcpu(v, arg);
 
         if ( rc == -ERESTART )
             rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iuh",
diff --git a/xen/include/public/hvm/hvm_vcpu.h b/xen/include/public/hvm/hvm_vcpu.h
new file mode 100644
index 0000000..db86edd
--- /dev/null
+++ b/xen/include/public/hvm/hvm_vcpu.h
@@ -0,0 +1,168 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_PUBLIC_HVM_HVM_VCPU_H__
+#define __XEN_PUBLIC_HVM_HVM_VCPU_H__
+
+#include "../xen.h"
+
+struct vcpu_hvm_x86_16 {
+    uint16_t ax;
+    uint16_t cx;
+    uint16_t dx;
+    uint16_t bx;
+    uint16_t sp;
+    uint16_t bp;
+    uint16_t si;
+    uint16_t di;
+    uint16_t ip;
+    uint16_t flags;
+
+    uint32_t cr0;
+    uint32_t cr4;
+
+    uint32_t cs_base;
+    uint32_t ds_base;
+    uint32_t ss_base;
+    uint32_t tr_base;
+    uint32_t cs_limit;
+    uint32_t ds_limit;
+    uint32_t ss_limit;
+    uint32_t tr_limit;
+    uint16_t cs_ar;
+    uint16_t ds_ar;
+    uint16_t ss_ar;
+    uint16_t tr_ar;
+};
+
+struct vcpu_hvm_x86_32 {
+    uint32_t eax;
+    uint32_t ecx;
+    uint32_t edx;
+    uint32_t ebx;
+    uint32_t esp;
+    uint32_t ebp;
+    uint32_t esi;
+    uint32_t edi;
+    uint32_t eip;
+    uint16_t eflags;
+
+    uint32_t cr0;
+    uint32_t cr3;
+    uint32_t cr4;
+    uint64_t efer;
+
+    uint32_t cs_base;
+    uint32_t ds_base;
+    uint32_t ss_base;
+    uint32_t tr_base;
+    uint32_t cs_limit;
+    uint32_t ds_limit;
+    uint32_t ss_limit;
+    uint32_t tr_limit;
+    uint16_t cs_ar;
+    uint16_t ds_ar;
+    uint16_t ss_ar;
+    uint16_t tr_ar;
+};
+
+struct vcpu_hvm_x86_64 {
+    uint64_t rax;
+    uint64_t rcx;
+    uint64_t rdx;
+    uint64_t rbx;
+    uint64_t rsp;
+    uint64_t rbp;
+    uint64_t rsi;
+    uint64_t rdi;
+    uint64_t r8;
+    uint64_t r9;
+    uint64_t r10;
+    uint64_t r11;
+    uint64_t r12;
+    uint64_t r13;
+    uint64_t r14;
+    uint64_t r15;
+    uint64_t rip;
+    uint64_t rflags;
+
+    uint64_t cr0;
+    uint64_t cr3;
+    uint64_t cr4;
+    uint64_t efer;
+
+    uint32_t cs_base;
+    uint32_t ds_base;
+    uint32_t ss_base;
+    uint32_t tr_base;
+    uint32_t cs_limit;
+    uint32_t ds_limit;
+    uint32_t ss_limit;
+    uint32_t tr_limit;
+    uint16_t cs_ar;
+    uint16_t ds_ar;
+    uint16_t ss_ar;
+    uint16_t tr_ar;
+};
+
+/*
+ * The layout of the _ar fields of the segment registers is the
+ * following:
+ *
+ * Bits [0,3]: type (bits 40-43).
+ * Bit      4: s    (descriptor type, bit 44).
+ * Bit  [5,6]: dpl  (descriptor privilege level, bits 45-46).
+ * Bit      7: p    (segment-present, bit 47).
+ * Bit      8: avl  (available for system software, bit 52).
+ * Bit      9: l    (64-bit code segment, bit 53).
+ * Bit     10: db   (meaning depends on the segment, bit 54).
+ * Bit     11: g    (granularity, bit 55)
+ *
+ * A more complete description of the meaning of this fields can be
+ * obtained from the Intel SDM, Volume 3, section 3.4.5.
+ */
+
+struct vcpu_hvm_context {
+#define VCPU_HVM_MODE_16B 0  /* 16bit fields of the structure will be used. */
+#define VCPU_HVM_MODE_32B 1  /* 32bit fields of the structure will be used. */
+#define VCPU_HVM_MODE_64B 2  /* 64bit fields of the structure will be used. */
+    uint32_t mode;
+
+    /* CPU registers. */
+    union {
+        struct vcpu_hvm_x86_16 x86_16;
+        struct vcpu_hvm_x86_32 x86_32;
+        struct vcpu_hvm_x86_64 x86_64;
+    } cpu_regs;
+};
+typedef struct vcpu_hvm_context vcpu_hvm_context_t;
+DEFINE_XEN_GUEST_HANDLE(vcpu_hvm_context_t);
+
+#endif /* __XEN_PUBLIC_HVM_HVM_VCPU_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index 848db8a..21690be 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -68,6 +68,8 @@ void arch_domain_unpause(struct domain *d);
 int arch_set_info_guest(struct vcpu *, vcpu_guest_context_u);
 void arch_get_info_guest(struct vcpu *, vcpu_guest_context_u);
 
+int arch_initialize_vcpu(struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg);
+
 int domain_relinquish_resources(struct domain *d);
 
 void dump_pageframe_info(struct domain *d);
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 27/31] xenconsole: try to attach to PV console if HVM fails
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (25 preceding siblings ...)
  2015-08-07 10:18 ` [PATCH v4 26/31] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs Roger Pau Monne
@ 2015-08-07 10:18 ` Roger Pau Monne
  2015-08-07 12:25   ` Wei Liu
  2015-08-07 10:18 ` [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN Roger Pau Monne
                   ` (3 subsequent siblings)
  30 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:18 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

HVM guests have always used the emulated serial console by default, but if
the emulated serial pty cannot be fetched from xenstore try to use the PV
console instead.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Changes since v3:
 - Drop the usage of a label and instead use if conditions.
---
 tools/console/client/main.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/tools/console/client/main.c b/tools/console/client/main.c
index f130a60..d006fdc 100644
--- a/tools/console/client/main.c
+++ b/tools/console/client/main.c
@@ -333,7 +333,7 @@ int main(int argc, char **argv)
 		{ 0 },
 
 	};
-	char *dom_path = NULL, *path = NULL;
+	char *dom_path = NULL, *path = NULL, *test = NULL;
 	int spty, xsfd;
 	struct xs_handle *xs;
 	char *end;
@@ -415,9 +415,15 @@ int main(int argc, char **argv)
 	path = malloc(strlen(dom_path) + strlen("/device/console/0/tty") + 5);
 	if (path == NULL)
 		err(ENOMEM, "malloc");
-	if (type == CONSOLE_SERIAL)
+	if (type == CONSOLE_SERIAL) {
 		snprintf(path, strlen(dom_path) + strlen("/serial/0/tty") + 5, "%s/serial/%d/tty", dom_path, num);
-	else {
+		test = xs_read(xs, XBT_NULL, path, NULL);
+		free(test);
+		if (test == NULL)
+			type = CONSOLE_PV;
+	}
+	if (type == CONSOLE_PV) {
+
 		if (num == 0)
 			snprintf(path, strlen(dom_path) + strlen("/console/tty") + 1, "%s/console/tty", dom_path);
 		else
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (26 preceding siblings ...)
  2015-08-07 10:18 ` [PATCH v4 27/31] xenconsole: try to attach to PV console if HVM fails Roger Pau Monne
@ 2015-08-07 10:18 ` Roger Pau Monne
  2015-08-07 12:32   ` Wei Liu
  2015-08-07 17:30   ` Andrew Cooper
  2015-08-07 10:18 ` [PATCH v4 29/31] libxc/xen: introduce HVM_PARAM_MODLIST_PFN Roger Pau Monne
                   ` (2 subsequent siblings)
  30 siblings, 2 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:18 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
	Ian Jackson, Jan Beulich, Roger Pau Monne

This HVM parameter returns a PFN that contains the address of the memory
page where the guest command line has been placed.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/libxc/xc_dom_x86.c        | 17 +++++++++++++++++
 xen/arch/x86/hvm/hvm.c          |  2 ++
 xen/include/public/hvm/params.h |  5 ++++-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 87bce6e..369745d 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -562,6 +562,23 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
     xc_hvm_param_set(xch, domid, HVM_PARAM_SHARING_RING_PFN,
                      special_pfn(SPECIALPAGE_SHARING));
 
+    if ( dom->cmdline )
+    {
+        xen_pfn_t cmdline_pfn = xc_dom_alloc_page(dom, "command line");
+        char *cmdline = xc_map_foreign_range(xch, domid, PAGE_SIZE,
+                                             PROT_READ | PROT_WRITE,
+                                             cmdline_pfn);
+        if ( cmdline == NULL ) {
+            DOMPRINTF("Unable to map command line page");
+            goto error_out;
+        }
+
+        strncpy(cmdline, dom->cmdline, MAX_GUEST_CMDLINE);
+        cmdline[MAX_GUEST_CMDLINE - 1] = '\0';
+        munmap(cmdline, PAGE_SIZE);
+        xc_hvm_param_set(xch, domid, HVM_PARAM_CMDLINE_PFN, cmdline_pfn);
+    }
+
     if ( dom->emulation )
     {
         /*
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 15ea5e2..615ea30 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -5866,6 +5866,7 @@ static int hvm_allow_set_param(struct domain *d,
     case HVM_PARAM_VM_GENERATION_ID_ADDR:
     case HVM_PARAM_STORE_EVTCHN:
     case HVM_PARAM_CONSOLE_EVTCHN:
+    case HVM_PARAM_CMDLINE_PFN:
         break;
     /*
      * The following parameters must not be set by the guest
@@ -6097,6 +6098,7 @@ static int hvm_allow_get_param(struct domain *d,
     case HVM_PARAM_CONSOLE_PFN:
     case HVM_PARAM_CONSOLE_EVTCHN:
     case HVM_PARAM_ALTP2M:
+    case HVM_PARAM_CMDLINE_PFN:
         break;
     /*
      * The following parameters must not be read by the guest
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index 147d9b8..aa926d4 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -190,6 +190,9 @@
 /* Boolean: Enable altp2m */
 #define HVM_PARAM_ALTP2M       35
 
-#define HVM_NR_PARAMS          36
+/* PFN of the command line. */
+#define HVM_PARAM_CMDLINE_PFN 36
+
+#define HVM_NR_PARAMS          37
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 29/31] libxc/xen: introduce HVM_PARAM_MODLIST_PFN
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (27 preceding siblings ...)
  2015-08-07 10:18 ` [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN Roger Pau Monne
@ 2015-08-07 10:18 ` Roger Pau Monne
  2015-08-07 12:36   ` Wei Liu
  2015-08-07 10:18 ` [PATCH v4 30/31] libxc: switch xc_dom_elfloader to be used with HVMlite domains Roger Pau Monne
  2015-08-07 10:18 ` [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model Roger Pau Monne
  30 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:18 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
	Ian Jackson, Jan Beulich, Keir Fraser, Roger Pau Monne

This HVM parameter is used to pass a list of loaded modules to the guest.
Right now the number of loaded modules is limited to 1 by the current
implementation, but this interface allows passing more than one module.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/libxc/xc_dom_x86.c        | 20 ++++++++++++++++++++
 xen/arch/x86/hvm/hvm.c          |  2 ++
 xen/include/public/hvm/params.h | 23 ++++++++++++++++++++++-
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 369745d..1599de4 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -579,6 +579,26 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
         xc_hvm_param_set(xch, domid, HVM_PARAM_CMDLINE_PFN, cmdline_pfn);
     }
 
+    if ( dom->ramdisk_blob )
+    {
+        xen_pfn_t modlist_pfn = xc_dom_alloc_page(dom, "module list");
+        uint64_t *modlist = xc_map_foreign_range(xch, domid, PAGE_SIZE,
+                                                 PROT_READ | PROT_WRITE,
+                                                 modlist_pfn);
+        if ( modlist == NULL ) {
+            DOMPRINTF("Unable to map module list page");
+            goto error_out;
+        }
+
+        /* This is currently limited to only one module. */
+        modlist[0] = dom->ramdisk_seg.vstart - dom->parms.virt_base;
+        modlist[1] = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
+        modlist[2] = 0;
+        modlist[3] = 0;
+        munmap(modlist, PAGE_SIZE);
+        xc_hvm_param_set(xch, domid, HVM_PARAM_MODLIST_PFN, modlist_pfn);
+    }
+
     if ( dom->emulation )
     {
         /*
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 615ea30..f2223ea 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -5867,6 +5867,7 @@ static int hvm_allow_set_param(struct domain *d,
     case HVM_PARAM_STORE_EVTCHN:
     case HVM_PARAM_CONSOLE_EVTCHN:
     case HVM_PARAM_CMDLINE_PFN:
+    case HVM_PARAM_MODLIST_PFN:
         break;
     /*
      * The following parameters must not be set by the guest
@@ -6099,6 +6100,7 @@ static int hvm_allow_get_param(struct domain *d,
     case HVM_PARAM_CONSOLE_EVTCHN:
     case HVM_PARAM_ALTP2M:
     case HVM_PARAM_CMDLINE_PFN:
+    case HVM_PARAM_MODLIST_PFN:
         break;
     /*
      * The following parameters must not be read by the guest
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index aa926d4..96f944e 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -193,6 +193,27 @@
 /* PFN of the command line. */
 #define HVM_PARAM_CMDLINE_PFN 36
 
-#define HVM_NR_PARAMS          37
+/*
+ * List of modules passed to the kernel.
+ *
+ * The PFN returned by this HVM_PARAM points to a page that contains an
+ * array of unsigned 64bit integers encoded in little endian.
+ *
+ * The first integer contains the address where the module has been loaded,
+ * while the second contains the size of the module in bytes. The last element
+ * in the array is a module with address 0 and length 0:
+ *
+ * module[0] = <address of 1st module>
+ * module[1] = <size of 1st module>
+ * [...]
+ * module[N/2] = <address of module N>
+ * module[N/2+1] = <size of module N>
+ * [...]
+ * module[M] = 0
+ * module[M+1] = 0
+ */
+#define HVM_PARAM_MODLIST_PFN 37
+
+#define HVM_NR_PARAMS          38
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 30/31] libxc: switch xc_dom_elfloader to be used with HVMlite domains
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (28 preceding siblings ...)
  2015-08-07 10:18 ` [PATCH v4 29/31] libxc/xen: introduce HVM_PARAM_MODLIST_PFN Roger Pau Monne
@ 2015-08-07 10:18 ` Roger Pau Monne
  2015-08-07 17:43   ` Andrew Cooper
  2015-08-07 10:18 ` [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model Roger Pau Monne
  30 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:18 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

Allow xc_dom_elfloader to report a guest type as hvm-3.0-x86_32 if it's
running inside of a HVM container and has the PHYS32_ENTRY elfnote set.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Only xc_dom_elfloader has been switched to support HVMlite, other loaders
should also be switched once we have a HVMlite compatible kernel that uses
them.
---
 tools/libxc/xc_dom_elfloader.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
index 66ea9d6..f3a0ed7 100644
--- a/tools/libxc/xc_dom_elfloader.c
+++ b/tools/libxc/xc_dom_elfloader.c
@@ -56,6 +56,10 @@ static char *xc_dom_guest_type(struct xc_dom_image *dom,
 {
     uint64_t machine = elf_uval(elf, elf->ehdr, e_machine);
 
+    if ( dom->container_type == XC_DOM_HVM_CONTAINER &&
+         dom->parms.phys_entry != UNSET_ADDR )
+        return "hvm-3.0-x86_32";
+
     switch ( machine )
     {
     case EM_386:
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model.
  2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
                   ` (29 preceding siblings ...)
  2015-08-07 10:18 ` [PATCH v4 30/31] libxc: switch xc_dom_elfloader to be used with HVMlite domains Roger Pau Monne
@ 2015-08-07 10:18 ` Roger Pau Monne
  2015-08-07 12:58   ` Wei Liu
  2015-08-07 15:18   ` Konrad Rzeszutek Wilk
  30 siblings, 2 replies; 84+ messages in thread
From: Roger Pau Monne @ 2015-08-07 10:18 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, Ian Campbell, Roger Pau Monne

Replace the firmware loaded into HVM guests with an OS kernel. Since the HVM
builder now uses the PV xc_dom_* set of functions this kernel will be parsed
and loaded inside the guest like on PV, but the container is a pure HVM
guest.

Also, if device_model_version is set to none or a device model for the
specified domain is not present unconditinally set the nic type to
LIBXL_NIC_TYPE_VIF.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
Changes since v3:
 - Add explicit /* fall through */ comments.
 - Expand libxl__device_nic_setdefault so that it sets the right nic type
   for HVMlite guests.
 - Remove stray space in hvm_build_set_params.
 - Fix the error paths of libxl__domain_firmware.
---
 docs/man/xl.cfg.pod.5        |  5 ++++
 tools/libxc/xc_dom_x86.c     |  7 +++++
 tools/libxl/libxl.c          | 39 ++++++++++++++-----------
 tools/libxl/libxl_create.c   | 16 ++++++++++-
 tools/libxl/libxl_dm.c       | 13 ++++++++-
 tools/libxl/libxl_dom.c      | 68 ++++++++++++++++++++++++++++++--------------
 tools/libxl/libxl_internal.h |  5 +++-
 tools/libxl/libxl_types.idl  |  1 +
 tools/libxl/libxl_x86.c      |  4 ++-
 tools/libxl/xl_cmdimpl.c     |  2 ++
 10 files changed, 118 insertions(+), 42 deletions(-)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index 80e51bb..8cd7726 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -1741,6 +1741,11 @@ This device-model is the default for Linux dom0.
 Use the device-model based upon the historical Xen fork of Qemu.
 This device-model is still the default for NetBSD dom0.
 
+=item B<none>
+
+Don't use any device model. This requires a kernel capable of booting
+in this mode.
+
 =back
 
 It is recommended to accept the default value for new guests.  If
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 1599de4..d67feb0 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -1269,6 +1269,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
     if ( nr_pages > target_pages )
         memflags |= XENMEMF_populate_on_demand;
 
+    /* Make sure there's a MMIO hole for the special pages. */
+    if ( dom->mmio_size == 0 )
+    {
+        dom->mmio_size = NR_SPECIAL_PAGES << PAGE_SHIFT;
+        dom->mmio_start = special_pfn(0);
+    }
+
     if ( dom->nr_vmemranges == 0 )
     {
         /* Build dummy vnode information
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 083f099..a01868a 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -1033,11 +1033,13 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
     }
 
     if (type == LIBXL_DOMAIN_TYPE_HVM) {
-        rc = libxl__domain_resume_device_model(gc, domid);
-        if (rc < 0) {
-            LOG(ERROR, "failed to unpause device model for domain %u:%d",
-                domid, rc);
-            goto out;
+        if (libxl__domain_has_device_model(gc, domid)) {
+            rc = libxl__domain_resume_device_model(gc, domid);
+            if (rc < 0) {
+                LOG(ERROR, "failed to unpause device model for domain %u:%d",
+                    domid, rc);
+                goto out;
+            }
         }
     }
     ret = xc_domain_unpause(ctx->xch, domid);
@@ -1567,7 +1569,6 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
     libxl_ctx *ctx = CTX;
     uint32_t domid = dis->domid;
     char *dom_path;
-    char *pid;
     int rc, dm_present;
 
     libxl__ev_child_init(&dis->destroyer);
@@ -1584,14 +1585,13 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
 
     switch (libxl__domain_type(gc, domid)) {
     case LIBXL_DOMAIN_TYPE_HVM:
-        if (!libxl_get_stubdom_id(CTX, domid))
-            dm_present = 1;
-        else
+        if (libxl_get_stubdom_id(CTX, domid)) {
             dm_present = 0;
-        break;
+            break;
+        }
+        /* fall through */
     case LIBXL_DOMAIN_TYPE_PV:
-        pid = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/image/device-model-pid", domid));
-        dm_present = (pid != NULL);
+        dm_present = libxl__domain_has_device_model(gc, domid);
         break;
     case LIBXL_DOMAIN_TYPE_INVALID:
         rc = ERROR_FAIL;
@@ -3203,7 +3203,7 @@ out:
 /******************************************************************************/
 
 int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
-                                 uint32_t domid)
+                                 uint32_t domid, libxl_domain_build_info *info)
 {
     int rc;
 
@@ -3240,8 +3240,15 @@ int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
 
     switch (libxl__domain_type(gc, domid)) {
     case LIBXL_DOMAIN_TYPE_HVM:
-        if (!nic->nictype)
-            nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
+        if (!nic->nictype) {
+            if (info != NULL &&
+                info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE)
+                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
+            else if (libxl__domain_has_device_model(gc, domid))
+                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
+            else
+                nic->nictype = LIBXL_NIC_TYPE_VIF;
+        }
         break;
     case LIBXL_DOMAIN_TYPE_PV:
         if (nic->nictype == LIBXL_NIC_TYPE_VIF_IOEMU) {
@@ -3290,7 +3297,7 @@ void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
     libxl_device_nic_init(&nic_saved);
     libxl_device_nic_copy(CTX, &nic_saved, nic);
 
-    rc = libxl__device_nic_setdefault(gc, nic, domid);
+    rc = libxl__device_nic_setdefault(gc, nic, domid, NULL);
     if (rc) goto out;
 
     front = flexarray_make(gc, 16, 1);
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 2348ffc..6738e34 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -119,6 +119,8 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
                 b_info->u.hvm.bios = LIBXL_BIOS_TYPE_ROMBIOS; break;
             case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
                 b_info->u.hvm.bios = LIBXL_BIOS_TYPE_SEABIOS; break;
+            case LIBXL_DEVICE_MODEL_VERSION_NONE:
+                break;
             default:return ERROR_INVAL;
             }
 
@@ -132,6 +134,8 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
             if (b_info->u.hvm.bios == LIBXL_BIOS_TYPE_ROMBIOS)
                 return ERROR_INVAL;
             break;
+        case LIBXL_DEVICE_MODEL_VERSION_NONE:
+            break;
         default:abort();
         }
 
@@ -236,6 +240,9 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
                 break;
             }
             break;
+        case LIBXL_DEVICE_MODEL_VERSION_NONE:
+            b_info->video_memkb = 0;
+            break;
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
         default:
             switch (b_info->u.hvm.vga.kind) {
@@ -923,7 +930,8 @@ static void initiate_domain_create(libxl__egc *egc,
          * called libxl_device_nic_add when domcreate_launch_dm gets called,
          * but qemu needs the nic information to be complete.
          */
-        ret = libxl__device_nic_setdefault(gc, &d_config->nics[i], domid);
+        ret = libxl__device_nic_setdefault(gc, &d_config->nics[i], domid,
+                                           &d_config->b_info);
         if (ret) {
             LOG(ERROR, "Unable to set nic defaults for nic %d", i);
             goto error_out;
@@ -1260,6 +1268,12 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
         libxl__device_console_add(gc, domid, &console, state, &device);
         libxl__device_console_dispose(&console);
 
+        if (d_config->b_info.device_model_version ==
+            LIBXL_DEVICE_MODEL_VERSION_NONE) {
+            domcreate_devmodel_started(egc, &dcs->dmss.dm, 0);
+            return;
+        }
+
         libxl_device_vkb_init(&vkb);
         libxl__device_vkb_add(gc, domid, &vkb);
         libxl_device_vkb_dispose(&vkb);
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index f6b4c89..7e71ce9 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1501,7 +1501,8 @@ static void spawn_stub_launch_dm(libxl__egc *egc,
          * called libxl_device_nic_add at this point, but qemu needs
          * the nic information to be complete.
          */
-        ret = libxl__device_nic_setdefault(gc, &dm_config->nics[i], dm_domid);
+        ret = libxl__device_nic_setdefault(gc, &dm_config->nics[i], dm_domid,
+                                           &dm_config->b_info);
         if (ret)
             goto out;
     }
@@ -1993,6 +1994,16 @@ out:
     return rc;
 }
 
+bool libxl__domain_has_device_model(libxl__gc *gc, uint32_t domid)
+{
+    char *pid;
+
+    pid = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("/local/domain/%d/image/device-model-pid", domid));
+
+    return (pid != NULL);
+}
+
 int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid)
 {
     char *path = libxl__device_model_xs_path(gc, LIBXL_TOOLSTACK_DOMID,
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 8b8e079..a8a02ac 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -781,21 +781,23 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
     uint64_t str_mfn, cons_mfn;
     int i;
 
-    va_map = xc_map_foreign_range(handle, domid,
-                                  XC_PAGE_SIZE, PROT_READ | PROT_WRITE,
-                                  HVM_INFO_PFN);
-    if (va_map == NULL)
-        return ERROR_FAIL;
+    if (info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE) {
+        va_map = xc_map_foreign_range(handle, domid,
+                                      XC_PAGE_SIZE, PROT_READ | PROT_WRITE,
+                                      HVM_INFO_PFN);
+        if (va_map == NULL)
+            return ERROR_FAIL;
 
-    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
-    va_hvm->apic_mode = libxl_defbool_val(info->u.hvm.apic);
-    va_hvm->nr_vcpus = info->max_vcpus;
-    memset(va_hvm->vcpu_online, 0, sizeof(va_hvm->vcpu_online));
-    memcpy(va_hvm->vcpu_online, info->avail_vcpus.map, info->avail_vcpus.size);
-    for (i = 0, sum = 0; i < va_hvm->length; i++)
-        sum += ((uint8_t *) va_hvm)[i];
-    va_hvm->checksum -= sum;
-    munmap(va_map, XC_PAGE_SIZE);
+        va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
+        va_hvm->apic_mode = libxl_defbool_val(info->u.hvm.apic);
+        va_hvm->nr_vcpus = info->max_vcpus;
+        memset(va_hvm->vcpu_online, 0, sizeof(va_hvm->vcpu_online));
+        memcpy(va_hvm->vcpu_online, info->avail_vcpus.map, info->avail_vcpus.size);
+        for (i = 0, sum = 0; i < va_hvm->length; i++)
+            sum += ((uint8_t *) va_hvm)[i];
+        va_hvm->checksum -= sum;
+        munmap(va_map, XC_PAGE_SIZE);
+    }
 
     xc_hvm_param_get(handle, domid, HVM_PARAM_STORE_PFN, &str_mfn);
     xc_hvm_param_get(handle, domid, HVM_PARAM_CONSOLE_PFN, &cons_mfn);
@@ -861,7 +863,7 @@ static int libxl__domain_firmware(libxl__gc *gc,
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     const char *firmware;
-    int e, rc = ERROR_FAIL;
+    int e, rc;
     int datalen = 0;
     void *data;
 
@@ -876,18 +878,34 @@ static int libxl__domain_firmware(libxl__gc *gc,
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
             firmware = "hvmloader";
             break;
+        case LIBXL_DEVICE_MODEL_VERSION_NONE:
+            if (info->kernel == NULL) {
+                LOG(ERROR, "no device model requested without a kernel");
+                rc = ERROR_FAIL;
+                goto out;
+            }
+            break;
         default:
             LOG(ERROR, "invalid device model version %d",
                 info->device_model_version);
-            return ERROR_FAIL;
-            break;
+            rc = ERROR_FAIL;
+            goto out;
         }
     }
 
-    rc = xc_dom_kernel_file(dom, libxl__abs_path(gc, firmware,
+    if (info->kernel != NULL &&
+        info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_NONE) {
+        /* Try to load a kernel instead of the firmware. */
+        rc = xc_dom_kernel_file(dom, info->kernel);
+        if (rc == 0 && info->ramdisk != NULL)
+            rc = xc_dom_ramdisk_file(dom, info->ramdisk);
+    } else {
+        rc = xc_dom_kernel_file(dom, libxl__abs_path(gc, firmware,
                                                  libxl__xenfirmwaredir_path()));
+    }
+
     if (rc != 0) {
-        LOGE(ERROR, "xc_dom_kernel_file failed");
+        LOGE(ERROR, "xc_dom_{kernel_file/ramdisk_file} failed");
         goto out;
     }
 
@@ -898,6 +916,7 @@ static int libxl__domain_firmware(libxl__gc *gc,
         if (e) {
             LOGEV(ERROR, e, "failed to read SMBIOS firmware file %s",
                 info->u.hvm.smbios_firmware);
+            rc = ERROR_FAIL;
             goto out;
         }
         libxl__ptr_add(gc, data);
@@ -915,6 +934,7 @@ static int libxl__domain_firmware(libxl__gc *gc,
         if (e) {
             LOGEV(ERROR, e, "failed to read ACPI firmware file %s",
                 info->u.hvm.acpi_firmware);
+            rc = ERROR_FAIL;
             goto out;
         }
         libxl__ptr_add(gc, data);
@@ -927,6 +947,7 @@ static int libxl__domain_firmware(libxl__gc *gc,
 
     return 0;
 out:
+    assert(rc != 0);
     return rc;
 }
 
@@ -939,10 +960,13 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
     uint64_t mmio_start, lowmem_end, highmem_end, mem_size;
     libxl_domain_build_info *const info = &d_config->b_info;
     struct xc_dom_image *dom = NULL;
+    bool emulated_devices =
+        info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE ?
+        true : false;
 
     xc_dom_loginit(ctx->xch);
 
-    dom = xc_dom_allocate(ctx->xch, NULL, NULL);
+    dom = xc_dom_allocate(ctx->xch, info->cmdline, NULL);
     if (!dom) {
         LOGE(ERROR, "xc_dom_allocate failed");
         goto out;
@@ -974,7 +998,7 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
 
     if (dom->target_pages == 0)
         dom->target_pages = mem_size >> XC_PAGE_SHIFT;
-    if (dom->mmio_size == 0)
+    if (dom->mmio_size == 0 && emulated_devices)
         dom->mmio_size = HVM_BELOW_4G_MMIO_LENGTH;
     lowmem_end = mem_size;
     highmem_end = 0;
@@ -987,7 +1011,7 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
     dom->lowmem_end = lowmem_end;
     dom->highmem_end = highmem_end;
     dom->mmio_start = mmio_start;
-    dom->emulation = true;
+    dom->emulation = emulated_devices;
 
     rc = libxl__domain_device_construct_rdm(gc, d_config,
                                             info->u.hvm.rdm_mem_boundary_memkb*1024,
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index ea89f1f..ee8d03d 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1172,7 +1172,8 @@ _hidden int libxl__domain_build_info_setdefault(libxl__gc *gc,
 _hidden int libxl__device_disk_setdefault(libxl__gc *gc,
                                           libxl_device_disk *disk);
 _hidden int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
-                                         uint32_t domid);
+                                         uint32_t domid,
+                                         libxl_domain_build_info *info);
 _hidden int libxl__device_vtpm_setdefault(libxl__gc *gc, libxl_device_vtpm *vtpm);
 _hidden int libxl__device_vfb_setdefault(libxl__gc *gc, libxl_device_vfb *vfb);
 _hidden int libxl__device_vkb_setdefault(libxl__gc *gc, libxl_device_vkb *vkb);
@@ -1617,6 +1618,8 @@ _hidden int libxl__wait_for_device_model_deprecated(libxl__gc *gc,
 
 _hidden int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid);
 
+_hidden bool libxl__domain_has_device_model(libxl__gc *gc, uint32_t domid);
+
 _hidden const libxl_vnc_info *libxl__dm_vnc(const libxl_domain_config *g_cfg);
 
 _hidden char *libxl__abs_path(libxl__gc *gc, const char *s, const char *path);
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index ef346e7..b6e99c4 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -98,6 +98,7 @@ libxl_device_model_version = Enumeration("device_model_version", [
     (0, "UNKNOWN"),
     (1, "QEMU_XEN_TRADITIONAL"), # Historical qemu-xen device model (qemu-dm)
     (2, "QEMU_XEN"),             # Upstream based qemu-xen device model
+    (3, "NONE"),                 # No device model
     ])
 
 libxl_console_type = Enumeration("console_type", [
diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
index 270f3cf..21424a5 100644
--- a/tools/libxl/libxl_x86.c
+++ b/tools/libxl/libxl_x86.c
@@ -7,7 +7,9 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
                                       libxl_domain_config *d_config,
                                       xc_domain_configuration_t *xc_config)
 {
-    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM)
+    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM &&
+        d_config->b_info.device_model_version !=
+        LIBXL_DEVICE_MODEL_VERSION_NONE)
         xc_config->emulation_flags = (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET |
                                       XEN_X86_EMU_PMTIMER | XEN_X86_EMU_RTC |
                                       XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC |
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 499a05c..2776318 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -2148,6 +2148,8 @@ skip_vfb:
         } else if (!strcmp(buf, "qemu-xen")) {
             b_info->device_model_version
                 = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN;
+        } else if (!strcmp(buf, "none")) {
+            b_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_NONE;
         } else {
             fprintf(stderr,
                     "Unknown device_model_version \"%s\" specified\n", buf);
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling
  2015-08-07 10:17 ` [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling Roger Pau Monne
@ 2015-08-07 10:49   ` Wei Liu
  2015-08-07 10:55     ` Roger Pau Monné
  2015-08-13 15:04   ` Ian Jackson
  2015-08-13 15:06   ` Wei Liu
  2 siblings, 1 reply; 84+ messages in thread
From: Wei Liu @ 2015-08-07 10:49 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:17:38PM +0200, Roger Pau Monne wrote:
> With the current code in libxl__build_hvm it is possible for the function to
> fail and still return 0.

It's hard to see where the bug is when this patch also does a bunch of
refactoring.

It would be good if you can separate the bug fix from other name
changing bits, so that we can apply that bug fix for 4.6 possibly queue
it up for backporting.

Wei.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling
  2015-08-07 10:49   ` Wei Liu
@ 2015-08-07 10:55     ` Roger Pau Monné
  2015-08-07 11:03       ` Wei Liu
  0 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-07 10:55 UTC (permalink / raw)
  To: Wei Liu; +Cc: xen-devel, Ian Jackson, Ian Campbell, Stefano Stabellini

El 07/08/15 a les 12.49, Wei Liu ha escrit:
> On Fri, Aug 07, 2015 at 12:17:38PM +0200, Roger Pau Monne wrote:
>> With the current code in libxl__build_hvm it is possible for the function to
>> fail and still return 0.
> 
> It's hard to see where the bug is when this patch also does a bunch of
> refactoring.

It refactors the error paths only, mainly replacing:

if (libxl_call_foo(bar))
    <error>

to

rc = libxl_call_foo(bar)
if (rc != 0)
    <error>

So we can keep the error codes returned by auxiliary functions.

> It would be good if you can separate the bug fix from other name
> changing bits, so that we can apply that bug fix for 4.6 possibly queue
> it up for backporting.

There are no name changing bits AFAICT.

Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling
  2015-08-07 10:55     ` Roger Pau Monné
@ 2015-08-07 11:03       ` Wei Liu
  2015-08-07 11:28         ` Roger Pau Monné
  0 siblings, 1 reply; 84+ messages in thread
From: Wei Liu @ 2015-08-07 11:03 UTC (permalink / raw)
  To: Roger Pau Monné
  Cc: xen-devel, Ian Campbell, Wei Liu, Ian Jackson, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:55:21PM +0200, Roger Pau Monné wrote:
> El 07/08/15 a les 12.49, Wei Liu ha escrit:
> > On Fri, Aug 07, 2015 at 12:17:38PM +0200, Roger Pau Monne wrote:
> >> With the current code in libxl__build_hvm it is possible for the function to
> >> fail and still return 0.

I care about this bit, which states clearly there is a bug that needs
fixing.

> > 
> > It's hard to see where the bug is when this patch also does a bunch of
> > refactoring.
> 
> It refactors the error paths only, mainly replacing:
> 
> if (libxl_call_foo(bar))
>     <error>
> 
> to
> 
> rc = libxl_call_foo(bar)
> if (rc != 0)
>     <error>
> 

But this suggests there is no bug? 

> So we can keep the error codes returned by auxiliary functions.
> 
> > It would be good if you can separate the bug fix from other name
> > changing bits, so that we can apply that bug fix for 4.6 possibly queue
> > it up for backporting.
> 
> There are no name changing bits AFAICT.
> 

Changing ret for rc is naming changing to me. It's a good thing to do to
comply with coding style, but mixing this with bug fix makes it hard to
backport the fix itself.

Wei.

> Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling
  2015-08-07 11:03       ` Wei Liu
@ 2015-08-07 11:28         ` Roger Pau Monné
  2015-08-07 11:43           ` Wei Liu
  0 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-07 11:28 UTC (permalink / raw)
  To: Wei Liu; +Cc: xen-devel, Ian Jackson, Ian Campbell, Stefano Stabellini

El 07/08/15 a les 13.03, Wei Liu ha escrit:
> On Fri, Aug 07, 2015 at 12:55:21PM +0200, Roger Pau Monné wrote:
>> El 07/08/15 a les 12.49, Wei Liu ha escrit:
>>> On Fri, Aug 07, 2015 at 12:17:38PM +0200, Roger Pau Monne wrote:
>>>> With the current code in libxl__build_hvm it is possible for the function to
>>>> fail and still return 0.
> 
> I care about this bit, which states clearly there is a bug that needs
> fixing.

There are a bunch of error paths in this function that needs fixing,
every error path below the call to libxl__domain_device_construct_rdm
will simply return with rc = 0, because the return code of the functions
is stored in ret, but the return code for libxl__build_hvm is fetched
from rc.

>>> It's hard to see where the bug is when this patch also does a bunch of
>>> refactoring.
>>
>> It refactors the error paths only, mainly replacing:
>>
>> if (libxl_call_foo(bar))
>>     <error>
>>
>> to
>>
>> rc = libxl_call_foo(bar)
>> if (rc != 0)
>>     <error>
>>
> 
> But this suggests there is no bug?

The bug is that we return with rc = 0, that's why it's important to
change this to follow the coding style. I agree that the patch could be
simpler by setting rc to some sane value in each error path (or just
setting rc to ERROR_FAIL in the out label), but it doesn't make much
sense to me to do this kind of fixing. If we fix it, we fix it for good.

> 
>> So we can keep the error codes returned by auxiliary functions.
>>
>>> It would be good if you can separate the bug fix from other name
>>> changing bits, so that we can apply that bug fix for 4.6 possibly queue
>>> it up for backporting.
>>
>> There are no name changing bits AFAICT.
>>
> 
> Changing ret for rc is naming changing to me. It's a good thing to do to
> comply with coding style, but mixing this with bug fix makes it hard to
> backport the fix itself.

I agree that the patch could be simplified, and I can send a simpler fix
iif needed, but as said above I would prefer to fix it in a proper way.

Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 08/31] libxc: rework BSP initialization
  2015-08-07 10:17 ` [PATCH v4 08/31] libxc: rework BSP initialization Roger Pau Monne
@ 2015-08-07 11:31   ` Wei Liu
  2015-08-07 12:04     ` Roger Pau Monné
  2015-08-07 15:22   ` Andrew Cooper
  1 sibling, 1 reply; 84+ messages in thread
From: Wei Liu @ 2015-08-07 11:31 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:17:45PM +0200, Roger Pau Monne wrote:
> Place the calls to xc_vcpu_setcontext and the allocation of the hypercall
> buffer into the arch-specific vcpu hooks. This is needed for the next patch,
> so x86 HVM guests can initialize the BSP using XEN_DOMCTL_sethvmcontext
> instead of XEN_DOMCTL_setvcpucontext.
> 
> This patch should not introduce any functional change.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> ---
>  tools/libxc/include/xc_dom.h |  2 +-
>  tools/libxc/xc_dom_arm.c     | 22 +++++++++++++++++-----
>  tools/libxc/xc_dom_boot.c    | 23 +----------------------
>  tools/libxc/xc_dom_x86.c     | 26 ++++++++++++++++++++------
>  4 files changed, 39 insertions(+), 34 deletions(-)
> 
> diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
> index 5c1bb0f..0245d24 100644
> --- a/tools/libxc/include/xc_dom.h
> +++ b/tools/libxc/include/xc_dom.h
> @@ -221,7 +221,7 @@ struct xc_dom_arch {
>      /* arch-specific data structs setup */
>      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, void *vcpu_ctxt);
> +    int (*vcpu) (struct xc_dom_image * dom);
>      int (*bootearly) (struct xc_dom_image * dom);
>      int (*bootlate) (struct xc_dom_image * dom);
>  
> diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
> index 7548dae..8865097 100644
> --- a/tools/libxc/xc_dom_arm.c
> +++ b/tools/libxc/xc_dom_arm.c
> @@ -119,9 +119,10 @@ static int shared_info_arm(struct xc_dom_image *dom, void *ptr)
>  
>  /* ------------------------------------------------------------------------ */
>  
> -static int vcpu_arm32(struct xc_dom_image *dom, void *ptr)
> +static int vcpu_arm32(struct xc_dom_image *dom)
>  {
> -    vcpu_guest_context_t *ctxt = ptr;
> +    vcpu_guest_context_any_t any_ctx;
> +    vcpu_guest_context_t *ctxt = &any_ctx.c;
>  

I think you still need to allocate hypercall safe buffer here, as well
as in other vcpu_* functions.

>      DOMPRINTF_CALLED(dom->xch);
>  
> @@ -154,12 +155,18 @@ static int vcpu_arm32(struct xc_dom_image *dom, void *ptr)
>      DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32,
>             ctxt->user_regs.cpsr, ctxt->user_regs.pc32);
>  
> -    return 0;
> +    rc = xc_vcpu_setcontext(dom->xch, dom->guest_domid, 0, &any_ctx);
> +    if ( rc != 0 )
> +        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
> +                     "%s: SETVCPUCONTEXT failed (rc=%d)", __func__, rc);
> +
> +    return rc;
>  }
>  
[...]
> -    ctxt = xc_hypercall_buffer_alloc(dom->xch, ctxt, sizeof(*ctxt));
> -    if ( ctxt == NULL )
> -        return -1;
> -
>      DOMPRINTF_CALLED(dom->xch);
>  
>      /* misc stuff*/
> @@ -259,13 +241,10 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
>          return rc;
>  
>      /* let the vm run */
> -    memset(ctxt, 0, sizeof(*ctxt));
> -    if ( (rc = dom->arch_hooks->vcpu(dom, ctxt)) != 0 )
> +    if ( (rc = dom->arch_hooks->vcpu(dom)) != 0 )
>          return rc;
>      xc_dom_unmap_all(dom);

This is not your problem, but this xc_dom_unmap_all is really
suspicious.

Wei.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling
  2015-08-07 11:28         ` Roger Pau Monné
@ 2015-08-07 11:43           ` Wei Liu
  0 siblings, 0 replies; 84+ messages in thread
From: Wei Liu @ 2015-08-07 11:43 UTC (permalink / raw)
  To: Roger Pau Monné
  Cc: xen-devel, Ian Campbell, Wei Liu, Ian Jackson, Stefano Stabellini

On Fri, Aug 07, 2015 at 01:28:32PM +0200, Roger Pau Monné wrote:
> El 07/08/15 a les 13.03, Wei Liu ha escrit:
> > On Fri, Aug 07, 2015 at 12:55:21PM +0200, Roger Pau Monné wrote:
> >> El 07/08/15 a les 12.49, Wei Liu ha escrit:
> >>> On Fri, Aug 07, 2015 at 12:17:38PM +0200, Roger Pau Monne wrote:
> >>>> With the current code in libxl__build_hvm it is possible for the function to
> >>>> fail and still return 0.
> > 
> > I care about this bit, which states clearly there is a bug that needs
> > fixing.
> 
> There are a bunch of error paths in this function that needs fixing,
> every error path below the call to libxl__domain_device_construct_rdm
> will simply return with rc = 0, because the return code of the functions
> is stored in ret, but the return code for libxl__build_hvm is fetched
> from rc.
> 

I see. Arguably that's a bug in RDM series. Not a regression.  And I
think I should post a two-liner patch to change rc to ret. This would be
a short bug fix for 4.6.

That would then make your patch a pure refactoring patch and be ready to
be applied for 4.7.

The other option is to apply this patch for 4.6. Since you didn't tag
this patch for-4.6, I didn't have that thought at the time I saw it.

Which way do you prefer? If you want the latter please resend this
single patch, reword the commit message to make it clearer.

Wei.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 09/31] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests
  2015-08-07 10:17 ` [PATCH v4 09/31] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests Roger Pau Monne
@ 2015-08-07 12:00   ` Wei Liu
  2015-08-07 15:58   ` Andrew Cooper
  1 sibling, 0 replies; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:00 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:17:46PM +0200, Roger Pau Monne wrote:
> This xc_dom_arch will be used in order to build HVM domains. The code is
> based on the existing xc_hvm_populate_memory and xc_hvm_populate_params
> functions.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> ---
> Changes since v3:
>  - Make sure c/s b9dbe33 is not reverted on this patch.
>  - Set the initial BSP state using {get/set}hvmcontext.
> ---
[...]
> +static void build_hvm_info(void *hvm_info_page, struct xc_dom_image *dom)
> +{
[...]
> +}
> +
> +static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
> +{
[...]
> +static int meminit_hvm(struct xc_dom_image *dom)
> +{

I didn't do a line by line comparison with original implementation for
every items in these functions, but if you forgot to move something here
I'm pretty sure we can easily spot that in the future. :-)

[...]
> +    xc_hvm_param_set(xch, domid, HVM_PARAM_IDENT_PT,
> +                     special_pfn(SPECIALPAGE_IDENT_PT) << PAGE_SHIFT);
> +
> +    dom->console_pfn = special_pfn(SPECIALPAGE_CONSOLE);
> +    dom->xenstore_pfn = special_pfn(SPECIALPAGE_XENSTORE);
> +    dom->parms.virt_hypercall = -1;
> +
> +    rc = 0;
> +    goto out;
> + error_out:
> +    rc = -1;
> + out:
> +
> +    return rc;

You can just write:

     rc = 0;
     return rc;
error_out:
     rc = -1
     return rc;

> +}
> +
>  /* ------------------------------------------------------------------------ */
>  
>  static int start_info_x86_32(struct xc_dom_image *dom)
> @@ -682,6 +833,103 @@ static int vcpu_x86_64(struct xc_dom_image *dom)
>      return rc;
>  }
>  
> +static int vcpu_hvm(struct xc_dom_image *dom)
> +{
> +    struct {
> +        struct hvm_save_descriptor header_d;
> +        HVM_SAVE_TYPE(HEADER) header;
> +        struct hvm_save_descriptor cpu_d;
> +        HVM_SAVE_TYPE(CPU) cpu;
> +        struct hvm_save_descriptor end_d;
> +        HVM_SAVE_TYPE(END) end;
> +    } bsp_ctx;
> +    uint8_t *full_ctx = NULL;
> +    int rc;
> +
> +    DOMPRINTF_CALLED(dom->xch);
> +
> +    /*
> +     * Get the full HVM context in order to have the header, it is not
> +     * possible to get the header with getcontext_partial, and crafting one
> +     * from userspace is also not an option since cpuid is trapped and
> +     * modified by Xen.
> +     */
> +
> +    rc = xc_domain_hvm_getcontext(dom->xch, dom->guest_domid, NULL, 0);
> +    if ( rc <= 0 )
> +    {
> +        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
> +                     "%s: unable to fetch HVM context size (rc=%d)",
> +                     __func__, rc);
> +        return rc;
> +    }
> +    full_ctx = malloc(rc);

xc_dom_malloc?

But you perhaps need hypercall safe buffer here.

The rest of this patch looks like purely mechanic changes to me so I
skip.

Wei.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 08/31] libxc: rework BSP initialization
  2015-08-07 11:31   ` Wei Liu
@ 2015-08-07 12:04     ` Roger Pau Monné
  2015-08-07 12:06       ` Wei Liu
  0 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-07 12:04 UTC (permalink / raw)
  To: Wei Liu; +Cc: xen-devel, Ian Jackson, Ian Campbell, Stefano Stabellini

El 07/08/15 a les 13.31, Wei Liu ha escrit:
> On Fri, Aug 07, 2015 at 12:17:45PM +0200, Roger Pau Monne wrote:
>> Place the calls to xc_vcpu_setcontext and the allocation of the hypercall
>> buffer into the arch-specific vcpu hooks. This is needed for the next patch,
>> so x86 HVM guests can initialize the BSP using XEN_DOMCTL_sethvmcontext
>> instead of XEN_DOMCTL_setvcpucontext.
>>
>> This patch should not introduce any functional change.
>>
>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>> Cc: Ian Campbell <ian.campbell@citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>> ---
>>  tools/libxc/include/xc_dom.h |  2 +-
>>  tools/libxc/xc_dom_arm.c     | 22 +++++++++++++++++-----
>>  tools/libxc/xc_dom_boot.c    | 23 +----------------------
>>  tools/libxc/xc_dom_x86.c     | 26 ++++++++++++++++++++------
>>  4 files changed, 39 insertions(+), 34 deletions(-)
>>
>> diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
>> index 5c1bb0f..0245d24 100644
>> --- a/tools/libxc/include/xc_dom.h
>> +++ b/tools/libxc/include/xc_dom.h
>> @@ -221,7 +221,7 @@ struct xc_dom_arch {
>>      /* arch-specific data structs setup */
>>      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, void *vcpu_ctxt);
>> +    int (*vcpu) (struct xc_dom_image * dom);
>>      int (*bootearly) (struct xc_dom_image * dom);
>>      int (*bootlate) (struct xc_dom_image * dom);
>>  
>> diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
>> index 7548dae..8865097 100644
>> --- a/tools/libxc/xc_dom_arm.c
>> +++ b/tools/libxc/xc_dom_arm.c
>> @@ -119,9 +119,10 @@ static int shared_info_arm(struct xc_dom_image *dom, void *ptr)
>>  
>>  /* ------------------------------------------------------------------------ */
>>  
>> -static int vcpu_arm32(struct xc_dom_image *dom, void *ptr)
>> +static int vcpu_arm32(struct xc_dom_image *dom)
>>  {
>> -    vcpu_guest_context_t *ctxt = ptr;
>> +    vcpu_guest_context_any_t any_ctx;
>> +    vcpu_guest_context_t *ctxt = &any_ctx.c;
>>  
> 
> I think you still need to allocate hypercall safe buffer here, as well
> as in other vcpu_* functions.

xc_vcpu_setcontext already bounces the buffer before doing the
hypercall, so I think it's safe.

>>      DOMPRINTF_CALLED(dom->xch);
>>  
>> @@ -154,12 +155,18 @@ static int vcpu_arm32(struct xc_dom_image *dom, void *ptr)
>>      DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32,
>>             ctxt->user_regs.cpsr, ctxt->user_regs.pc32);
>>  
>> -    return 0;
>> +    rc = xc_vcpu_setcontext(dom->xch, dom->guest_domid, 0, &any_ctx);
>> +    if ( rc != 0 )
>> +        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
>> +                     "%s: SETVCPUCONTEXT failed (rc=%d)", __func__, rc);
>> +
>> +    return rc;
>>  }
>>  
> [...]
>> -    ctxt = xc_hypercall_buffer_alloc(dom->xch, ctxt, sizeof(*ctxt));
>> -    if ( ctxt == NULL )
>> -        return -1;
>> -
>>      DOMPRINTF_CALLED(dom->xch);
>>  
>>      /* misc stuff*/
>> @@ -259,13 +241,10 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
>>          return rc;
>>  
>>      /* let the vm run */
>> -    memset(ctxt, 0, sizeof(*ctxt));
>> -    if ( (rc = dom->arch_hooks->vcpu(dom, ctxt)) != 0 )
>> +    if ( (rc = dom->arch_hooks->vcpu(dom)) != 0 )
>>          return rc;
>>      xc_dom_unmap_all(dom);
> 
> This is not your problem, but this xc_dom_unmap_all is really
> suspicious.

I agree, xc_dom_release already calls xc_dom_unmap_all. I guess it's not
a big issue since xc_dom_boot_image is almost the last function called
when doing domain creation, but I'm also not that familiar with libxc in
order to figure out if there's a reason for calling xc_dom_unmap_all here.

Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 08/31] libxc: rework BSP initialization
  2015-08-07 12:04     ` Roger Pau Monné
@ 2015-08-07 12:06       ` Wei Liu
  2015-08-07 15:30         ` Andrew Cooper
  0 siblings, 1 reply; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:06 UTC (permalink / raw)
  To: Roger Pau Monné
  Cc: xen-devel, Ian Campbell, Wei Liu, Ian Jackson, Stefano Stabellini

On Fri, Aug 07, 2015 at 02:04:21PM +0200, Roger Pau Monné wrote:
> El 07/08/15 a les 13.31, Wei Liu ha escrit:
> > On Fri, Aug 07, 2015 at 12:17:45PM +0200, Roger Pau Monne wrote:
> >> Place the calls to xc_vcpu_setcontext and the allocation of the hypercall
> >> buffer into the arch-specific vcpu hooks. This is needed for the next patch,
> >> so x86 HVM guests can initialize the BSP using XEN_DOMCTL_sethvmcontext
> >> instead of XEN_DOMCTL_setvcpucontext.
> >>
> >> This patch should not introduce any functional change.
> >>
> >> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> >> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> >> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> >> Cc: Ian Campbell <ian.campbell@citrix.com>
> >> Cc: Wei Liu <wei.liu2@citrix.com>
> >> ---
> >>  tools/libxc/include/xc_dom.h |  2 +-
> >>  tools/libxc/xc_dom_arm.c     | 22 +++++++++++++++++-----
> >>  tools/libxc/xc_dom_boot.c    | 23 +----------------------
> >>  tools/libxc/xc_dom_x86.c     | 26 ++++++++++++++++++++------
> >>  4 files changed, 39 insertions(+), 34 deletions(-)
> >>
> >> diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
> >> index 5c1bb0f..0245d24 100644
> >> --- a/tools/libxc/include/xc_dom.h
> >> +++ b/tools/libxc/include/xc_dom.h
> >> @@ -221,7 +221,7 @@ struct xc_dom_arch {
> >>      /* arch-specific data structs setup */
> >>      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, void *vcpu_ctxt);
> >> +    int (*vcpu) (struct xc_dom_image * dom);
> >>      int (*bootearly) (struct xc_dom_image * dom);
> >>      int (*bootlate) (struct xc_dom_image * dom);
> >>  
> >> diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
> >> index 7548dae..8865097 100644
> >> --- a/tools/libxc/xc_dom_arm.c
> >> +++ b/tools/libxc/xc_dom_arm.c
> >> @@ -119,9 +119,10 @@ static int shared_info_arm(struct xc_dom_image *dom, void *ptr)
> >>  
> >>  /* ------------------------------------------------------------------------ */
> >>  
> >> -static int vcpu_arm32(struct xc_dom_image *dom, void *ptr)
> >> +static int vcpu_arm32(struct xc_dom_image *dom)
> >>  {
> >> -    vcpu_guest_context_t *ctxt = ptr;
> >> +    vcpu_guest_context_any_t any_ctx;
> >> +    vcpu_guest_context_t *ctxt = &any_ctx.c;
> >>  
> > 
> > I think you still need to allocate hypercall safe buffer here, as well
> > as in other vcpu_* functions.
> 
> xc_vcpu_setcontext already bounces the buffer before doing the
> hypercall, so I think it's safe.
> 
> >>      DOMPRINTF_CALLED(dom->xch);
> >>  
> >> @@ -154,12 +155,18 @@ static int vcpu_arm32(struct xc_dom_image *dom, void *ptr)
> >>      DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32,
> >>             ctxt->user_regs.cpsr, ctxt->user_regs.pc32);
> >>  
> >> -    return 0;
> >> +    rc = xc_vcpu_setcontext(dom->xch, dom->guest_domid, 0, &any_ctx);
> >> +    if ( rc != 0 )
> >> +        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
> >> +                     "%s: SETVCPUCONTEXT failed (rc=%d)", __func__, rc);
> >> +
> >> +    return rc;
> >>  }
> >>  
> > [...]
> >> -    ctxt = xc_hypercall_buffer_alloc(dom->xch, ctxt, sizeof(*ctxt));
> >> -    if ( ctxt == NULL )
> >> -        return -1;
> >> -
> >>      DOMPRINTF_CALLED(dom->xch);
> >>  
> >>      /* misc stuff*/
> >> @@ -259,13 +241,10 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
> >>          return rc;
> >>  
> >>      /* let the vm run */
> >> -    memset(ctxt, 0, sizeof(*ctxt));
> >> -    if ( (rc = dom->arch_hooks->vcpu(dom, ctxt)) != 0 )
> >> +    if ( (rc = dom->arch_hooks->vcpu(dom)) != 0 )
> >>          return rc;
> >>      xc_dom_unmap_all(dom);
> > 
> > This is not your problem, but this xc_dom_unmap_all is really
> > suspicious.
> 
> I agree, xc_dom_release already calls xc_dom_unmap_all. I guess it's not
> a big issue since xc_dom_boot_image is almost the last function called
> when doing domain creation, but I'm also not that familiar with libxc in
> order to figure out if there's a reason for calling xc_dom_unmap_all here.
> 

Yeah, let's worry about that later.

Wei.

> Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 10/31] libxl: switch HVM domain building to use xc_dom_* helpers
  2015-08-07 10:17 ` [PATCH v4 10/31] libxl: switch HVM domain building to use xc_dom_* helpers Roger Pau Monne
@ 2015-08-07 12:12   ` Wei Liu
  0 siblings, 0 replies; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:12 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:17:47PM +0200, Roger Pau Monne wrote:
> Now that we have all the code in place HVM domain building in libxl can be
> switched to use the xc_dom_* family of functions, just like they are used in
> order to build PV guests.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>

Acked-by: Wei Liu <wei.liu2@citrix.com>

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 11/31] libxc: remove dead HVM building code
  2015-08-07 10:17 ` [PATCH v4 11/31] libxc: remove dead HVM building code Roger Pau Monne
@ 2015-08-07 12:12   ` Wei Liu
  2015-08-07 15:59   ` Andrew Cooper
  1 sibling, 0 replies; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:12 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:17:48PM +0200, Roger Pau Monne wrote:
> Remove xc_hvm_build_x86.c and xc_hvm_build_arm.c since xc_hvm_build is not
> longer used in order to create HVM guests.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>

Acked-by: Wei Liu <wei.liu2@citrix.com>

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 24/31] libxc: allow creating domains without emulated devices.
  2015-08-07 10:18 ` [PATCH v4 24/31] libxc: allow creating domains without emulated devices Roger Pau Monne
@ 2015-08-07 12:18   ` Wei Liu
  2015-08-07 16:36   ` Andrew Cooper
  1 sibling, 0 replies; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:18 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:18:01PM +0200, Roger Pau Monne wrote:
> Introduce a new flag in xc_dom_image that turns on and off the emulated
> devices. This prevents creating the VGA hole, the hvm_info page and the
> ioreq server pages. libxl unconditionally sets it to true for all HVM
> domains at the moment.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> ---
> Changes since v3:
>  - Explain the meaning of the "emulation" xc_dom_image field.
> ---
>  tools/libxc/include/xc_dom.h |  3 ++
>  tools/libxc/xc_dom_x86.c     | 71 +++++++++++++++++++++++++-------------------
>  tools/libxl/libxl_dom.c      |  1 +
>  3 files changed, 44 insertions(+), 31 deletions(-)
> 
> diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
> index cda40d9..99225cf 100644
> --- a/tools/libxc/include/xc_dom.h
> +++ b/tools/libxc/include/xc_dom.h
> @@ -194,6 +194,9 @@ struct xc_dom_image {
>      xen_pfn_t lowmem_end;
>      xen_pfn_t highmem_end;
>  
> +    /* If set disables the setup of the IOREQ pages and the VGA MMIO hole. */
> +    bool emulation;
> +

My impression is that we might want to enable / disable specific
emulation functionalities in the future, but since this is internal
detail so we have the liberty to do whatever we want.

A single flag and a comment here is good enough for me. The code also
looks correct. So

Acked-by: Wei Liu <wei.liu2@citrix.com>

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 25/31] xen: allow HVM guests to use XENMEM_memory_map
  2015-08-07 10:18 ` [PATCH v4 25/31] xen: allow HVM guests to use XENMEM_memory_map Roger Pau Monne
@ 2015-08-07 12:22   ` Wei Liu
  2015-08-07 15:44     ` Roger Pau Monné
  0 siblings, 1 reply; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:22 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
	Ian Jackson, Jan Beulich, xen-devel

On Fri, Aug 07, 2015 at 12:18:02PM +0200, Roger Pau Monne wrote:
> Enable this hypercall for HVM guests in order to fetch the e820 memory
> map in the absence of an emulated BIOS. The memory map is populated and
> notified to Xen in arch_setup_meminit_hvm.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
>  tools/libxc/xc_dom_x86.c | 29 ++++++++++++++++++++++++++++-
>  1 file changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> index b587b12..87bce6e 100644
> --- a/tools/libxc/xc_dom_x86.c
> +++ b/tools/libxc/xc_dom_x86.c
> @@ -1205,6 +1205,7 @@ static int check_mmio_hole(uint64_t start, uint64_t memsize,
>          return 1;
>  }
>  
> +#define MAX_E820_ENTRIES    128
>  static int meminit_hvm(struct xc_dom_image *dom)
>  {
>      unsigned long i, vmemid, nr_pages = dom->total_pages;
> @@ -1225,6 +1226,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
>      unsigned int nr_vmemranges, nr_vnodes;
>      xc_interface *xch = dom->xch;
>      uint32_t domid = dom->guest_domid;
> +    struct e820entry entries[MAX_E820_ENTRIES];
> +    int e820_index = 0;
>  
>      if ( nr_pages > target_pages )
>          memflags |= XENMEMF_populate_on_demand;
> @@ -1275,6 +1278,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>          vnode_to_pnode = dom->vnode_to_pnode;
>      }
>  
> +    /* Add one additional memory range to account for the VGA hole */
> +    if ( (nr_vmemranges + (dom->emulation ? 1 : 0)) > MAX_E820_ENTRIES )
> +    {
> +        DOMPRINTF("Too many memory ranges");
> +        goto error_out;
> +    }
> +
>      total_pages = 0;
>      p2m_size = 0;
>      for ( i = 0; i < nr_vmemranges; i++ )
> @@ -1363,9 +1373,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>       * Under 2MB mode, we allocate pages in batches of no more than 8MB to 
>       * ensure that we can be preempted and hence dom0 remains responsive.
>       */
> -    if ( dom->emulation )
> +    if ( dom->emulation ) {
>          rc = xc_domain_populate_physmap_exact(
>              xch, domid, 0xa0, 0, memflags, &dom->p2m_host[0x00]);
> +        entries[e820_index].addr = 0;
> +        entries[e820_index].size = 0xa0 << PAGE_SHIFT;
> +        entries[e820_index++].type = E820_RAM;
> +    }
>  
>      stat_normal_pages = 0;
>      for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
> @@ -1392,6 +1406,12 @@ static int meminit_hvm(struct xc_dom_image *dom)
>          else
>              cur_pages = vmemranges[vmemid].start >> PAGE_SHIFT;
>  
> +        /* Build an e820 map. */
> +        entries[e820_index].addr = cur_pages << PAGE_SHIFT;
> +        entries[e820_index].size = vmemranges[vmemid].end -
> +                                   entries[e820_index].addr;
> +        entries[e820_index++].type = E820_RAM;
> +
>          while ( (rc == 0) && (end_pages > cur_pages) )
>          {
>              /* Clip count to maximum 1GB extent. */
> @@ -1509,6 +1529,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>      DPRINTF("  2MB PAGES: 0x%016lx\n", stat_2mb_pages);
>      DPRINTF("  1GB PAGES: 0x%016lx\n", stat_1gb_pages);
>  
> +    rc = xc_domain_set_memory_map(xch, domid, entries, e820_index);
> +    if ( rc != 0 )
> +    {
> +        DOMPRINTF("unable to set memory map.");
> +        goto error_out;
> +    }
> +

I think in RDM series there is already a memory map generated in libxl.

You might want to move this to libxl, which is supposed to be the
arbitrator of what a guest should look like.

What do you think?

Wei.


>      rc = 0;
>      goto out;
>   error_out:
> -- 
> 1.9.5 (Apple Git-50.3)

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 27/31] xenconsole: try to attach to PV console if HVM fails
  2015-08-07 10:18 ` [PATCH v4 27/31] xenconsole: try to attach to PV console if HVM fails Roger Pau Monne
@ 2015-08-07 12:25   ` Wei Liu
  0 siblings, 0 replies; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:25 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:18:04PM +0200, Roger Pau Monne wrote:
> HVM guests have always used the emulated serial console by default, but if
> the emulated serial pty cannot be fetched from xenstore try to use the PV
> console instead.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>

Acked-by: Wei Liu <wei.liu2@citrix.com>

> ---
> Changes since v3:
>  - Drop the usage of a label and instead use if conditions.
> ---
>  tools/console/client/main.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/console/client/main.c b/tools/console/client/main.c
> index f130a60..d006fdc 100644
> --- a/tools/console/client/main.c
> +++ b/tools/console/client/main.c
> @@ -333,7 +333,7 @@ int main(int argc, char **argv)
>  		{ 0 },
>  
>  	};
> -	char *dom_path = NULL, *path = NULL;
> +	char *dom_path = NULL, *path = NULL, *test = NULL;
>  	int spty, xsfd;
>  	struct xs_handle *xs;
>  	char *end;
> @@ -415,9 +415,15 @@ int main(int argc, char **argv)
>  	path = malloc(strlen(dom_path) + strlen("/device/console/0/tty") + 5);
>  	if (path == NULL)
>  		err(ENOMEM, "malloc");
> -	if (type == CONSOLE_SERIAL)
> +	if (type == CONSOLE_SERIAL) {
>  		snprintf(path, strlen(dom_path) + strlen("/serial/0/tty") + 5, "%s/serial/%d/tty", dom_path, num);
> -	else {
> +		test = xs_read(xs, XBT_NULL, path, NULL);
> +		free(test);
> +		if (test == NULL)
> +			type = CONSOLE_PV;
> +	}
> +	if (type == CONSOLE_PV) {
> +
>  		if (num == 0)
>  			snprintf(path, strlen(dom_path) + strlen("/console/tty") + 1, "%s/console/tty", dom_path);
>  		else
> -- 
> 1.9.5 (Apple Git-50.3)

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN
  2015-08-07 10:18 ` [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN Roger Pau Monne
@ 2015-08-07 12:32   ` Wei Liu
  2015-08-07 17:30   ` Andrew Cooper
  1 sibling, 0 replies; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:32 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
	Ian Jackson, Jan Beulich, xen-devel

On Fri, Aug 07, 2015 at 12:18:05PM +0200, Roger Pau Monne wrote:
> This HVM parameter returns a PFN that contains the address of the memory
> page where the guest command line has been placed.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
>  tools/libxc/xc_dom_x86.c        | 17 +++++++++++++++++
>  xen/arch/x86/hvm/hvm.c          |  2 ++
>  xen/include/public/hvm/params.h |  5 ++++-
>  3 files changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> index 87bce6e..369745d 100644
> --- a/tools/libxc/xc_dom_x86.c
> +++ b/tools/libxc/xc_dom_x86.c
> @@ -562,6 +562,23 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
>      xc_hvm_param_set(xch, domid, HVM_PARAM_SHARING_RING_PFN,
>                       special_pfn(SPECIALPAGE_SHARING));
>  
> +    if ( dom->cmdline )
> +    {
> +        xen_pfn_t cmdline_pfn = xc_dom_alloc_page(dom, "command line");
> +        char *cmdline = xc_map_foreign_range(xch, domid, PAGE_SIZE,
> +                                             PROT_READ | PROT_WRITE,
> +                                             cmdline_pfn);
> +        if ( cmdline == NULL ) {
> +            DOMPRINTF("Unable to map command line page");
> +            goto error_out;
> +        }
> +
> +        strncpy(cmdline, dom->cmdline, MAX_GUEST_CMDLINE);
> +        cmdline[MAX_GUEST_CMDLINE - 1] = '\0';
> +        munmap(cmdline, PAGE_SIZE);
> +        xc_hvm_param_set(xch, domid, HVM_PARAM_CMDLINE_PFN, cmdline_pfn);
> +    }
> +

FWIW this change looks correct. This bit:

Acked-by: Wei Liu <wei.liu2@citrix.com>


>      if ( dom->emulation )
>      {
>          /*
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index 15ea5e2..615ea30 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -5866,6 +5866,7 @@ static int hvm_allow_set_param(struct domain *d,
>      case HVM_PARAM_VM_GENERATION_ID_ADDR:
>      case HVM_PARAM_STORE_EVTCHN:
>      case HVM_PARAM_CONSOLE_EVTCHN:
> +    case HVM_PARAM_CMDLINE_PFN:
>          break;
>      /*
>       * The following parameters must not be set by the guest
> @@ -6097,6 +6098,7 @@ static int hvm_allow_get_param(struct domain *d,
>      case HVM_PARAM_CONSOLE_PFN:
>      case HVM_PARAM_CONSOLE_EVTCHN:
>      case HVM_PARAM_ALTP2M:
> +    case HVM_PARAM_CMDLINE_PFN:
>          break;
>      /*
>       * The following parameters must not be read by the guest
> diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
> index 147d9b8..aa926d4 100644
> --- a/xen/include/public/hvm/params.h
> +++ b/xen/include/public/hvm/params.h
> @@ -190,6 +190,9 @@
>  /* Boolean: Enable altp2m */
>  #define HVM_PARAM_ALTP2M       35
>  
> -#define HVM_NR_PARAMS          36
> +/* PFN of the command line. */
> +#define HVM_PARAM_CMDLINE_PFN 36
> +
> +#define HVM_NR_PARAMS          37
>  
>  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
> -- 
> 1.9.5 (Apple Git-50.3)

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 29/31] libxc/xen: introduce HVM_PARAM_MODLIST_PFN
  2015-08-07 10:18 ` [PATCH v4 29/31] libxc/xen: introduce HVM_PARAM_MODLIST_PFN Roger Pau Monne
@ 2015-08-07 12:36   ` Wei Liu
  0 siblings, 0 replies; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:36 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
	Ian Jackson, Jan Beulich, xen-devel, Keir Fraser

On Fri, Aug 07, 2015 at 12:18:06PM +0200, Roger Pau Monne wrote:
> This HVM parameter is used to pass a list of loaded modules to the guest.
> Right now the number of loaded modules is limited to 1 by the current
> implementation, but this interface allows passing more than one module.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
>  tools/libxc/xc_dom_x86.c        | 20 ++++++++++++++++++++
>  xen/arch/x86/hvm/hvm.c          |  2 ++
>  xen/include/public/hvm/params.h | 23 ++++++++++++++++++++++-
>  3 files changed, 44 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> index 369745d..1599de4 100644
> --- a/tools/libxc/xc_dom_x86.c
> +++ b/tools/libxc/xc_dom_x86.c
> @@ -579,6 +579,26 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
>          xc_hvm_param_set(xch, domid, HVM_PARAM_CMDLINE_PFN, cmdline_pfn);
>      }
>  
> +    if ( dom->ramdisk_blob )
> +    {
> +        xen_pfn_t modlist_pfn = xc_dom_alloc_page(dom, "module list");
> +        uint64_t *modlist = xc_map_foreign_range(xch, domid, PAGE_SIZE,
> +                                                 PROT_READ | PROT_WRITE,
> +                                                 modlist_pfn);
> +        if ( modlist == NULL ) {
> +            DOMPRINTF("Unable to map module list page");
> +            goto error_out;
> +        }
> +
> +        /* This is currently limited to only one module. */
> +        modlist[0] = dom->ramdisk_seg.vstart - dom->parms.virt_base;
> +        modlist[1] = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
> +        modlist[2] = 0;
> +        modlist[3] = 0;
> +        munmap(modlist, PAGE_SIZE);
> +        xc_hvm_param_set(xch, domid, HVM_PARAM_MODLIST_PFN, modlist_pfn);
> +    }
> +

The code looks correct.

Acked-by: Wei Liu <wei.liu2@citrix.com>

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model.
  2015-08-07 10:18 ` [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model Roger Pau Monne
@ 2015-08-07 12:58   ` Wei Liu
  2015-08-07 15:51     ` Roger Pau Monné
  2015-08-07 15:18   ` Konrad Rzeszutek Wilk
  1 sibling, 1 reply; 84+ messages in thread
From: Wei Liu @ 2015-08-07 12:58 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:18:08PM +0200, Roger Pau Monne wrote:
> Replace the firmware loaded into HVM guests with an OS kernel. Since the HVM
> builder now uses the PV xc_dom_* set of functions this kernel will be parsed
> and loaded inside the guest like on PV, but the container is a pure HVM
> guest.
> 
> Also, if device_model_version is set to none or a device model for the
> specified domain is not present unconditinally set the nic type to
> LIBXL_NIC_TYPE_VIF.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> ---
> Changes since v3:
>  - Add explicit /* fall through */ comments.
>  - Expand libxl__device_nic_setdefault so that it sets the right nic type
>    for HVMlite guests.
>  - Remove stray space in hvm_build_set_params.
>  - Fix the error paths of libxl__domain_firmware.
> ---
>  docs/man/xl.cfg.pod.5        |  5 ++++
>  tools/libxc/xc_dom_x86.c     |  7 +++++
>  tools/libxl/libxl.c          | 39 ++++++++++++++-----------
>  tools/libxl/libxl_create.c   | 16 ++++++++++-
>  tools/libxl/libxl_dm.c       | 13 ++++++++-
>  tools/libxl/libxl_dom.c      | 68 ++++++++++++++++++++++++++++++--------------
>  tools/libxl/libxl_internal.h |  5 +++-
>  tools/libxl/libxl_types.idl  |  1 +
>  tools/libxl/libxl_x86.c      |  4 ++-
>  tools/libxl/xl_cmdimpl.c     |  2 ++
>  10 files changed, 118 insertions(+), 42 deletions(-)
> 
> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
> index 80e51bb..8cd7726 100644
> --- a/docs/man/xl.cfg.pod.5
> +++ b/docs/man/xl.cfg.pod.5
> @@ -1741,6 +1741,11 @@ This device-model is the default for Linux dom0.
>  Use the device-model based upon the historical Xen fork of Qemu.
>  This device-model is still the default for NetBSD dom0.
>  
> +=item B<none>
> +
> +Don't use any device model. This requires a kernel capable of booting
> +in this mode.

booting without emulated devices?

> +
>  =back
>  
>  It is recommended to accept the default value for new guests.  If
> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> index 1599de4..d67feb0 100644
> --- a/tools/libxc/xc_dom_x86.c
> +++ b/tools/libxc/xc_dom_x86.c
> @@ -1269,6 +1269,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>      if ( nr_pages > target_pages )
>          memflags |= XENMEMF_populate_on_demand;
>  
> +    /* Make sure there's a MMIO hole for the special pages. */
> +    if ( dom->mmio_size == 0 )
> +    {
> +        dom->mmio_size = NR_SPECIAL_PAGES << PAGE_SHIFT;
> +        dom->mmio_start = special_pfn(0);
> +    }
> +

Better to just assert(dom->mmio_size != 0);

It's really libxl's responsibility to generate memory layout for guest.
Libxc doesn't have all information to make the decision.

>      if ( dom->nr_vmemranges == 0 )
>      {
>          /* Build dummy vnode information
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index 083f099..a01868a 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -1033,11 +1033,13 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
>      }
>  
>      if (type == LIBXL_DOMAIN_TYPE_HVM) {
> -        rc = libxl__domain_resume_device_model(gc, domid);
> -        if (rc < 0) {
> -            LOG(ERROR, "failed to unpause device model for domain %u:%d",
> -                domid, rc);
> -            goto out;
> +        if (libxl__domain_has_device_model(gc, domid)) {

Checking for device model version is not enough?

> +            rc = libxl__domain_resume_device_model(gc, domid);
> +            if (rc < 0) {
> +                LOG(ERROR, "failed to unpause device model for domain %u:%d",
> +                    domid, rc);
> +                goto out;
> +            }
>          }
>      }
>      ret = xc_domain_unpause(ctx->xch, domid);
> @@ -1567,7 +1569,6 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
>      libxl_ctx *ctx = CTX;
>      uint32_t domid = dis->domid;
>      char *dom_path;
> -    char *pid;
>      int rc, dm_present;
>  
>      libxl__ev_child_init(&dis->destroyer);
> @@ -1584,14 +1585,13 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
>  
>      switch (libxl__domain_type(gc, domid)) {
>      case LIBXL_DOMAIN_TYPE_HVM:
> -        if (!libxl_get_stubdom_id(CTX, domid))
> -            dm_present = 1;
> -        else
> +        if (libxl_get_stubdom_id(CTX, domid)) {
>              dm_present = 0;
> -        break;
> +            break;
> +        }
> +        /* fall through */
>      case LIBXL_DOMAIN_TYPE_PV:
> -        pid = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/image/device-model-pid", domid));
> -        dm_present = (pid != NULL);
> +        dm_present = libxl__domain_has_device_model(gc, domid);
>          break;
>      case LIBXL_DOMAIN_TYPE_INVALID:
>          rc = ERROR_FAIL;
> @@ -3203,7 +3203,7 @@ out:
>  /******************************************************************************/
>  
>  int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
> -                                 uint32_t domid)
> +                                 uint32_t domid, libxl_domain_build_info *info)
>  {
>      int rc;
>  
> @@ -3240,8 +3240,15 @@ int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
>  
>      switch (libxl__domain_type(gc, domid)) {
>      case LIBXL_DOMAIN_TYPE_HVM:
> -        if (!nic->nictype)
> -            nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
> +        if (!nic->nictype) {
> +            if (info != NULL &&
> +                info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE)
> +                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
> +            else if (libxl__domain_has_device_model(gc, domid))
> +                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
> +            else
> +                nic->nictype = LIBXL_NIC_TYPE_VIF;

I think all you need is to pass in device model version and

   if version != none
       nictype = ioemu
   else
       nictype = vif

?

Otherwise the code suggests that there can be case you have specified a
device model when creating a domain but it somehow disappears when
domain is running?

Wei.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic
  2015-08-07 10:17 ` [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic Roger Pau Monne
@ 2015-08-07 14:09   ` Boris Ostrovsky
  2015-08-07 15:41     ` Roger Pau Monné
  2015-08-07 16:29   ` Andrew Cooper
  1 sibling, 1 reply; 84+ messages in thread
From: Boris Ostrovsky @ 2015-08-07 14:09 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Kevin Tian, Suravee Suthikulpanit, Andrew Cooper, Eddie Dong,
	Jan Beulich, Aravind Gopalakrishnan, Jun Nakajima

On 08/07/2015 06:17 AM, Roger Pau Monne wrote:
> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
> index a0a97e7..5acb246 100644
> --- a/xen/arch/x86/hvm/vmx/vmcs.c
> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
> @@ -1027,6 +1027,20 @@ static int construct_vmcs(struct vcpu *v)
>           ASSERT(!(v->arch.hvm_vmx.exec_control & CPU_BASED_RDTSC_EXITING));
>       }
>   
> +    if ( !has_vlapic(d) )
> +    {
> +        /* Disable virtual apics, TPR */
> +        v->arch.hvm_vmx.secondary_exec_control &=
> +            ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES
> +              | SECONDARY_EXEC_APIC_REGISTER_VIRT
> +              | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
> +        v->arch.hvm_vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
> +
> +        /* In turn, disable posted interrupts. */
> +        __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
> +                  vmx_pin_based_exec_control & ~PIN_BASED_POSTED_INTERRUPT);
> +    }
> +
>       vmx_update_cpu_exec_control(v);

This is the same code as the one used right above, in 'if ( 
is_pvh_domain(d) )' clause. Can you combine the two?

-boris

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model.
  2015-08-07 10:18 ` [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model Roger Pau Monne
  2015-08-07 12:58   ` Wei Liu
@ 2015-08-07 15:18   ` Konrad Rzeszutek Wilk
  2015-08-07 15:57     ` Roger Pau Monné
  1 sibling, 1 reply; 84+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-07 15:18 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Ian Campbell, Wei Liu, Ian Jackson, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:18:08PM +0200, Roger Pau Monne wrote:
> Replace the firmware loaded into HVM guests with an OS kernel. Since the HVM
> builder now uses the PV xc_dom_* set of functions this kernel will be parsed
> and loaded inside the guest like on PV, but the container is a pure HVM
> guest.

What is your plan in regards to the 'pvh' parameteR? Should it be
repurposed so you can use both?
> 
> Also, if device_model_version is set to none or a device model for the
> specified domain is not present unconditinally set the nic type to
> LIBXL_NIC_TYPE_VIF.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> ---
> Changes since v3:
>  - Add explicit /* fall through */ comments.
>  - Expand libxl__device_nic_setdefault so that it sets the right nic type
>    for HVMlite guests.
>  - Remove stray space in hvm_build_set_params.
>  - Fix the error paths of libxl__domain_firmware.
> ---
>  docs/man/xl.cfg.pod.5        |  5 ++++
>  tools/libxc/xc_dom_x86.c     |  7 +++++
>  tools/libxl/libxl.c          | 39 ++++++++++++++-----------
>  tools/libxl/libxl_create.c   | 16 ++++++++++-
>  tools/libxl/libxl_dm.c       | 13 ++++++++-
>  tools/libxl/libxl_dom.c      | 68 ++++++++++++++++++++++++++++++--------------
>  tools/libxl/libxl_internal.h |  5 +++-
>  tools/libxl/libxl_types.idl  |  1 +
>  tools/libxl/libxl_x86.c      |  4 ++-
>  tools/libxl/xl_cmdimpl.c     |  2 ++
>  10 files changed, 118 insertions(+), 42 deletions(-)
> 
> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
> index 80e51bb..8cd7726 100644
> --- a/docs/man/xl.cfg.pod.5
> +++ b/docs/man/xl.cfg.pod.5
> @@ -1741,6 +1741,11 @@ This device-model is the default for Linux dom0.
>  Use the device-model based upon the historical Xen fork of Qemu.
>  This device-model is still the default for NetBSD dom0.
>  
> +=item B<none>
> +
> +Don't use any device model. This requires a kernel capable of booting
> +in this mode.
> +
>  =back
>  
>  It is recommended to accept the default value for new guests.  If
> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> index 1599de4..d67feb0 100644
> --- a/tools/libxc/xc_dom_x86.c
> +++ b/tools/libxc/xc_dom_x86.c
> @@ -1269,6 +1269,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>      if ( nr_pages > target_pages )
>          memflags |= XENMEMF_populate_on_demand;
>  
> +    /* Make sure there's a MMIO hole for the special pages. */
> +    if ( dom->mmio_size == 0 )
> +    {
> +        dom->mmio_size = NR_SPECIAL_PAGES << PAGE_SHIFT;
> +        dom->mmio_start = special_pfn(0);
> +    }
> +
>      if ( dom->nr_vmemranges == 0 )
>      {
>          /* Build dummy vnode information
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index 083f099..a01868a 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -1033,11 +1033,13 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
>      }
>  
>      if (type == LIBXL_DOMAIN_TYPE_HVM) {
> -        rc = libxl__domain_resume_device_model(gc, domid);
> -        if (rc < 0) {
> -            LOG(ERROR, "failed to unpause device model for domain %u:%d",
> -                domid, rc);
> -            goto out;
> +        if (libxl__domain_has_device_model(gc, domid)) {
> +            rc = libxl__domain_resume_device_model(gc, domid);
> +            if (rc < 0) {
> +                LOG(ERROR, "failed to unpause device model for domain %u:%d",
> +                    domid, rc);
> +                goto out;
> +            }
>          }
>      }
>      ret = xc_domain_unpause(ctx->xch, domid);
> @@ -1567,7 +1569,6 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
>      libxl_ctx *ctx = CTX;
>      uint32_t domid = dis->domid;
>      char *dom_path;
> -    char *pid;
>      int rc, dm_present;
>  
>      libxl__ev_child_init(&dis->destroyer);
> @@ -1584,14 +1585,13 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
>  
>      switch (libxl__domain_type(gc, domid)) {
>      case LIBXL_DOMAIN_TYPE_HVM:
> -        if (!libxl_get_stubdom_id(CTX, domid))
> -            dm_present = 1;
> -        else
> +        if (libxl_get_stubdom_id(CTX, domid)) {
>              dm_present = 0;
> -        break;
> +            break;
> +        }
> +        /* fall through */
>      case LIBXL_DOMAIN_TYPE_PV:
> -        pid = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/image/device-model-pid", domid));
> -        dm_present = (pid != NULL);
> +        dm_present = libxl__domain_has_device_model(gc, domid);
>          break;
>      case LIBXL_DOMAIN_TYPE_INVALID:
>          rc = ERROR_FAIL;
> @@ -3203,7 +3203,7 @@ out:
>  /******************************************************************************/
>  
>  int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
> -                                 uint32_t domid)
> +                                 uint32_t domid, libxl_domain_build_info *info)
>  {
>      int rc;
>  
> @@ -3240,8 +3240,15 @@ int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
>  
>      switch (libxl__domain_type(gc, domid)) {
>      case LIBXL_DOMAIN_TYPE_HVM:
> -        if (!nic->nictype)
> -            nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
> +        if (!nic->nictype) {
> +            if (info != NULL &&
> +                info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE)
> +                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
> +            else if (libxl__domain_has_device_model(gc, domid))
> +                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
> +            else
> +                nic->nictype = LIBXL_NIC_TYPE_VIF;
> +        }
>          break;
>      case LIBXL_DOMAIN_TYPE_PV:
>          if (nic->nictype == LIBXL_NIC_TYPE_VIF_IOEMU) {
> @@ -3290,7 +3297,7 @@ void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
>      libxl_device_nic_init(&nic_saved);
>      libxl_device_nic_copy(CTX, &nic_saved, nic);
>  
> -    rc = libxl__device_nic_setdefault(gc, nic, domid);
> +    rc = libxl__device_nic_setdefault(gc, nic, domid, NULL);
>      if (rc) goto out;
>  
>      front = flexarray_make(gc, 16, 1);
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index 2348ffc..6738e34 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -119,6 +119,8 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
>                  b_info->u.hvm.bios = LIBXL_BIOS_TYPE_ROMBIOS; break;
>              case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
>                  b_info->u.hvm.bios = LIBXL_BIOS_TYPE_SEABIOS; break;
> +            case LIBXL_DEVICE_MODEL_VERSION_NONE:
> +                break;
>              default:return ERROR_INVAL;
>              }
>  
> @@ -132,6 +134,8 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
>              if (b_info->u.hvm.bios == LIBXL_BIOS_TYPE_ROMBIOS)
>                  return ERROR_INVAL;
>              break;
> +        case LIBXL_DEVICE_MODEL_VERSION_NONE:
> +            break;
>          default:abort();
>          }
>  
> @@ -236,6 +240,9 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
>                  break;
>              }
>              break;
> +        case LIBXL_DEVICE_MODEL_VERSION_NONE:
> +            b_info->video_memkb = 0;
> +            break;
>          case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
>          default:
>              switch (b_info->u.hvm.vga.kind) {
> @@ -923,7 +930,8 @@ static void initiate_domain_create(libxl__egc *egc,
>           * called libxl_device_nic_add when domcreate_launch_dm gets called,
>           * but qemu needs the nic information to be complete.
>           */
> -        ret = libxl__device_nic_setdefault(gc, &d_config->nics[i], domid);
> +        ret = libxl__device_nic_setdefault(gc, &d_config->nics[i], domid,
> +                                           &d_config->b_info);
>          if (ret) {
>              LOG(ERROR, "Unable to set nic defaults for nic %d", i);
>              goto error_out;
> @@ -1260,6 +1268,12 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
>          libxl__device_console_add(gc, domid, &console, state, &device);
>          libxl__device_console_dispose(&console);
>  
> +        if (d_config->b_info.device_model_version ==
> +            LIBXL_DEVICE_MODEL_VERSION_NONE) {
> +            domcreate_devmodel_started(egc, &dcs->dmss.dm, 0);
> +            return;
> +        }
> +
>          libxl_device_vkb_init(&vkb);
>          libxl__device_vkb_add(gc, domid, &vkb);
>          libxl_device_vkb_dispose(&vkb);
> diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
> index f6b4c89..7e71ce9 100644
> --- a/tools/libxl/libxl_dm.c
> +++ b/tools/libxl/libxl_dm.c
> @@ -1501,7 +1501,8 @@ static void spawn_stub_launch_dm(libxl__egc *egc,
>           * called libxl_device_nic_add at this point, but qemu needs
>           * the nic information to be complete.
>           */
> -        ret = libxl__device_nic_setdefault(gc, &dm_config->nics[i], dm_domid);
> +        ret = libxl__device_nic_setdefault(gc, &dm_config->nics[i], dm_domid,
> +                                           &dm_config->b_info);
>          if (ret)
>              goto out;
>      }
> @@ -1993,6 +1994,16 @@ out:
>      return rc;
>  }
>  
> +bool libxl__domain_has_device_model(libxl__gc *gc, uint32_t domid)
> +{
> +    char *pid;
> +
> +    pid = libxl__xs_read(gc, XBT_NULL,
> +          GCSPRINTF("/local/domain/%d/image/device-model-pid", domid));
> +
> +    return (pid != NULL);
> +}
> +
>  int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid)
>  {
>      char *path = libxl__device_model_xs_path(gc, LIBXL_TOOLSTACK_DOMID,
> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> index 8b8e079..a8a02ac 100644
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -781,21 +781,23 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
>      uint64_t str_mfn, cons_mfn;
>      int i;
>  
> -    va_map = xc_map_foreign_range(handle, domid,
> -                                  XC_PAGE_SIZE, PROT_READ | PROT_WRITE,
> -                                  HVM_INFO_PFN);
> -    if (va_map == NULL)
> -        return ERROR_FAIL;
> +    if (info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE) {
> +        va_map = xc_map_foreign_range(handle, domid,
> +                                      XC_PAGE_SIZE, PROT_READ | PROT_WRITE,
> +                                      HVM_INFO_PFN);
> +        if (va_map == NULL)
> +            return ERROR_FAIL;
>  
> -    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
> -    va_hvm->apic_mode = libxl_defbool_val(info->u.hvm.apic);
> -    va_hvm->nr_vcpus = info->max_vcpus;
> -    memset(va_hvm->vcpu_online, 0, sizeof(va_hvm->vcpu_online));
> -    memcpy(va_hvm->vcpu_online, info->avail_vcpus.map, info->avail_vcpus.size);
> -    for (i = 0, sum = 0; i < va_hvm->length; i++)
> -        sum += ((uint8_t *) va_hvm)[i];
> -    va_hvm->checksum -= sum;
> -    munmap(va_map, XC_PAGE_SIZE);
> +        va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
> +        va_hvm->apic_mode = libxl_defbool_val(info->u.hvm.apic);
> +        va_hvm->nr_vcpus = info->max_vcpus;
> +        memset(va_hvm->vcpu_online, 0, sizeof(va_hvm->vcpu_online));
> +        memcpy(va_hvm->vcpu_online, info->avail_vcpus.map, info->avail_vcpus.size);
> +        for (i = 0, sum = 0; i < va_hvm->length; i++)
> +            sum += ((uint8_t *) va_hvm)[i];
> +        va_hvm->checksum -= sum;
> +        munmap(va_map, XC_PAGE_SIZE);
> +    }
>  
>      xc_hvm_param_get(handle, domid, HVM_PARAM_STORE_PFN, &str_mfn);
>      xc_hvm_param_get(handle, domid, HVM_PARAM_CONSOLE_PFN, &cons_mfn);
> @@ -861,7 +863,7 @@ static int libxl__domain_firmware(libxl__gc *gc,
>  {
>      libxl_ctx *ctx = libxl__gc_owner(gc);
>      const char *firmware;
> -    int e, rc = ERROR_FAIL;
> +    int e, rc;
>      int datalen = 0;
>      void *data;
>  
> @@ -876,18 +878,34 @@ static int libxl__domain_firmware(libxl__gc *gc,
>          case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
>              firmware = "hvmloader";
>              break;
> +        case LIBXL_DEVICE_MODEL_VERSION_NONE:
> +            if (info->kernel == NULL) {
> +                LOG(ERROR, "no device model requested without a kernel");
> +                rc = ERROR_FAIL;
> +                goto out;
> +            }
> +            break;
>          default:
>              LOG(ERROR, "invalid device model version %d",
>                  info->device_model_version);
> -            return ERROR_FAIL;
> -            break;
> +            rc = ERROR_FAIL;
> +            goto out;
>          }
>      }
>  
> -    rc = xc_dom_kernel_file(dom, libxl__abs_path(gc, firmware,
> +    if (info->kernel != NULL &&
> +        info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_NONE) {
> +        /* Try to load a kernel instead of the firmware. */
> +        rc = xc_dom_kernel_file(dom, info->kernel);
> +        if (rc == 0 && info->ramdisk != NULL)
> +            rc = xc_dom_ramdisk_file(dom, info->ramdisk);
> +    } else {
> +        rc = xc_dom_kernel_file(dom, libxl__abs_path(gc, firmware,
>                                                   libxl__xenfirmwaredir_path()));
> +    }
> +
>      if (rc != 0) {
> -        LOGE(ERROR, "xc_dom_kernel_file failed");
> +        LOGE(ERROR, "xc_dom_{kernel_file/ramdisk_file} failed");
>          goto out;
>      }
>  
> @@ -898,6 +916,7 @@ static int libxl__domain_firmware(libxl__gc *gc,
>          if (e) {
>              LOGEV(ERROR, e, "failed to read SMBIOS firmware file %s",
>                  info->u.hvm.smbios_firmware);
> +            rc = ERROR_FAIL;
>              goto out;
>          }
>          libxl__ptr_add(gc, data);
> @@ -915,6 +934,7 @@ static int libxl__domain_firmware(libxl__gc *gc,
>          if (e) {
>              LOGEV(ERROR, e, "failed to read ACPI firmware file %s",
>                  info->u.hvm.acpi_firmware);
> +            rc = ERROR_FAIL;
>              goto out;
>          }
>          libxl__ptr_add(gc, data);
> @@ -927,6 +947,7 @@ static int libxl__domain_firmware(libxl__gc *gc,
>  
>      return 0;
>  out:
> +    assert(rc != 0);
>      return rc;
>  }
>  
> @@ -939,10 +960,13 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
>      uint64_t mmio_start, lowmem_end, highmem_end, mem_size;
>      libxl_domain_build_info *const info = &d_config->b_info;
>      struct xc_dom_image *dom = NULL;
> +    bool emulated_devices =
> +        info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE ?
> +        true : false;
>  
>      xc_dom_loginit(ctx->xch);
>  
> -    dom = xc_dom_allocate(ctx->xch, NULL, NULL);
> +    dom = xc_dom_allocate(ctx->xch, info->cmdline, NULL);
>      if (!dom) {
>          LOGE(ERROR, "xc_dom_allocate failed");
>          goto out;
> @@ -974,7 +998,7 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
>  
>      if (dom->target_pages == 0)
>          dom->target_pages = mem_size >> XC_PAGE_SHIFT;
> -    if (dom->mmio_size == 0)
> +    if (dom->mmio_size == 0 && emulated_devices)
>          dom->mmio_size = HVM_BELOW_4G_MMIO_LENGTH;
>      lowmem_end = mem_size;
>      highmem_end = 0;
> @@ -987,7 +1011,7 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
>      dom->lowmem_end = lowmem_end;
>      dom->highmem_end = highmem_end;
>      dom->mmio_start = mmio_start;
> -    dom->emulation = true;
> +    dom->emulation = emulated_devices;
>  
>      rc = libxl__domain_device_construct_rdm(gc, d_config,
>                                              info->u.hvm.rdm_mem_boundary_memkb*1024,
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index ea89f1f..ee8d03d 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -1172,7 +1172,8 @@ _hidden int libxl__domain_build_info_setdefault(libxl__gc *gc,
>  _hidden int libxl__device_disk_setdefault(libxl__gc *gc,
>                                            libxl_device_disk *disk);
>  _hidden int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
> -                                         uint32_t domid);
> +                                         uint32_t domid,
> +                                         libxl_domain_build_info *info);
>  _hidden int libxl__device_vtpm_setdefault(libxl__gc *gc, libxl_device_vtpm *vtpm);
>  _hidden int libxl__device_vfb_setdefault(libxl__gc *gc, libxl_device_vfb *vfb);
>  _hidden int libxl__device_vkb_setdefault(libxl__gc *gc, libxl_device_vkb *vkb);
> @@ -1617,6 +1618,8 @@ _hidden int libxl__wait_for_device_model_deprecated(libxl__gc *gc,
>  
>  _hidden int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid);
>  
> +_hidden bool libxl__domain_has_device_model(libxl__gc *gc, uint32_t domid);
> +
>  _hidden const libxl_vnc_info *libxl__dm_vnc(const libxl_domain_config *g_cfg);
>  
>  _hidden char *libxl__abs_path(libxl__gc *gc, const char *s, const char *path);
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index ef346e7..b6e99c4 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -98,6 +98,7 @@ libxl_device_model_version = Enumeration("device_model_version", [
>      (0, "UNKNOWN"),
>      (1, "QEMU_XEN_TRADITIONAL"), # Historical qemu-xen device model (qemu-dm)
>      (2, "QEMU_XEN"),             # Upstream based qemu-xen device model
> +    (3, "NONE"),                 # No device model
>      ])
>  
>  libxl_console_type = Enumeration("console_type", [
> diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
> index 270f3cf..21424a5 100644
> --- a/tools/libxl/libxl_x86.c
> +++ b/tools/libxl/libxl_x86.c
> @@ -7,7 +7,9 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
>                                        libxl_domain_config *d_config,
>                                        xc_domain_configuration_t *xc_config)
>  {
> -    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM)
> +    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM &&
> +        d_config->b_info.device_model_version !=
> +        LIBXL_DEVICE_MODEL_VERSION_NONE)
>          xc_config->emulation_flags = (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET |
>                                        XEN_X86_EMU_PMTIMER | XEN_X86_EMU_RTC |
>                                        XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC |
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> index 499a05c..2776318 100644
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -2148,6 +2148,8 @@ skip_vfb:
>          } else if (!strcmp(buf, "qemu-xen")) {
>              b_info->device_model_version
>                  = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN;
> +        } else if (!strcmp(buf, "none")) {
> +            b_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_NONE;
>          } else {
>              fprintf(stderr,
>                      "Unknown device_model_version \"%s\" specified\n", buf);
> -- 
> 1.9.5 (Apple Git-50.3)
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 08/31] libxc: rework BSP initialization
  2015-08-07 10:17 ` [PATCH v4 08/31] libxc: rework BSP initialization Roger Pau Monne
  2015-08-07 11:31   ` Wei Liu
@ 2015-08-07 15:22   ` Andrew Cooper
  1 sibling, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 15:22 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Ian Jackson, Wei Liu, Ian Campbell, Stefano Stabellini

On 07/08/15 11:17, Roger Pau Monne wrote:
> Place the calls to xc_vcpu_setcontext and the allocation of the hypercall
> buffer into the arch-specific vcpu hooks. This is needed for the next patch,
> so x86 HVM guests can initialize the BSP using XEN_DOMCTL_sethvmcontext
> instead of XEN_DOMCTL_setvcpucontext.
>
> This patch should not introduce any functional change.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 08/31] libxc: rework BSP initialization
  2015-08-07 12:06       ` Wei Liu
@ 2015-08-07 15:30         ` Andrew Cooper
  0 siblings, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 15:30 UTC (permalink / raw)
  To: Wei Liu, Roger Pau Monné
  Cc: xen-devel, Ian Jackson, Ian Campbell, Stefano Stabellini

On 07/08/15 13:06, Wei Liu wrote:
>
>>>> -    ctxt = xc_hypercall_buffer_alloc(dom->xch, ctxt, sizeof(*ctxt));
>>>> -    if ( ctxt == NULL )
>>>> -        return -1;
>>>> -
>>>>      DOMPRINTF_CALLED(dom->xch);
>>>>  
>>>>      /* misc stuff*/
>>>> @@ -259,13 +241,10 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
>>>>          return rc;
>>>>  
>>>>      /* let the vm run */
>>>> -    memset(ctxt, 0, sizeof(*ctxt));
>>>> -    if ( (rc = dom->arch_hooks->vcpu(dom, ctxt)) != 0 )
>>>> +    if ( (rc = dom->arch_hooks->vcpu(dom)) != 0 )
>>>>          return rc;
>>>>      xc_dom_unmap_all(dom);
>>> This is not your problem, but this xc_dom_unmap_all is really
>>> suspicious.
>> I agree, xc_dom_release already calls xc_dom_unmap_all. I guess it's not
>> a big issue since xc_dom_boot_image is almost the last function called
>> when doing domain creation, but I'm also not that familiar with libxc in
>> order to figure out if there's a reason for calling xc_dom_unmap_all here.
>>
> Yeah, let's worry about that later.

:)  Make absolutely no assumptions about the correctness of the existing
code.

I got lead down several rabbit holes with migration v2 (one hole going
back to 2002 and the bitkeeper source history).

~Andrew

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic
  2015-08-07 14:09   ` Boris Ostrovsky
@ 2015-08-07 15:41     ` Roger Pau Monné
  2015-08-07 16:11       ` Boris Ostrovsky
  0 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-07 15:41 UTC (permalink / raw)
  To: Boris Ostrovsky, xen-devel
  Cc: Kevin Tian, Suravee Suthikulpanit, Andrew Cooper, Eddie Dong,
	Jan Beulich, Aravind Gopalakrishnan, Jun Nakajima

El 07/08/15 a les 16.09, Boris Ostrovsky ha escrit:
> On 08/07/2015 06:17 AM, Roger Pau Monne wrote:
>> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
>> index a0a97e7..5acb246 100644
>> --- a/xen/arch/x86/hvm/vmx/vmcs.c
>> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
>> @@ -1027,6 +1027,20 @@ static int construct_vmcs(struct vcpu *v)
>>           ASSERT(!(v->arch.hvm_vmx.exec_control &
>> CPU_BASED_RDTSC_EXITING));
>>       }
>>   +    if ( !has_vlapic(d) )
>> +    {
>> +        /* Disable virtual apics, TPR */
>> +        v->arch.hvm_vmx.secondary_exec_control &=
>> +            ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES
>> +              | SECONDARY_EXEC_APIC_REGISTER_VIRT
>> +              | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
>> +        v->arch.hvm_vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
>> +
>> +        /* In turn, disable posted interrupts. */
>> +        __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
>> +                  vmx_pin_based_exec_control &
>> ~PIN_BASED_POSTED_INTERRUPT);
>> +    }
>> +
>>       vmx_update_cpu_exec_control(v);
> 
> This is the same code as the one used right above, in 'if (
> is_pvh_domain(d) )' clause. Can you combine the two?

No, it's not the same code. The PVH code disables unrestricted guest and
sets the entry of the VM to be in long mode, which is not true for HVMlite.

Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 25/31] xen: allow HVM guests to use XENMEM_memory_map
  2015-08-07 12:22   ` Wei Liu
@ 2015-08-07 15:44     ` Roger Pau Monné
  2015-08-07 15:55       ` Wei Liu
  0 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-07 15:44 UTC (permalink / raw)
  To: Wei Liu
  Cc: Ian Campbell, Stefano Stabellini, Andrew Cooper, Ian Jackson,
	Jan Beulich, xen-devel

El 07/08/15 a les 14.22, Wei Liu ha escrit:
> On Fri, Aug 07, 2015 at 12:18:02PM +0200, Roger Pau Monne wrote:
>> Enable this hypercall for HVM guests in order to fetch the e820 memory
>> map in the absence of an emulated BIOS. The memory map is populated and
>> notified to Xen in arch_setup_meminit_hvm.
>>
>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>> Cc: Ian Campbell <ian.campbell@citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>> Cc: Jan Beulich <jbeulich@suse.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>>  tools/libxc/xc_dom_x86.c | 29 ++++++++++++++++++++++++++++-
>>  1 file changed, 28 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
>> index b587b12..87bce6e 100644
>> --- a/tools/libxc/xc_dom_x86.c
>> +++ b/tools/libxc/xc_dom_x86.c
>> @@ -1205,6 +1205,7 @@ static int check_mmio_hole(uint64_t start, uint64_t memsize,
>>          return 1;
>>  }
>>  
>> +#define MAX_E820_ENTRIES    128
>>  static int meminit_hvm(struct xc_dom_image *dom)
>>  {
>>      unsigned long i, vmemid, nr_pages = dom->total_pages;
>> @@ -1225,6 +1226,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>      unsigned int nr_vmemranges, nr_vnodes;
>>      xc_interface *xch = dom->xch;
>>      uint32_t domid = dom->guest_domid;
>> +    struct e820entry entries[MAX_E820_ENTRIES];
>> +    int e820_index = 0;
>>  
>>      if ( nr_pages > target_pages )
>>          memflags |= XENMEMF_populate_on_demand;
>> @@ -1275,6 +1278,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>          vnode_to_pnode = dom->vnode_to_pnode;
>>      }
>>  
>> +    /* Add one additional memory range to account for the VGA hole */
>> +    if ( (nr_vmemranges + (dom->emulation ? 1 : 0)) > MAX_E820_ENTRIES )
>> +    {
>> +        DOMPRINTF("Too many memory ranges");
>> +        goto error_out;
>> +    }
>> +
>>      total_pages = 0;
>>      p2m_size = 0;
>>      for ( i = 0; i < nr_vmemranges; i++ )
>> @@ -1363,9 +1373,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>       * Under 2MB mode, we allocate pages in batches of no more than 8MB to 
>>       * ensure that we can be preempted and hence dom0 remains responsive.
>>       */
>> -    if ( dom->emulation )
>> +    if ( dom->emulation ) {
>>          rc = xc_domain_populate_physmap_exact(
>>              xch, domid, 0xa0, 0, memflags, &dom->p2m_host[0x00]);
>> +        entries[e820_index].addr = 0;
>> +        entries[e820_index].size = 0xa0 << PAGE_SHIFT;
>> +        entries[e820_index++].type = E820_RAM;
>> +    }
>>  
>>      stat_normal_pages = 0;
>>      for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
>> @@ -1392,6 +1406,12 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>          else
>>              cur_pages = vmemranges[vmemid].start >> PAGE_SHIFT;
>>  
>> +        /* Build an e820 map. */
>> +        entries[e820_index].addr = cur_pages << PAGE_SHIFT;
>> +        entries[e820_index].size = vmemranges[vmemid].end -
>> +                                   entries[e820_index].addr;
>> +        entries[e820_index++].type = E820_RAM;
>> +
>>          while ( (rc == 0) && (end_pages > cur_pages) )
>>          {
>>              /* Clip count to maximum 1GB extent. */
>> @@ -1509,6 +1529,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>      DPRINTF("  2MB PAGES: 0x%016lx\n", stat_2mb_pages);
>>      DPRINTF("  1GB PAGES: 0x%016lx\n", stat_1gb_pages);
>>  
>> +    rc = xc_domain_set_memory_map(xch, domid, entries, e820_index);
>> +    if ( rc != 0 )
>> +    {
>> +        DOMPRINTF("unable to set memory map.");
>> +        goto error_out;
>> +    }
>> +
> 
> I think in RDM series there is already a memory map generated in libxl.
> 
> You might want to move this to libxl, which is supposed to be the
> arbitrator of what a guest should look like.
> 
> What do you think?

I would like to do that, the only problem I see is that libxl doesn't
have any notion of the "special pages", so it doesn't know the size of
the hole it has to made. I guess one solution would be moving the
defines at the top of xc_dom_x86.c to a public libxc header so libxl can
pick up the size and position of the hole.

Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model.
  2015-08-07 12:58   ` Wei Liu
@ 2015-08-07 15:51     ` Roger Pau Monné
  2015-08-07 16:24       ` Wei Liu
  0 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-07 15:51 UTC (permalink / raw)
  To: Wei Liu; +Cc: xen-devel, Ian Jackson, Ian Campbell, Stefano Stabellini

El 07/08/15 a les 14.58, Wei Liu ha escrit:
> On Fri, Aug 07, 2015 at 12:18:08PM +0200, Roger Pau Monne wrote:
>> Replace the firmware loaded into HVM guests with an OS kernel. Since the HVM
>> builder now uses the PV xc_dom_* set of functions this kernel will be parsed
>> and loaded inside the guest like on PV, but the container is a pure HVM
>> guest.
>>
>> Also, if device_model_version is set to none or a device model for the
>> specified domain is not present unconditinally set the nic type to
>> LIBXL_NIC_TYPE_VIF.
>>
>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>> Cc: Ian Campbell <ian.campbell@citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>> ---
>> Changes since v3:
>>  - Add explicit /* fall through */ comments.
>>  - Expand libxl__device_nic_setdefault so that it sets the right nic type
>>    for HVMlite guests.
>>  - Remove stray space in hvm_build_set_params.
>>  - Fix the error paths of libxl__domain_firmware.
>> ---
>>  docs/man/xl.cfg.pod.5        |  5 ++++
>>  tools/libxc/xc_dom_x86.c     |  7 +++++
>>  tools/libxl/libxl.c          | 39 ++++++++++++++-----------
>>  tools/libxl/libxl_create.c   | 16 ++++++++++-
>>  tools/libxl/libxl_dm.c       | 13 ++++++++-
>>  tools/libxl/libxl_dom.c      | 68 ++++++++++++++++++++++++++++++--------------
>>  tools/libxl/libxl_internal.h |  5 +++-
>>  tools/libxl/libxl_types.idl  |  1 +
>>  tools/libxl/libxl_x86.c      |  4 ++-
>>  tools/libxl/xl_cmdimpl.c     |  2 ++
>>  10 files changed, 118 insertions(+), 42 deletions(-)
>>
>> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
>> index 80e51bb..8cd7726 100644
>> --- a/docs/man/xl.cfg.pod.5
>> +++ b/docs/man/xl.cfg.pod.5
>> @@ -1741,6 +1741,11 @@ This device-model is the default for Linux dom0.
>>  Use the device-model based upon the historical Xen fork of Qemu.
>>  This device-model is still the default for NetBSD dom0.
>>  
>> +=item B<none>
>> +
>> +Don't use any device model. This requires a kernel capable of booting
>> +in this mode.
> 
> booting without emulated devices?

Yes, that's more clear.

>> +
>>  =back
>>  
>>  It is recommended to accept the default value for new guests.  If
>> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
>> index 1599de4..d67feb0 100644
>> --- a/tools/libxc/xc_dom_x86.c
>> +++ b/tools/libxc/xc_dom_x86.c
>> @@ -1269,6 +1269,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>      if ( nr_pages > target_pages )
>>          memflags |= XENMEMF_populate_on_demand;
>>  
>> +    /* Make sure there's a MMIO hole for the special pages. */
>> +    if ( dom->mmio_size == 0 )
>> +    {
>> +        dom->mmio_size = NR_SPECIAL_PAGES << PAGE_SHIFT;
>> +        dom->mmio_start = special_pfn(0);
>> +    }
>> +
> 
> Better to just assert(dom->mmio_size != 0);
> 
> It's really libxl's responsibility to generate memory layout for guest.
> Libxc doesn't have all information to make the decision.

As said in a previous email, libxl doesn't know the size or position of
the special pages created by libxc code, so right now it's impossible
for libxl to create a correct mmio hole for a HVMlite guest.

> 
>>      if ( dom->nr_vmemranges == 0 )
>>      {
>>          /* Build dummy vnode information
>> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
>> index 083f099..a01868a 100644
>> --- a/tools/libxl/libxl.c
>> +++ b/tools/libxl/libxl.c
>> @@ -1033,11 +1033,13 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
>>      }
>>  
>>      if (type == LIBXL_DOMAIN_TYPE_HVM) {
>> -        rc = libxl__domain_resume_device_model(gc, domid);
>> -        if (rc < 0) {
>> -            LOG(ERROR, "failed to unpause device model for domain %u:%d",
>> -                domid, rc);
>> -            goto out;
>> +        if (libxl__domain_has_device_model(gc, domid)) {
> 
> Checking for device model version is not enough?

Sadly we don't have access to the device model version here, and it is
not stored anywhere, so the only option I see is to actually check if
there's a device model running or not in order to figure out if we have
to unpause it.

>> +            rc = libxl__domain_resume_device_model(gc, domid);
>> +            if (rc < 0) {
>> +                LOG(ERROR, "failed to unpause device model for domain %u:%d",
>> +                    domid, rc);
>> +                goto out;
>> +            }
>>          }
>>      }
>>      ret = xc_domain_unpause(ctx->xch, domid);
>> @@ -1567,7 +1569,6 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
>>      libxl_ctx *ctx = CTX;
>>      uint32_t domid = dis->domid;
>>      char *dom_path;
>> -    char *pid;
>>      int rc, dm_present;
>>  
>>      libxl__ev_child_init(&dis->destroyer);
>> @@ -1584,14 +1585,13 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
>>  
>>      switch (libxl__domain_type(gc, domid)) {
>>      case LIBXL_DOMAIN_TYPE_HVM:
>> -        if (!libxl_get_stubdom_id(CTX, domid))
>> -            dm_present = 1;
>> -        else
>> +        if (libxl_get_stubdom_id(CTX, domid)) {
>>              dm_present = 0;
>> -        break;
>> +            break;
>> +        }
>> +        /* fall through */
>>      case LIBXL_DOMAIN_TYPE_PV:
>> -        pid = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/image/device-model-pid", domid));
>> -        dm_present = (pid != NULL);
>> +        dm_present = libxl__domain_has_device_model(gc, domid);
>>          break;
>>      case LIBXL_DOMAIN_TYPE_INVALID:
>>          rc = ERROR_FAIL;
>> @@ -3203,7 +3203,7 @@ out:
>>  /******************************************************************************/
>>  
>>  int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
>> -                                 uint32_t domid)
>> +                                 uint32_t domid, libxl_domain_build_info *info)
>>  {
>>      int rc;
>>  
>> @@ -3240,8 +3240,15 @@ int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
>>  
>>      switch (libxl__domain_type(gc, domid)) {
>>      case LIBXL_DOMAIN_TYPE_HVM:
>> -        if (!nic->nictype)
>> -            nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
>> +        if (!nic->nictype) {
>> +            if (info != NULL &&
>> +                info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE)
>> +                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
>> +            else if (libxl__domain_has_device_model(gc, domid))
>> +                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
>> +            else
>> +                nic->nictype = LIBXL_NIC_TYPE_VIF;
> 
> I think all you need is to pass in device model version and
> 
>    if version != none
>        nictype = ioemu
>    else
>        nictype = vif
> 
> ?
> 
> Otherwise the code suggests that there can be case you have specified a
> device model when creating a domain but it somehow disappears when
> domain is running?

That's exactly the case. During domain creation we know if there's a
device model or not. But if we are doing a hot-attach of a nic this
information is not available, so the only solution I see is to actually
check for the device model presence.

Thanks for the review, Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 25/31] xen: allow HVM guests to use XENMEM_memory_map
  2015-08-07 15:44     ` Roger Pau Monné
@ 2015-08-07 15:55       ` Wei Liu
  2015-08-07 16:00         ` Roger Pau Monné
  0 siblings, 1 reply; 84+ messages in thread
From: Wei Liu @ 2015-08-07 15:55 UTC (permalink / raw)
  To: Roger Pau Monné
  Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
	Ian Jackson, Jan Beulich, xen-devel

On Fri, Aug 07, 2015 at 05:44:22PM +0200, Roger Pau Monné wrote:
> El 07/08/15 a les 14.22, Wei Liu ha escrit:
> > On Fri, Aug 07, 2015 at 12:18:02PM +0200, Roger Pau Monne wrote:
> >> Enable this hypercall for HVM guests in order to fetch the e820 memory
> >> map in the absence of an emulated BIOS. The memory map is populated and
> >> notified to Xen in arch_setup_meminit_hvm.
> >>
> >> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> >> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> >> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> >> Cc: Ian Campbell <ian.campbell@citrix.com>
> >> Cc: Wei Liu <wei.liu2@citrix.com>
> >> Cc: Jan Beulich <jbeulich@suse.com>
> >> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> >> ---
> >>  tools/libxc/xc_dom_x86.c | 29 ++++++++++++++++++++++++++++-
> >>  1 file changed, 28 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> >> index b587b12..87bce6e 100644
> >> --- a/tools/libxc/xc_dom_x86.c
> >> +++ b/tools/libxc/xc_dom_x86.c
> >> @@ -1205,6 +1205,7 @@ static int check_mmio_hole(uint64_t start, uint64_t memsize,
> >>          return 1;
> >>  }
> >>  
> >> +#define MAX_E820_ENTRIES    128
> >>  static int meminit_hvm(struct xc_dom_image *dom)
> >>  {
> >>      unsigned long i, vmemid, nr_pages = dom->total_pages;
> >> @@ -1225,6 +1226,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
> >>      unsigned int nr_vmemranges, nr_vnodes;
> >>      xc_interface *xch = dom->xch;
> >>      uint32_t domid = dom->guest_domid;
> >> +    struct e820entry entries[MAX_E820_ENTRIES];
> >> +    int e820_index = 0;
> >>  
> >>      if ( nr_pages > target_pages )
> >>          memflags |= XENMEMF_populate_on_demand;
> >> @@ -1275,6 +1278,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
> >>          vnode_to_pnode = dom->vnode_to_pnode;
> >>      }
> >>  
> >> +    /* Add one additional memory range to account for the VGA hole */
> >> +    if ( (nr_vmemranges + (dom->emulation ? 1 : 0)) > MAX_E820_ENTRIES )
> >> +    {
> >> +        DOMPRINTF("Too many memory ranges");
> >> +        goto error_out;
> >> +    }
> >> +
> >>      total_pages = 0;
> >>      p2m_size = 0;
> >>      for ( i = 0; i < nr_vmemranges; i++ )
> >> @@ -1363,9 +1373,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
> >>       * Under 2MB mode, we allocate pages in batches of no more than 8MB to 
> >>       * ensure that we can be preempted and hence dom0 remains responsive.
> >>       */
> >> -    if ( dom->emulation )
> >> +    if ( dom->emulation ) {
> >>          rc = xc_domain_populate_physmap_exact(
> >>              xch, domid, 0xa0, 0, memflags, &dom->p2m_host[0x00]);
> >> +        entries[e820_index].addr = 0;
> >> +        entries[e820_index].size = 0xa0 << PAGE_SHIFT;
> >> +        entries[e820_index++].type = E820_RAM;
> >> +    }
> >>  
> >>      stat_normal_pages = 0;
> >>      for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
> >> @@ -1392,6 +1406,12 @@ static int meminit_hvm(struct xc_dom_image *dom)
> >>          else
> >>              cur_pages = vmemranges[vmemid].start >> PAGE_SHIFT;
> >>  
> >> +        /* Build an e820 map. */
> >> +        entries[e820_index].addr = cur_pages << PAGE_SHIFT;
> >> +        entries[e820_index].size = vmemranges[vmemid].end -
> >> +                                   entries[e820_index].addr;
> >> +        entries[e820_index++].type = E820_RAM;
> >> +
> >>          while ( (rc == 0) && (end_pages > cur_pages) )
> >>          {
> >>              /* Clip count to maximum 1GB extent. */
> >> @@ -1509,6 +1529,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
> >>      DPRINTF("  2MB PAGES: 0x%016lx\n", stat_2mb_pages);
> >>      DPRINTF("  1GB PAGES: 0x%016lx\n", stat_1gb_pages);
> >>  
> >> +    rc = xc_domain_set_memory_map(xch, domid, entries, e820_index);
> >> +    if ( rc != 0 )
> >> +    {
> >> +        DOMPRINTF("unable to set memory map.");
> >> +        goto error_out;
> >> +    }
> >> +
> > 
> > I think in RDM series there is already a memory map generated in libxl.
> > 
> > You might want to move this to libxl, which is supposed to be the
> > arbitrator of what a guest should look like.
> > 
> > What do you think?
> 
> I would like to do that, the only problem I see is that libxl doesn't
> have any notion of the "special pages", so it doesn't know the size of
> the hole it has to made. I guess one solution would be moving the
> defines at the top of xc_dom_x86.c to a public libxc header so libxl can
> pick up the size and position of the hole.

But the code above has no notion of special pages either. Can it not
just use the E820 map generated in libxl? I think at the time you wrote
this patch libxl doesn't generate E820 for HVM guest, but it does now,
so maybe you can drop this patch?

BTW the title is not very accurate because this patch doesn't involve
allowing / disallowing hvm to use that hypercall.

Wei.

> 
> Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model.
  2015-08-07 15:18   ` Konrad Rzeszutek Wilk
@ 2015-08-07 15:57     ` Roger Pau Monné
  2015-08-07 17:52       ` Andrew Cooper
  0 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-07 15:57 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: xen-devel, Ian Campbell, Wei Liu, Ian Jackson, Stefano Stabellini

El 07/08/15 a les 17.18, Konrad Rzeszutek Wilk ha escrit:
> On Fri, Aug 07, 2015 at 12:18:08PM +0200, Roger Pau Monne wrote:
>> Replace the firmware loaded into HVM guests with an OS kernel. Since the HVM
>> builder now uses the PV xc_dom_* set of functions this kernel will be parsed
>> and loaded inside the guest like on PV, but the container is a pure HVM
>> guest.
> 
> What is your plan in regards to the 'pvh' parameteR? Should it be
> repurposed so you can use both?

I haven't thought about this TBH.

One option could be to make the pvh parameter an alias to builder='hvm'
device_model_version='none' with a forced 64bit entry point, but since
PVH has never made it out of the experimental state I'm not sure if it's
worth to keep it.

Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 09/31] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests
  2015-08-07 10:17 ` [PATCH v4 09/31] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests Roger Pau Monne
  2015-08-07 12:00   ` Wei Liu
@ 2015-08-07 15:58   ` Andrew Cooper
  1 sibling, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 15:58 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Ian Jackson, Wei Liu, Ian Campbell, Stefano Stabellini

On 07/08/15 11:17, Roger Pau Monne wrote:
> +static void build_hvm_info(void *hvm_info_page, struct xc_dom_image *dom)
> +{
> +    struct hvm_info_table *hvm_info = (struct hvm_info_table *)
> +        (((unsigned char *)hvm_info_page) + HVM_INFO_OFFSET);
> +    uint8_t sum;
> +    int i;
> +
> +    memset(hvm_info_page, 0, PAGE_SIZE);
> +
> +    /* Fill in the header. */
> +    memcpy(hvm_info->signature, "HVM INFO", sizeof(hvm_info->signature));
> +    hvm_info->length = sizeof(struct hvm_info_table);
> +
> +    /* Sensible defaults: these can be overridden by the caller. */
> +    hvm_info->apic_mode = 1;
> +    hvm_info->nr_vcpus = 1;
> +    memset(hvm_info->vcpu_online, 0xff, sizeof(hvm_info->vcpu_online));

I realise you are just copying existing code, so won't hold this against
you, but these are not sensible defaults.

There is a lot of cleanup which should be done, but this particular
series is not the place for it.

>  static int start_info_x86_32(struct xc_dom_image *dom)
> @@ -682,6 +833,103 @@ static int vcpu_x86_64(struct xc_dom_image *dom)
>      return rc;
>  }
>  
> +static int vcpu_hvm(struct xc_dom_image *dom)
> +{
> +    struct {
> +        struct hvm_save_descriptor header_d;
> +        HVM_SAVE_TYPE(HEADER) header;
> +        struct hvm_save_descriptor cpu_d;
> +        HVM_SAVE_TYPE(CPU) cpu;
> +        struct hvm_save_descriptor end_d;
> +        HVM_SAVE_TYPE(END) end;
> +    } bsp_ctx;
> +    uint8_t *full_ctx = NULL;
> +    int rc;
> +
> +    DOMPRINTF_CALLED(dom->xch);
> +
> +    /*
> +     * Get the full HVM context in order to have the header, it is not
> +     * possible to get the header with getcontext_partial, and crafting one
> +     * from userspace is also not an option since cpuid is trapped and
> +     * modified by Xen.
> +     */

Eww.  Again, not your fault so this patch is ok, but we should see about
making things like this easier to do.

I have a cunning plan as part of some longterm improvements to migration
which might come in handy.

> +
> +    rc = xc_domain_hvm_getcontext(dom->xch, dom->guest_domid, NULL, 0);
> +    if ( rc <= 0 )
> +    {
> +        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
> +                     "%s: unable to fetch HVM context size (rc=%d)",
> +                     __func__, rc);
> +        return rc;
> +    }
> +    full_ctx = malloc(rc);
> +    if ( full_ctx == NULL )
> +    {
> +        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
> +                     "%s: unable to allocate memory for HVM context (rc=%d)",
> +                     __func__, rc);
> +        return -ENOMEM;
> +    }
> +
> +    memset(full_ctx, 0, rc);

calloc() instead of malloc().

> +
> +    rc = xc_domain_hvm_getcontext(dom->xch, dom->guest_domid, full_ctx, rc);
> +    if ( rc <= 0 )
> +    {
> +        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
> +                     "%s: unable to fetch HVM context (rc=%d)",
> +                     __func__, rc);
> +        goto out;
> +    }
> +
> +    /* Copy the header to our partial context. */
> +    memset(&bsp_ctx, 0, sizeof(bsp_ctx));
> +    memcpy(&bsp_ctx, full_ctx,
> +           siz
>
>
>
>> +    return rc;
>> +}
>> +
>>  /* ------------------------------------------------------------------------ */
>>  
>>  static int x86_compat(xc_interface *xch, domid_t domid, char *guest_type)
>> @@ -762,7 +1010,7 @@ static int meminit_pv(struct xc_dom_image *dom)
>>  
>>      if ( dom->superpages )
>>      {
>> -        int count = dom->total_pages >> SUPERPAGE_PFN_SHIFT;
>> +        int count = dom->total_pages >> SUPERPAGE_2MB_SHIFT;
>>          xen_pfn_t extents[count];
>>  
>>          dom->p2m_size = dom->total_pages;
>> @@ -773,9 +1021,9 @@ static int meminit_pv(struct xc_dom_image *dom)
>>  
>>          DOMPRINTF("Populating memory with %d superpages", count);
>>          for ( pfn = 0; pfn < count; pfn++ )
>> -            extents[pfn] = pfn << SUPERPAGE_PFN_SHIFT;
>> +            extents[pfn] = pfn << SUPERPAGE_2MB_SHIFT;
>>          rc = xc_domain_populate_physmap_exact(dom->xch, dom->guest_domid,
>> -                                               count, SUPERPAGE_PFN_SHIFT, 0,
>> +                                               count, SUPERPAGE_2MB_SHIFT, 0,
>>                                                 extents);
>>          if ( rc )
>>              return rc;
>> @@ -785,7 +1033,7 @@ static int meminit_pv(struct xc_dom_image *dom)
>>          for ( i = 0; i < count; i++ )
>>          {
>>              mfn = extents[i];
>> -            for ( j = 0; j < SUPERPAGE_NR_PFNS; j++, pfn++ )
>> +            for ( j = 0; j < SUPERPAGE_2MB_NR_PFNS; j++, pfn++ )
>>                  dom->p2m_host[pfn] = mfn + j;
>>          }
>>      }
>> @@ -870,7 +1118,7 @@ static int meminit_pv(struct xc_dom_image *dom)
>>  
>>              pages = (vmemranges[i].end - vmemranges[i].start)
>>                  >> PAGE_SHIFT;
>> -            super_pages = pages >> SUPERPAGE_PFN_SHIFT;
>> +            super_pages = pages >> SUPERPAGE_2MB_SHIFT;
>>              pfn_base = vmemranges[i].start >> PAGE_SHIFT;
>>  
>>              for ( pfn = pfn_base; pfn < pfn_base+pages; pfn++ )
>> @@ -883,11 +1131,11 @@ static int meminit_pv(struct xc_dom_image *dom)
>>                  super_pages -= count;
>>  
>>                  for ( pfn = pfn_base_idx, j = 0;
>> -                      pfn < pfn_base_idx + (count << SUPERPAGE_PFN_SHIFT);
>> -                      pfn += SUPERPAGE_NR_PFNS, j++ )
>> +                      pfn < pfn_base_idx + (count << SUPERPAGE_2MB_SHIFT);
>> +                      pfn += SUPERPAGE_2MB_NR_PFNS, j++ )
>>                      extents[j] = dom->p2m_host[pfn];
>>                  rc = xc_domain_populate_physmap(dom->xch, dom->guest_domid, count,
>> -                                                SUPERPAGE_PFN_SHIFT, memflags,
>> +                                                SUPERPAGE_2MB_SHIFT, memflags,
>>                                                  extents);
>>                  if ( rc < 0 )
>>                      return rc;
>> @@ -897,7 +1145,7 @@ static int meminit_pv(struct xc_dom_image *dom)
>>                  for ( j = 0; j < rc; j++ )
>>                  {
>>                      mfn = extents[j];
>> -                    for ( k = 0; k < SUPERPAGE_NR_PFNS; k++, pfn++ )
>> +                    for ( k = 0; k < SUPERPAGE_2MB_NR_PFNS; k++, pfn++ )
>>                          dom->p2m_host[pfn] = mfn + k;
>>                  }
>>                  pfn_base_idx = pfn;
>> @@ -938,6 +1186,332 @@ static int meminit_pv(struct xc_dom_image *dom)
>>      return rc;
>>  }
>>  
>> +/*
>> + * Check whether there exists mmio hole in the specified memory range.
>> + * Returns 1 if exists, else returns 0.
>> + */
>> +static int check_mmio_hole(uint64_t start, uint64_t memsize,
>> +                           uint64_t mmio_start, uint64_t mmio_size)
>> +{
>> +    if ( start + memsize <= mmio_start || start >= mmio_start + mmio_size )
>> +        return 0;
>> +    else
>> +        return 1;
>> +}
>> +
>> +static int meminit_hvm(struct xc_dom_image *dom)
>> +{
>> +    unsigned long i, vmemid, nr_pages = dom->total_pages;
>> +    unsigned long p2m_size;
>> +    unsigned long target_pages = dom->target_pages;
>> +    unsigned long cur_pages, cur_pfn;
>> +    int rc;
>> +    xen_capabilities_info_t caps;
>> +    unsigned long stat_normal_pages = 0, stat_2mb_pages = 0, 
>> +        stat_1gb_pages = 0;
>> +    unsigned int memflags = 0;
>> +    int claim_enabled = dom->claim_enabled;
>> +    uint64_t total_pages;
>> +    xen_vmemrange_t dummy_vmemrange[2];
>> +    unsigned int dummy_vnode_to_pnode[1];
>> +    xen_vmemrange_t *vmemranges;
>> +    unsigned int *vnode_to_pnode;
>> +    unsigned int nr_vmemranges, nr_vnodes;
>> +    xc_interface *xch = dom->xch;
>> +    uint32_t domid = dom->guest_domid;
>> +
>> +    if ( nr_pages > target_pages )
>> +        memflags |= XENMEMF_populate_on_demand;
>> +
>> +    if ( dom->nr_vmemranges == 0 )
>> +    {
>> +        /* Build dummy vnode information
>> +         *
>> +         * Guest physical address space layout:
>> +         * [0, hole_start) [hole_start, 4G) [4G, highmem_end)
>> +         *
>> +         * Of course if there is no high memory, the second vmemrange
>> +         * has no effect on the actual result.
>> +         */
>> +
>> +        dummy_vmemrange[0].start = 0;
>> +        dummy_vmemrange[0].end   = dom->lowmem_end;
>> +        dummy_vmemrange[0].flags = 0;
>> +        dummy_vmemrange[0].nid   = 0;
>> +        nr_vmemranges = 1;
>> +
>> +        if ( dom->highmem_end > (1ULL << 32) )
>> +        {
>> +            dummy_vmemrange[1].start = 1ULL << 32;
>> +            dummy_vmemrange[1].end   = dom->highmem_end;
>> +            dummy_vmemrange[1].flags = 0;
>> +            dummy_vmemrange[1].nid   = 0;
>> +
>> +            nr_vmemranges++;
>> +        }
>> +
>> +        dummy_vnode_to_pnode[0] = XC_NUMA_NO_NODE;
>> +        nr_vnodes = 1;
>> +        vmemranges = dummy_vmemrange;
>> +        vnode_to_pnode = dummy_vnode_to_pnode;
>> +    }
>> +    else
>> +    {
>> +        if ( nr_pages > target_pages )
>> +        {
>> +            DOMPRINTF("Cannot enable vNUMA and PoD at the same time");
>> +            goto error_out;
>> +        }
>> +
>> +        nr_vmemranges = dom->nr_vmemranges;
>> +        nr_vnodes = dom->nr_vnodes;
>> +        vmemranges = dom->vmemranges;
>> +        vnode_to_pnode = dom->vnode_to_pnode;
>> +    }
>> +
>> +    total_pages = 0;
>> +    p2m_size = 0;
>> +    for ( i = 0; i < nr_vmemranges; i++ )
>> +    {
>> +        total_pages += ((vmemranges[i].end - vmemranges[i].start)
>> +                        >> PAGE_SHIFT);
>> +        p2m_size = p2m_size > (vmemranges[i].end >> PAGE_SHIFT) ?
>> +            p2m_size : (vmemranges[i].end >> PAGE_SHIFT);
>> +    }
>> +
>> +    if ( total_pages != nr_pages )
>> +    {
>> +        DOMPRINTF("vNUMA memory pages mismatch (0x%"PRIx64" != 0x%"PRIx64")",
>> +               total_pages, nr_pages);
>> +        goto error_out;
>> +    }
>> +
>> +    if ( xc_version(xch, XENVER_capabilities, &caps) != 0 )
>> +    {
>> +        DOMPRINTF("Could not get Xen capabilities");
>> +        goto error_out;
>> +    }
>> +
>> +    dom->p2m_size = p2m_size;
>> +    dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) *
>> +                                      dom->p2m_size);
>> +    if ( dom->p2m_host == NULL )
>> +    {
>> +        DOMPRINTF("Could not allocate p2m");
>> +        goto error_out;
>> +    }
>> +
>> +    for ( i = 0; i < p2m_size; i++ )
>> +        dom->p2m_host[i] = ((xen_pfn_t)-1);
>> +    for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
>> +    {
>> +        uint64_t pfn;
>> +
>> +        for ( pfn = vmemranges[vmemid].start >> PAGE_SHIFT;
>> +              pfn < vmemranges[vmemid].end >> PAGE_SHIFT;
>> +              pfn++ )
>> +            dom->p2m_host[pfn] = pfn;
>> +    }
>> +
>> +    /*
>> +     * Try to claim pages for early warning of insufficient memory available.
>> +     * This should go before xc_domain_set_pod_target, becuase that function
>> +     * actually allocates memory for the guest. Claiming after memory has been
>> +     * allocated is pointless.
>> +     */
>> +    if ( claim_enabled ) {
>> +        rc = xc_domain_claim_pages(xch, domid, target_pages - VGA_HOLE_SIZE);
>> +        if ( rc != 0 )
>> +        {
>> +            DOMPRINTF("Could not allocate memory for HVM guest as we cannot claim memory!");
>> +            goto error_out;
>> +        }
>> +    }
>> +
>> +    if ( memflags & XENMEMF_populate_on_demand )
>> +    {
>> +        /*
>> +         * Subtract VGA_HOLE_SIZE from target_pages for the VGA
>> +         * "hole".  Xen will adjust the PoD cache size so that domain
>> +         * tot_pages will be target_pages - VGA_HOLE_SIZE after
>> +         * this call.
>> +         */
>> +        rc = xc_domain_set_pod_target(xch, domid, target_pages - VGA_HOLE_SIZE,
>> +                                      NULL, NULL, NULL);
>> +        if ( rc != 0 )
>> +        {
>> +            DOMPRINTF("Could not set PoD target for HVM guest.\n");
>> +            goto error_out;
>> +        }
>> +    }
>> +
>> +    /*
>> +     * Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000.
>> +     *
>> +     * We attempt to allocate 1GB pages if possible. It falls back on 2MB
>> +     * pages if 1GB allocation fails. 4KB pages will be used eventually if
>> +     * both fail.
>> +     * 
>> +     * Under 2MB mode, we allocate pages in batches of no more than 8MB to 
>> +     * ensure that we can be preempted and hence dom0 remains responsive.
>> +     */
>> +    rc = xc_domain_populate_physmap_exact(
>> +        xch, domid, 0xa0, 0, memflags, &dom->p2m_host[0x00]);
>> +
>> +    stat_normal_pages = 0;
>> +    for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
>> +    {
>> +        unsigned int new_memflags = memflags;
>> +        uint64_t end_pages;
>> +        unsigned int vnode = vmemranges[vmemid].nid;
>> +        unsigned int pnode = vnode_to_pnode[vnode];
>> +
>> +        if ( pnode != XC_NUMA_NO_NODE )
>> +            new_memflags |= XENMEMF_exact_node(pnode);
>> +
>> +        end_pages = vmemranges[vmemid].end >> PAGE_SHIFT;
>> +        /*
>> +         * Consider vga hole belongs to the vmemrange that covers
>> +         * 0xA0000-0xC0000. Note that 0x00000-0xA0000 is populated just
>> +         * before this loop.
>> +         */
>> +        if ( vmemranges[vmemid].start == 0 )
>> +        {
>> +            cur_pages = 0xc0;
>> +            stat_normal_pages += 0xc0;
>> +        }
>> +        else
>> +            cur_pages = vmemranges[vmemid].start >> PAGE_SHIFT;
>> +
>> +        while ( (rc == 0) && (end_pages > cur_pages) )
>> +        {
>> +            /* Clip count to maximum 1GB extent. */
>> +            unsigned long count = end_pages - cur_pages;
>> +            unsigned long max_pages = SUPERPAGE_1GB_NR_PFNS;
>> +
>> +            if ( count > max_pages )
>> +                count = max_pages;
>> +
>> +            cur_pfn = dom->p2m_host[cur_pages];
>> +
>> +            /* Take care the corner cases of super page tails */
>> +            if ( ((cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1)) != 0) &&
>> +                 (count > (-cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1))) )
>> +                count = -cur_pfn & (SUPERPAGE_1GB_NR_PFNS-1);
>> +            else if ( ((count & (SUPERPAGE_1GB_NR_PFNS-1)) != 0) &&
>> +                      (count > SUPERPAGE_1GB_NR_PFNS) )
>> +                count &= ~(SUPERPAGE_1GB_NR_PFNS - 1);
>> +
>> +            /* Attemp to allocate 1GB super page. Because in each pass
>> +             * we only allocate at most 1GB, we don't have to clip
>> +             * super page boundaries.
>> +             */
>> +            if ( ((count | cur_pfn) & (SUPERPAGE_1GB_NR_PFNS - 1)) == 0 &&
>> +                 /* Check if there exists MMIO hole in the 1GB memory
>> +                  * range */
>> +                 !check_mmio_hole(cur_pfn << PAGE_SHIFT,
>> +                                  SUPERPAGE_1GB_NR_PFNS << PAGE_SHIFT,
>> +                                  dom->mmio_start, dom->mmio_size) )
>> +            {
>> +                long done;
>> +                unsigned long nr_extents = count >> SUPERPAGE_1GB_SHIFT;
>> +                xen_pfn_t sp_extents[nr_extents];
>> +
>> +                for ( i = 0; i < nr_extents; i++ )
>> +                    sp_extents[i] =
>> +                        dom->p2m_host[cur_pages+(i<<SUPERPAGE_1GB_SHIFT)];
>> +
>> +                done = xc_domain_populate_physmap(xch, domid, nr_extents,
>> +                                                  SUPERPAGE_1GB_SHIFT,
>> +                                                  memflags, sp_extents);
>> +
>> +                if ( done > 0 )
>> +                {
>> +                    stat_1gb_pages += done;
>> +                    done <<= SUPERPAGE_1GB_SHIFT;
>> +                    cur_pages += done;
>> +                    count -= done;
>> +                }
>> +            }
>> +
>> +            if ( count != 0 )
>> +            {
>> +                /* Clip count to maximum 8MB extent. */
>> +                max_pages = SUPERPAGE_2MB_NR_PFNS * 4;
>> +                if ( count > max_pages )
>> +                    count = max_pages;
>> +
>> +                /* Clip partial superpage extents to superpage
>> +                 * boundaries. */
>> +                if ( ((cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1)) != 0) &&
>> +                     (count > (-cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1))) )
>> +                    count = -cur_pfn & (SUPERPAGE_2MB_NR_PFNS-1);
>> +                else if ( ((count & (SUPERPAGE_2MB_NR_PFNS-1)) != 0) &&
>> +                          (count > SUPERPAGE_2MB_NR_PFNS) )
>> +                    count &= ~(SUPERPAGE_2MB_NR_PFNS - 1); /* clip non-s.p. tail */
>> +
>> +                /* Attempt to allocate superpage extents. */
>> +                if ( ((count | cur_pfn) & (SUPERPAGE_2MB_NR_PFNS - 1)) == 0 )
>> +                {
>> +                    long done;
>> +                    unsigned long nr_extents = count >> SUPERPAGE_2MB_SHIFT;
>> +                    xen_pfn_t sp_extents[nr_extents];
>> +
>> +                    for ( i = 0; i < nr_extents; i++ )
>> +                        sp_extents[i] =
>> +                            dom->p2m_host[cur_pages+(i<<SUPERPAGE_2MB_SHIFT)];
>> +
>> +                    done = xc_domain_populate_physmap(xch, domid, nr_extents,
>> +                                                      SUPERPAGE_2MB_SHIFT,
>> +                                                      memflags, sp_extents);
>> +
>> +                    if ( done > 0 )
>> +                    {
>> +                        stat_2mb_pages += done;
>> +                        done <<= SUPERPAGE_2MB_SHIFT;
>> +                        cur_pages += done;
>> +                        count -= done;
>> +                    }
>> +                }
>> +            }
>> +
>> +            /* Fall back to 4kB extents. */
>> +            if ( count != 0 )
>> +            {
>> +                rc = xc_domain_populate_physmap_exact(
>> +                    xch, domid, count, 0, new_memflags, &dom->p2m_host[cur_pages]);
>> +                cur_pages += count;
>> +                stat_normal_pages += count;
>> +            }
>> +        }
>> +
>> +        if ( rc != 0 )
>> +            break;
>> +    }
>> +
>> +    if ( rc != 0 )
>> +    {
>> +        DOMPRINTF("Could not allocate memory for HVM guest.");
>> +        goto error_out;
>> +    }
>> +
>> +    DPRINTF("PHYSICAL MEMORY ALLOCATION:\n");
>> +    DPRINTF("  4KB PAGES: 0x%016lx\n", stat_normal_pages);
>> +    DPRINTF("  2MB PAGES: 0x%016lx\n", stat_2mb_pages);
>> +    DPRINTF("  1GB PAGES: 0x%016lx\n", stat_1gb_pages);
>> +
>> +    rc = 0;
>> +    goto out;
>> + error_out:
>> +    rc = -1;
>> + out:
>> +
>> +    /* ensure no unclaimed pages are left unused */
>> +    xc_domain_claim_pages(xch, domid, 0 /* cancels the claim */);
>> +
>> +    return rc;
>> +}
>> +
>>  /* ------------------------------------------------------------------------ */
>>  
>>  static int bootearly(struct xc_dom_image *dom)
>> @@ -1052,6 +1626,12 @@ static int bootlate_pv(struct xc_dom_image *dom)
>>      return 0;
>>  }
>>  
>> +static int bootlate_hvm(struct xc_dom_image *dom)
>> +{
>> +    DOMPRINTF("%s: doing nothing", __func__);
>> +    return 0;
>> +}
>> +
>>  int xc_dom_feature_translated(struct xc_dom_image *dom)
>>  {
>>      /* Guests running inside HVM containers are always auto-translated. */
>> @@ -1095,10 +1675,27 @@ static struct xc_dom_arch xc_dom_64 = {
>>      .bootlate = bootlate_pv,
>>  };
>>  
>> +static struct xc_dom_arch xc_hvm_32 = {
>> +    .guest_type = "hvm-3.0-x86_32",
>> +    .native_protocol = XEN_IO_PROTO_ABI_X86_32,
>> +    .page_shift = PAGE_SHIFT_X86,
>> +    .sizeof_pfn = 4,
>> +    .alloc_magic_pages = alloc_magic_pages_hvm,
>> +    .count_pgtables = NULL,
>> +    .setup_pgtables = NULL,
>> +    .start_info = NULL,
>> +    .shared_info = NULL,
>> +    .vcpu = vcpu_hvm,
>> +    .meminit = meminit_hvm,
>> +    .bootearly = bootearly,
>> +    .bootlate = bootlate_hvm,
>> +};
>> +
>>  static void __init register_arch_hooks(void)
>>  {
>>      xc_dom_register_arch_hooks(&xc_dom_32_pae);
>>      xc_dom_register_arch_hooks(&xc_dom_64);
>> +    xc_dom_register_arch_hooks(&xc_hvm_32);
>>  }
>>  
>>  /*
> eof(struct hvm_save_descriptor) + HVM_SAVE_LENGTH(HEADER));
> +
> +    /* Set the CPU descriptor. */
> +    bsp_ctx.cpu_d.typecode = HVM_SAVE_CODE(CPU);
> +    bsp_ctx.cpu_d.instance = 0;
> +    bsp_ctx.cpu_d.length = HVM_SAVE_LENGTH(CPU);
> +
> +    /* Set the cached part of the relevant segment registers. */
> +    bsp_ctx.cpu.cs_base = 0;
> +    bsp_ctx.cpu.ds_base = 0;
> +    bsp_ctx.cpu.ss_base = 0;
> +    bsp_ctx.cpu.tr_base = 0;
> +    bsp_ctx.cpu.cs_limit = ~0u;
> +    bsp_ctx.cpu.ds_limit = ~0u;
> +    bsp_ctx.cpu.ss_limit = ~0u;
> +    bsp_ctx.cpu.tr_limit = 0xff;
> +    bsp_ctx.cpu.cs_arbytes = 0xc9b;
> +    bsp_ctx.cpu.ds_arbytes = 0xc93;
> +    bsp_ctx.cpu.ss_arbytes = 0xc93;
> +    bsp_ctx.cpu.tr_arbytes = 0x8b;
> +
> +    /* Set the control registers. */
> +    bsp_ctx.cpu.cr0 = X86_CR0_PE | X86_CR0_ET;
> +
> +    /* Set the IP. */
> +    bsp_ctx.cpu.rip = dom->parms.phys_entry;
> +
> +    /* Set the end descriptor. */
> +    bsp_ctx.end_d.typecode = HVM_SAVE_CODE(END);
> +    bsp_ctx.end_d.instance = 0;
> +    bsp_ctx.end_d.length = HVM_SAVE_LENGTH(END);
> +
> +    rc = xc_domain_hvm_setcontext(dom->xch, dom->guest_domid,
> +                                  (uint8_t *)&bsp_ctx, sizeof(bsp_ctx));
> +    if ( rc != 0 )
> +        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
> +                     "%s: SETHVMCONTEXT failed (rc=%d)", __func__, rc);
> +
> + out:
> +    if ( full_ctx != NULL )
> +        free(full_ctx);

No need for the NULL check.

Otherwise, Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 11/31] libxc: remove dead HVM building code
  2015-08-07 10:17 ` [PATCH v4 11/31] libxc: remove dead HVM building code Roger Pau Monne
  2015-08-07 12:12   ` Wei Liu
@ 2015-08-07 15:59   ` Andrew Cooper
  1 sibling, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 15:59 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Ian Jackson, Wei Liu, Ian Campbell, Stefano Stabellini

On 07/08/15 11:17, Roger Pau Monne wrote:
> Remove xc_hvm_build_x86.c and xc_hvm_build_arm.c since xc_hvm_build is not
> longer used in order to create HVM guests.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>

Even more slimming down!

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 25/31] xen: allow HVM guests to use XENMEM_memory_map
  2015-08-07 15:55       ` Wei Liu
@ 2015-08-07 16:00         ` Roger Pau Monné
  0 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-07 16:00 UTC (permalink / raw)
  To: Wei Liu
  Cc: Ian Campbell, Stefano Stabellini, Andrew Cooper, Ian Jackson,
	Jan Beulich, xen-devel

El 07/08/15 a les 17.55, Wei Liu ha escrit:
> On Fri, Aug 07, 2015 at 05:44:22PM +0200, Roger Pau Monné wrote:
>> El 07/08/15 a les 14.22, Wei Liu ha escrit:
>>> On Fri, Aug 07, 2015 at 12:18:02PM +0200, Roger Pau Monne wrote:
>>>> Enable this hypercall for HVM guests in order to fetch the e820 memory
>>>> map in the absence of an emulated BIOS. The memory map is populated and
>>>> notified to Xen in arch_setup_meminit_hvm.
>>>>
>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>>> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>>>> Cc: Ian Campbell <ian.campbell@citrix.com>
>>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>> ---
>>>>  tools/libxc/xc_dom_x86.c | 29 ++++++++++++++++++++++++++++-
>>>>  1 file changed, 28 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
>>>> index b587b12..87bce6e 100644
>>>> --- a/tools/libxc/xc_dom_x86.c
>>>> +++ b/tools/libxc/xc_dom_x86.c
>>>> @@ -1205,6 +1205,7 @@ static int check_mmio_hole(uint64_t start, uint64_t memsize,
>>>>          return 1;
>>>>  }
>>>>  
>>>> +#define MAX_E820_ENTRIES    128
>>>>  static int meminit_hvm(struct xc_dom_image *dom)
>>>>  {
>>>>      unsigned long i, vmemid, nr_pages = dom->total_pages;
>>>> @@ -1225,6 +1226,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>>>      unsigned int nr_vmemranges, nr_vnodes;
>>>>      xc_interface *xch = dom->xch;
>>>>      uint32_t domid = dom->guest_domid;
>>>> +    struct e820entry entries[MAX_E820_ENTRIES];
>>>> +    int e820_index = 0;
>>>>  
>>>>      if ( nr_pages > target_pages )
>>>>          memflags |= XENMEMF_populate_on_demand;
>>>> @@ -1275,6 +1278,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>>>          vnode_to_pnode = dom->vnode_to_pnode;
>>>>      }
>>>>  
>>>> +    /* Add one additional memory range to account for the VGA hole */
>>>> +    if ( (nr_vmemranges + (dom->emulation ? 1 : 0)) > MAX_E820_ENTRIES )
>>>> +    {
>>>> +        DOMPRINTF("Too many memory ranges");
>>>> +        goto error_out;
>>>> +    }
>>>> +
>>>>      total_pages = 0;
>>>>      p2m_size = 0;
>>>>      for ( i = 0; i < nr_vmemranges; i++ )
>>>> @@ -1363,9 +1373,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>>>       * Under 2MB mode, we allocate pages in batches of no more than 8MB to 
>>>>       * ensure that we can be preempted and hence dom0 remains responsive.
>>>>       */
>>>> -    if ( dom->emulation )
>>>> +    if ( dom->emulation ) {
>>>>          rc = xc_domain_populate_physmap_exact(
>>>>              xch, domid, 0xa0, 0, memflags, &dom->p2m_host[0x00]);
>>>> +        entries[e820_index].addr = 0;
>>>> +        entries[e820_index].size = 0xa0 << PAGE_SHIFT;
>>>> +        entries[e820_index++].type = E820_RAM;
>>>> +    }
>>>>  
>>>>      stat_normal_pages = 0;
>>>>      for ( vmemid = 0; vmemid < nr_vmemranges; vmemid++ )
>>>> @@ -1392,6 +1406,12 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>>>          else
>>>>              cur_pages = vmemranges[vmemid].start >> PAGE_SHIFT;
>>>>  
>>>> +        /* Build an e820 map. */
>>>> +        entries[e820_index].addr = cur_pages << PAGE_SHIFT;
>>>> +        entries[e820_index].size = vmemranges[vmemid].end -
>>>> +                                   entries[e820_index].addr;
>>>> +        entries[e820_index++].type = E820_RAM;
>>>> +
>>>>          while ( (rc == 0) && (end_pages > cur_pages) )
>>>>          {
>>>>              /* Clip count to maximum 1GB extent. */
>>>> @@ -1509,6 +1529,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>>>      DPRINTF("  2MB PAGES: 0x%016lx\n", stat_2mb_pages);
>>>>      DPRINTF("  1GB PAGES: 0x%016lx\n", stat_1gb_pages);
>>>>  
>>>> +    rc = xc_domain_set_memory_map(xch, domid, entries, e820_index);
>>>> +    if ( rc != 0 )
>>>> +    {
>>>> +        DOMPRINTF("unable to set memory map.");
>>>> +        goto error_out;
>>>> +    }
>>>> +
>>>
>>> I think in RDM series there is already a memory map generated in libxl.
>>>
>>> You might want to move this to libxl, which is supposed to be the
>>> arbitrator of what a guest should look like.
>>>
>>> What do you think?
>>
>> I would like to do that, the only problem I see is that libxl doesn't
>> have any notion of the "special pages", so it doesn't know the size of
>> the hole it has to made. I guess one solution would be moving the
>> defines at the top of xc_dom_x86.c to a public libxc header so libxl can
>> pick up the size and position of the hole.
> 
> But the code above has no notion of special pages either. Can it not
> just use the E820 map generated in libxl? I think at the time you wrote
> this patch libxl doesn't generate E820 for HVM guest, but it does now,
> so maybe you can drop this patch?

Yes, by the time I did that libxl was not building any memory map for
HVM guests. This was a preparatory patch so HVMlite guests could fetch a
memory map using the hypercall interface.

I agree that now that libxl builds a memory map this is no longer
needed, I will find a way to build a correct memory map for HVMlite
guests from libxl.

> BTW the title is not very accurate because this patch doesn't involve
> allowing / disallowing hvm to use that hypercall.

>From our talk above I guess this is going to be dropped/replaced from
the series anyway, so no need to think of a better subject :).

Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 12/31] xen/x86: add bitmap of enabled emulated devices
  2015-08-07 10:17 ` [PATCH v4 12/31] xen/x86: add bitmap of enabled emulated devices Roger Pau Monne
@ 2015-08-07 16:08   ` Andrew Cooper
  0 siblings, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 16:08 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Wei Liu, Ian Jackson, Ian Campbell, Jan Beulich, Stefano Stabellini

On 07/08/15 11:17, Roger Pau Monne wrote:
> Introduce a bitmap in x86 xen_arch_domainconfig that allows enabling or
> disabling specific devices emulated inside of Xen for HVM guests.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic
  2015-08-07 15:41     ` Roger Pau Monné
@ 2015-08-07 16:11       ` Boris Ostrovsky
  2015-08-07 16:18         ` Roger Pau Monné
  0 siblings, 1 reply; 84+ messages in thread
From: Boris Ostrovsky @ 2015-08-07 16:11 UTC (permalink / raw)
  To: Roger Pau Monné, xen-devel
  Cc: Kevin Tian, Suravee Suthikulpanit, Andrew Cooper, Eddie Dong,
	Jan Beulich, Aravind Gopalakrishnan, Jun Nakajima

On 08/07/2015 11:41 AM, Roger Pau Monné wrote:
> El 07/08/15 a les 16.09, Boris Ostrovsky ha escrit:
>> On 08/07/2015 06:17 AM, Roger Pau Monne wrote:
>>> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
>>> index a0a97e7..5acb246 100644
>>> --- a/xen/arch/x86/hvm/vmx/vmcs.c
>>> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
>>> @@ -1027,6 +1027,20 @@ static int construct_vmcs(struct vcpu *v)
>>>            ASSERT(!(v->arch.hvm_vmx.exec_control &
>>> CPU_BASED_RDTSC_EXITING));
>>>        }
>>>    +    if ( !has_vlapic(d) )
>>> +    {
>>> +        /* Disable virtual apics, TPR */
>>> +        v->arch.hvm_vmx.secondary_exec_control &=
>>> +            ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES
>>> +              | SECONDARY_EXEC_APIC_REGISTER_VIRT
>>> +              | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
>>> +        v->arch.hvm_vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
>>> +
>>> +        /* In turn, disable posted interrupts. */
>>> +        __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
>>> +                  vmx_pin_based_exec_control &
>>> ~PIN_BASED_POSTED_INTERRUPT);
>>> +    }
>>> +
>>>        vmx_update_cpu_exec_control(v);
>> This is the same code as the one used right above, in 'if (
>> is_pvh_domain(d) )' clause. Can you combine the two?
> No, it's not the same code. The PVH code disables unrestricted guest and
> sets the entry of the VM to be in long mode, which is not true for HVMlite.

Right, but the first part of that 'if' statement is the same as the one 
you are adding (including the comments). So I was suggesting

     if ( is_pvh_domain(d) || !has_vlapic(d))
     {
         /* Disable virtual apics, TPR */
         v->arch.hvm_vmx.secondary_exec_control &=
             ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES
               | SECONDARY_EXEC_APIC_REGISTER_VIRT
               | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
         v->arch.hvm_vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;

         /* In turn, disable posted interrupts. */
         __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
                   vmx_pin_based_exec_control & 
~PIN_BASED_POSTED_INTERRUPT);
    }

     if ( is_pvh_domain(d) )
     {
         /* Unrestricted guest (real mode for EPT) */
         v->arch.hvm_vmx.secondary_exec_control &=
             ~SECONDARY_EXEC_UNRESTRICTED_GUEST;

         /* Start in 64-bit mode. PVH 32bitfixme. */
         vmentry_ctl |= VM_ENTRY_IA32E_MODE;       /* GUEST_EFER.LME/LMA 
ignored */

         ASSERT(v->arch.hvm_vmx.exec_control & 
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS);
         ASSERT(v->arch.hvm_vmx.exec_control & 
CPU_BASED_ACTIVATE_MSR_BITMAP);
         ASSERT(!(v->arch.hvm_vmx.exec_control & CPU_BASED_RDTSC_EXITING));
     }


-boris

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic
  2015-08-07 16:11       ` Boris Ostrovsky
@ 2015-08-07 16:18         ` Roger Pau Monné
  0 siblings, 0 replies; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-07 16:18 UTC (permalink / raw)
  To: Boris Ostrovsky, xen-devel
  Cc: Kevin Tian, Suravee Suthikulpanit, Andrew Cooper, Eddie Dong,
	Jan Beulich, Aravind Gopalakrishnan, Jun Nakajima

El 07/08/15 a les 18.11, Boris Ostrovsky ha escrit:
> On 08/07/2015 11:41 AM, Roger Pau Monné wrote:
>> El 07/08/15 a les 16.09, Boris Ostrovsky ha escrit:
>>> On 08/07/2015 06:17 AM, Roger Pau Monne wrote:
>>>> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
>>>> index a0a97e7..5acb246 100644
>>>> --- a/xen/arch/x86/hvm/vmx/vmcs.c
>>>> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
>>>> @@ -1027,6 +1027,20 @@ static int construct_vmcs(struct vcpu *v)
>>>>            ASSERT(!(v->arch.hvm_vmx.exec_control &
>>>> CPU_BASED_RDTSC_EXITING));
>>>>        }
>>>>    +    if ( !has_vlapic(d) )
>>>> +    {
>>>> +        /* Disable virtual apics, TPR */
>>>> +        v->arch.hvm_vmx.secondary_exec_control &=
>>>> +            ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES
>>>> +              | SECONDARY_EXEC_APIC_REGISTER_VIRT
>>>> +              | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
>>>> +        v->arch.hvm_vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
>>>> +
>>>> +        /* In turn, disable posted interrupts. */
>>>> +        __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
>>>> +                  vmx_pin_based_exec_control &
>>>> ~PIN_BASED_POSTED_INTERRUPT);
>>>> +    }
>>>> +
>>>>        vmx_update_cpu_exec_control(v);
>>> This is the same code as the one used right above, in 'if (
>>> is_pvh_domain(d) )' clause. Can you combine the two?
>> No, it's not the same code. The PVH code disables unrestricted guest and
>> sets the entry of the VM to be in long mode, which is not true for
>> HVMlite.
> 
> Right, but the first part of that 'if' statement is the same as the one
> you are adding (including the comments). So I was suggesting
> 
>     if ( is_pvh_domain(d) || !has_vlapic(d))
>     {
>         /* Disable virtual apics, TPR */
>         v->arch.hvm_vmx.secondary_exec_control &=
>             ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES
>               | SECONDARY_EXEC_APIC_REGISTER_VIRT
>               | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
>         v->arch.hvm_vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
> 
>         /* In turn, disable posted interrupts. */
>         __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
>                   vmx_pin_based_exec_control &
> ~PIN_BASED_POSTED_INTERRUPT);
>    }
> 
>     if ( is_pvh_domain(d) )
>     {
>         /* Unrestricted guest (real mode for EPT) */
>         v->arch.hvm_vmx.secondary_exec_control &=
>             ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
> 
>         /* Start in 64-bit mode. PVH 32bitfixme. */
>         vmentry_ctl |= VM_ENTRY_IA32E_MODE;       /* GUEST_EFER.LME/LMA
> ignored */
> 
>         ASSERT(v->arch.hvm_vmx.exec_control &
> CPU_BASED_ACTIVATE_SECONDARY_CONTROLS);
>         ASSERT(v->arch.hvm_vmx.exec_control &
> CPU_BASED_ACTIVATE_MSR_BITMAP);
>         ASSERT(!(v->arch.hvm_vmx.exec_control & CPU_BASED_RDTSC_EXITING));
>     }

I did it as a separate condition so that when the time comes we can
completely rip the is_pvh_domain case out without having to touch this
code, but I don't have any preference TBH. I can do it that way in a
further revision if that seems preferable.

Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model.
  2015-08-07 15:51     ` Roger Pau Monné
@ 2015-08-07 16:24       ` Wei Liu
  2015-08-07 18:41         ` Andrew Cooper
  0 siblings, 1 reply; 84+ messages in thread
From: Wei Liu @ 2015-08-07 16:24 UTC (permalink / raw)
  To: Roger Pau Monné
  Cc: xen-devel, Ian Campbell, Wei Liu, Ian Jackson, Stefano Stabellini

On Fri, Aug 07, 2015 at 05:51:02PM +0200, Roger Pau Monné wrote:
[...]
> >>  It is recommended to accept the default value for new guests.  If
> >> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> >> index 1599de4..d67feb0 100644
> >> --- a/tools/libxc/xc_dom_x86.c
> >> +++ b/tools/libxc/xc_dom_x86.c
> >> @@ -1269,6 +1269,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
> >>      if ( nr_pages > target_pages )
> >>          memflags |= XENMEMF_populate_on_demand;
> >>  
> >> +    /* Make sure there's a MMIO hole for the special pages. */
> >> +    if ( dom->mmio_size == 0 )
> >> +    {
> >> +        dom->mmio_size = NR_SPECIAL_PAGES << PAGE_SHIFT;
> >> +        dom->mmio_start = special_pfn(0);
> >> +    }
> >> +
> > 
> > Better to just assert(dom->mmio_size != 0);
> > 
> > It's really libxl's responsibility to generate memory layout for guest.
> > Libxc doesn't have all information to make the decision.
> 
> As said in a previous email, libxl doesn't know the size or position of
> the special pages created by libxc code, so right now it's impossible
> for libxl to create a correct mmio hole for a HVMlite guest.
> 

Then your change here doesn't solve the real problem. You can't guarantee
when dom->mmio_size != 0, 1) the hole is large enough to accommodate all
special pages, 2) special pages don't clash with real mmio pages.

I still think there should be only one entity that controls what guest
memory layout looks like. And that entity should be the one which has
all the information available. In this case, libxl should be the one who
decides.

> > 
> >>      if ( dom->nr_vmemranges == 0 )
> >>      {
> >>          /* Build dummy vnode information
> >> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> >> index 083f099..a01868a 100644
> >> --- a/tools/libxl/libxl.c
> >> +++ b/tools/libxl/libxl.c
> >> @@ -1033,11 +1033,13 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
> >>      }
> >>  
> >>      if (type == LIBXL_DOMAIN_TYPE_HVM) {
> >> -        rc = libxl__domain_resume_device_model(gc, domid);
> >> -        if (rc < 0) {
> >> -            LOG(ERROR, "failed to unpause device model for domain %u:%d",
> >> -                domid, rc);
> >> -            goto out;
> >> +        if (libxl__domain_has_device_model(gc, domid)) {
> > 
> > Checking for device model version is not enough?
> 
> Sadly we don't have access to the device model version here, and it is
> not stored anywhere, so the only option I see is to actually check if
> there's a device model running or not in order to figure out if we have
> to unpause it.
> 

There is a function called libxl__device_model_version_running. You can
use that.

> >> +            rc = libxl__domain_resume_device_model(gc, domid);
> >> +            if (rc < 0) {
> >> +                LOG(ERROR, "failed to unpause device model for domain %u:%d",
> >> +                    domid, rc);
> >> +                goto out;
> >> +            }
> >>          }
> >>      }
> >>      ret = xc_domain_unpause(ctx->xch, domid);
> >> @@ -1567,7 +1569,6 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
> >>      libxl_ctx *ctx = CTX;
> >>      uint32_t domid = dis->domid;
> >>      char *dom_path;
> >> -    char *pid;
> >>      int rc, dm_present;
> >>  
> >>      libxl__ev_child_init(&dis->destroyer);
> >> @@ -1584,14 +1585,13 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
> >>  
> >>      switch (libxl__domain_type(gc, domid)) {
> >>      case LIBXL_DOMAIN_TYPE_HVM:
> >> -        if (!libxl_get_stubdom_id(CTX, domid))
> >> -            dm_present = 1;
> >> -        else
> >> +        if (libxl_get_stubdom_id(CTX, domid)) {
> >>              dm_present = 0;
> >> -        break;
> >> +            break;
> >> +        }
> >> +        /* fall through */
> >>      case LIBXL_DOMAIN_TYPE_PV:
> >> -        pid = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/image/device-model-pid", domid));
> >> -        dm_present = (pid != NULL);
> >> +        dm_present = libxl__domain_has_device_model(gc, domid);
> >>          break;
> >>      case LIBXL_DOMAIN_TYPE_INVALID:
> >>          rc = ERROR_FAIL;
> >> @@ -3203,7 +3203,7 @@ out:
> >>  /******************************************************************************/
> >>  
> >>  int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
> >> -                                 uint32_t domid)
> >> +                                 uint32_t domid, libxl_domain_build_info *info)
> >>  {
> >>      int rc;
> >>  
> >> @@ -3240,8 +3240,15 @@ int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
> >>  
> >>      switch (libxl__domain_type(gc, domid)) {
> >>      case LIBXL_DOMAIN_TYPE_HVM:
> >> -        if (!nic->nictype)
> >> -            nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
> >> +        if (!nic->nictype) {
> >> +            if (info != NULL &&
> >> +                info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE)
> >> +                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
> >> +            else if (libxl__domain_has_device_model(gc, domid))
> >> +                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
> >> +            else
> >> +                nic->nictype = LIBXL_NIC_TYPE_VIF;
> > 
> > I think all you need is to pass in device model version and
> > 
> >    if version != none
> >        nictype = ioemu
> >    else
> >        nictype = vif
> > 
> > ?
> > 
> > Otherwise the code suggests that there can be case you have specified a
> > device model when creating a domain but it somehow disappears when
> > domain is running?
> 
> That's exactly the case. During domain creation we know if there's a
> device model or not. But if we are doing a hot-attach of a nic this
> information is not available, so the only solution I see is to actually
> check for the device model presence.
> 

See above, use the other function instead.

Wei.

> Thanks for the review, Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic
  2015-08-07 10:17 ` [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic Roger Pau Monne
  2015-08-07 14:09   ` Boris Ostrovsky
@ 2015-08-07 16:29   ` Andrew Cooper
  1 sibling, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 16:29 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Kevin Tian, Jan Beulich, Eddie Dong, Aravind Gopalakrishnan,
	Jun Nakajima, Boris Ostrovsky, Suravee Suthikulpanit

On 07/08/15 11:17, Roger Pau Monne wrote:
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> Cc: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Jun Nakajima <jun.nakajima@intel.com>
> Cc: Eddie Dong <eddie.dong@intel.com>
> Cc: Kevin Tian <kevin.tian@intel.com>
> ---

Patches 13 - 21 (all the "allow disable of $FOO" ones)

Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>

I have not done a thorough review, but the patches look plausible to a
first order approximation.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 22/31] xen/x86: allow disabling all emulated devices inside of Xen
  2015-08-07 10:17 ` [PATCH v4 22/31] xen/x86: allow disabling all emulated devices inside of Xen Roger Pau Monne
@ 2015-08-07 16:32   ` Andrew Cooper
  0 siblings, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 16:32 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel; +Cc: Jan Beulich

On 07/08/15 11:17, Roger Pau Monne wrote:
> Only allow enabling or disabling all the emulated devices inside of Xen,
> right now Xen doesn't support enabling specific emulated devices only.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
>  xen/arch/x86/domain.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index c508074..432fe43 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -563,7 +563,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
>                            XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC |
>                            XEN_X86_EMU_PMU | XEN_X86_EMU_VGA |
>                            XEN_X86_EMU_IOMMU);
> -        if ( (config->emulation_flags & emulation_mask) != emulation_mask )
> +        if ( (config->emulation_flags & emulation_mask) != emulation_mask &&
> +             (config->emulation_flags & emulation_mask) != 0 )
>          {
>              printk(XENLOG_G_ERR "d%d: Xen does not allow HVM creation with the "
>                     "current selection of emulators: %#x.\n", d->domain_id,

Thinking about it, it might be better to have a first check against
~emulation_mask (returning -EINVAL for an unknown emulator selection),
and a second check for == mask || == 0 (returning -EOPNOTSUP for an
unsupported combination of valid emulators).

This will have a knockon effect effect on patch 12.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 24/31] libxc: allow creating domains without emulated devices.
  2015-08-07 10:18 ` [PATCH v4 24/31] libxc: allow creating domains without emulated devices Roger Pau Monne
  2015-08-07 12:18   ` Wei Liu
@ 2015-08-07 16:36   ` Andrew Cooper
  2015-08-17 15:55     ` Roger Pau Monné
  1 sibling, 1 reply; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 16:36 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Ian Jackson, Wei Liu, Ian Campbell, Stefano Stabellini

On 07/08/15 11:18, Roger Pau Monne wrote:
> @@ -1336,7 +1343,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
>           * tot_pages will be target_pages - VGA_HOLE_SIZE after
>           * this call.
>           */
> -        rc = xc_domain_set_pod_target(xch, domid, target_pages - VGA_HOLE_SIZE,
> +        rc = xc_domain_set_pod_target(xch, domid, target_pages -
> +                                      dom->emulation ? VGA_HOLE_SIZE : 0,
>                                        NULL, NULL, NULL);

This might be more cleanly expressed as having d->vga_hole_size which is
either VGA_HOLE_SIZE or 0, depending on dom->emulation.

~Andrew

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 23/31] elfnotes: intorduce a new PHYS_ENTRY elfnote
  2015-08-07 10:18 ` [PATCH v4 23/31] elfnotes: intorduce a new PHYS_ENTRY elfnote Roger Pau Monne
@ 2015-08-07 16:37   ` Andrew Cooper
  2015-08-07 16:44   ` Wei Liu
  1 sibling, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 16:37 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Ian Jackson, Wei Liu, Ian Campbell, Stefano Stabellini

On 07/08/15 11:18, Roger Pau Monne wrote:
> This new elfnote contains the 32bit entry point into the kernel. Xen will
> use this entry point in order to launch the guest kernel in 32bit protected
> mode with paging disabled.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 23/31] elfnotes: intorduce a new PHYS_ENTRY elfnote
  2015-08-07 10:18 ` [PATCH v4 23/31] elfnotes: intorduce a new PHYS_ENTRY elfnote Roger Pau Monne
  2015-08-07 16:37   ` Andrew Cooper
@ 2015-08-07 16:44   ` Wei Liu
  1 sibling, 0 replies; 84+ messages in thread
From: Wei Liu @ 2015-08-07 16:44 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:18:00PM +0200, Roger Pau Monne wrote:
> This new elfnote contains the 32bit entry point into the kernel. Xen will
> use this entry point in order to launch the guest kernel in 32bit protected
> mode with paging disabled.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>

Acked-by: Wei Liu <wei.liu2@citrix.com>

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN
  2015-08-07 10:18 ` [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN Roger Pau Monne
  2015-08-07 12:32   ` Wei Liu
@ 2015-08-07 17:30   ` Andrew Cooper
  2015-08-18 10:01     ` Roger Pau Monné
  1 sibling, 1 reply; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 17:30 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Wei Liu, Ian Jackson, Ian Campbell, Jan Beulich, Stefano Stabellini

On 07/08/15 11:18, Roger Pau Monne wrote:
> This HVM parameter returns a PFN that contains the address of the memory
> page where the guest command line has been placed.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
>  tools/libxc/xc_dom_x86.c        | 17 +++++++++++++++++
>  xen/arch/x86/hvm/hvm.c          |  2 ++
>  xen/include/public/hvm/params.h |  5 ++++-
>  3 files changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> index 87bce6e..369745d 100644
> --- a/tools/libxc/xc_dom_x86.c
> +++ b/tools/libxc/xc_dom_x86.c
> @@ -562,6 +562,23 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
>      xc_hvm_param_set(xch, domid, HVM_PARAM_SHARING_RING_PFN,
>                       special_pfn(SPECIALPAGE_SHARING));
>  
> +    if ( dom->cmdline )
> +    {
> +        xen_pfn_t cmdline_pfn = xc_dom_alloc_page(dom, "command line");
> +        char *cmdline = xc_map_foreign_range(xch, domid, PAGE_SIZE,
> +                                             PROT_READ | PROT_WRITE,
> +                                             cmdline_pfn);
> +        if ( cmdline == NULL ) {

Mix of coding styles.

> +            DOMPRINTF("Unable to map command line page");
> +            goto error_out;
> +        }
> +
> +        strncpy(cmdline, dom->cmdline, MAX_GUEST_CMDLINE);
> +        cmdline[MAX_GUEST_CMDLINE - 1] = '\0';
> +        munmap(cmdline, PAGE_SIZE);
> +        xc_hvm_param_set(xch, domid, HVM_PARAM_CMDLINE_PFN, cmdline_pfn);

I am still very much on the fence about the use of HVM parameters here,
especially as this is one-shot information which will be freed by the
guest boot process.

How much of an inconvenience would it be to specify:

%ebx is a phyaddr of a structure looking like:

struct dmlike_start_info {
    uint32_t magic;
    uint32_t flags; /* so as not to shoot ourselves in the foot */
    uint32_t cmdline_paddr;
    uint32_t nr_modules;
    uint32_t modlist_paddr;
};

And a

struct dmlite_modlist_entry {
    uint64_t paddr;
    uint64_t size;
};

This avoids enforcing page alignment on the two bits of information.  I
don't forsee the structures needing to change in the future, and in the
typical case can fit in a few hundred bytes rather than two pages.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 30/31] libxc: switch xc_dom_elfloader to be used with HVMlite domains
  2015-08-07 10:18 ` [PATCH v4 30/31] libxc: switch xc_dom_elfloader to be used with HVMlite domains Roger Pau Monne
@ 2015-08-07 17:43   ` Andrew Cooper
  0 siblings, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 17:43 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Ian Jackson, Wei Liu, Ian Campbell, Stefano Stabellini

On 07/08/15 11:18, Roger Pau Monne wrote:
> Allow xc_dom_elfloader to report a guest type as hvm-3.0-x86_32 if it's
> running inside of a HVM container and has the PHYS32_ENTRY elfnote set.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model.
  2015-08-07 15:57     ` Roger Pau Monné
@ 2015-08-07 17:52       ` Andrew Cooper
  0 siblings, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 17:52 UTC (permalink / raw)
  To: Roger Pau Monné, Konrad Rzeszutek Wilk
  Cc: Ian Jackson, xen-devel, Wei Liu, Ian Campbell, Stefano Stabellini

On 07/08/15 16:57, Roger Pau Monné wrote:
> El 07/08/15 a les 17.18, Konrad Rzeszutek Wilk ha escrit:
>> On Fri, Aug 07, 2015 at 12:18:08PM +0200, Roger Pau Monne wrote:
>>> Replace the firmware loaded into HVM guests with an OS kernel. Since the HVM
>>> builder now uses the PV xc_dom_* set of functions this kernel will be parsed
>>> and loaded inside the guest like on PV, but the container is a pure HVM
>>> guest.
>> What is your plan in regards to the 'pvh' parameteR? Should it be
>> repurposed so you can use both?
> I haven't thought about this TBH.
>
> One option could be to make the pvh parameter an alias to builder='hvm'
> device_model_version='none' with a forced 64bit entry point, but since
> PVH has never made it out of the experimental state I'm not sure if it's
> worth to keep it.

We can't remove it from the libxl API as it has been released now, even
if the underlying feature was only ever experimental.

As we plan to do some retroactive renaming at some point, it is probably
fine to keep "pvh=1" as a shorthand for "set me up the required bits
please".

~Andrew

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model.
  2015-08-07 16:24       ` Wei Liu
@ 2015-08-07 18:41         ` Andrew Cooper
  2015-08-10  7:57           ` Paul Durrant
  0 siblings, 1 reply; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 18:41 UTC (permalink / raw)
  To: Wei Liu, Roger Pau Monné
  Cc: xen-devel, Ian Jackson, Ian Campbell, Stefano Stabellini

On 07/08/15 17:24, Wei Liu wrote:
> On Fri, Aug 07, 2015 at 05:51:02PM +0200, Roger Pau Monné wrote:
> [...]
>>>>  It is recommended to accept the default value for new guests.  If
>>>> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
>>>> index 1599de4..d67feb0 100644
>>>> --- a/tools/libxc/xc_dom_x86.c
>>>> +++ b/tools/libxc/xc_dom_x86.c
>>>> @@ -1269,6 +1269,13 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>>>      if ( nr_pages > target_pages )
>>>>          memflags |= XENMEMF_populate_on_demand;
>>>>  
>>>> +    /* Make sure there's a MMIO hole for the special pages. */
>>>> +    if ( dom->mmio_size == 0 )
>>>> +    {
>>>> +        dom->mmio_size = NR_SPECIAL_PAGES << PAGE_SHIFT;
>>>> +        dom->mmio_start = special_pfn(0);
>>>> +    }
>>>> +
>>> Better to just assert(dom->mmio_size != 0);
>>>
>>> It's really libxl's responsibility to generate memory layout for guest.
>>> Libxc doesn't have all information to make the decision.
>> As said in a previous email, libxl doesn't know the size or position of
>> the special pages created by libxc code, so right now it's impossible
>> for libxl to create a correct mmio hole for a HVMlite guest.
>>
> Then your change here doesn't solve the real problem. You can't guarantee
> when dom->mmio_size != 0, 1) the hole is large enough to accommodate all
> special pages, 2) special pages don't clash with real mmio pages.
>
> I still think there should be only one entity that controls what guest
> memory layout looks like. And that entity should be the one which has
> all the information available. In this case, libxl should be the one who
> decides.

Layout and runtime management of guests has been in a very poor state
since forever.

This results from a combination of things not having been written down
to start with, new features bolted on the side, and bits moving around. 
Even at the London Hackathon in 2013, a group of us couldn't even work
out whether it was possible for a guest with certain combinations of
features to perform correct calculates not to exhaust its PoD pool and
suffer a domian_crash().

This seems like a good opportunity to take a step back and reconsider
things from scratch with the benefit of hindsight, in the hopes of
finding a way forward which gets us into a better position.

Funnily enough, there happens to be a large collection of people
happening very shortly in Seattle, and a rumour of some whiteboards.

We should consider:

* What there is (potentially) in a guests physical address space
** MMIO holes (including high), VGA hole, RMRR holes, magic emulator
pages, magic Xen pages, ACPI reported regions, etc.
** Ancillary bits such as the PoD pool, Shadow pool, etc.
* What are the architectural and ABI restrictions which exist
* What limits exist, which are static, which are dynamic
* What needs to be known by each entity in the system
** including what shouldn't be known by certain entities.

This will hopefully present a (more) clear picture of which entity
should be making things like layout decisions, and what extra
information they need to know.

It will also hopefully show how to go about fixing the existing runtime
memory management issues.

~Andrew

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 26/31] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
  2015-08-07 10:18 ` [PATCH v4 26/31] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs Roger Pau Monne
@ 2015-08-07 19:03   ` Andrew Cooper
  2015-08-12  8:22     ` Jan Beulich
  0 siblings, 1 reply; 84+ messages in thread
From: Andrew Cooper @ 2015-08-07 19:03 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel; +Cc: Stefano Stabellini, Ian Campbell, Jan Beulich

On 07/08/15 11:18, Roger Pau Monne wrote:
> Allow the usage of the VCPUOP_initialise, VCPUOP_up, VCPUOP_down and
> VCPUOP_is_up hypercalls from HVM guests.
>
> This patch introduces a new structure (vcpu_hvm_context) that should be used
> in conjuction with the VCPUOP_initialise hypercall in order to initialize
> vCPUs for HVM guests.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
> ---
>  xen/arch/arm/domain.c             |  24 ++++++
>  xen/arch/x86/domain.c             | 156 +++++++++++++++++++++++++++++++++++
>  xen/arch/x86/hvm/hvm.c            |   8 ++
>  xen/common/domain.c               |  16 +---
>  xen/include/public/hvm/hvm_vcpu.h | 168 ++++++++++++++++++++++++++++++++++++++
>  xen/include/xen/domain.h          |   2 +
>  6 files changed, 359 insertions(+), 15 deletions(-)
>  create mode 100644 xen/include/public/hvm/hvm_vcpu.h
>
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index b2bfc7d..b20035d 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -752,6 +752,30 @@ int arch_set_info_guest(
>      return 0;
>  }
>  
> +int arch_initialize_vcpu(struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg)
> +{
> +    struct vcpu_guest_context *ctxt;
> +    struct domain *d = current->domain;
> +    int rc;
> +
> +    if ( (ctxt = alloc_vcpu_guest_context()) == NULL )

I have a patch to drop this {alloc,free}_vcpu_guest_context()
infrastructure in 4.7

It was done to avoid issuing order 1 domheap allocations and spuriously
failing because of memory fragmentation, but vmalloc() is now a strictly
better option.

> +        return -ENOMEM;
> +
> +    if ( copy_from_guest(ctxt, arg, 1) )
> +    {
> +        free_vcpu_guest_context(ctxt);
> +        return -EFAULT;
> +    }
> +
> +    domain_lock(d);
> +    rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, ctxt);
> +    domain_unlock(d);
> +
> +    free_vcpu_guest_context(ctxt);
> +
> +    return rc;
> +}
> +
>  int arch_vcpu_reset(struct vcpu *v)
>  {
>      vcpu_end_shutdown_deferral(v);
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index 432fe43..4a7f8d9 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -37,6 +37,7 @@
>  #include <xen/wait.h>
>  #include <xen/guest_access.h>
>  #include <public/sysctl.h>
> +#include <public/hvm/hvm_vcpu.h>
>  #include <asm/regs.h>
>  #include <asm/mc146818rtc.h>
>  #include <asm/system.h>
> @@ -1135,6 +1136,161 @@ int arch_set_info_guest(
>  #undef c
>  }
>  
> +/* Called by VCPUOP_initialise for HVM guests. */
> +static int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx)
> +{
> +    struct segment_register seg;
> +
> +#define get_context_seg(ctx, seg, f)                                        \
> +    (ctx)->mode == VCPU_HVM_MODE_16B ? (ctx)->cpu_regs.x86_16.seg##_##f :   \
> +    (ctx)->mode == VCPU_HVM_MODE_32B ? (ctx)->cpu_regs.x86_32.seg##_##f :   \
> +    (ctx)->cpu_regs.x86_64.seg##_##f

I would be tempted to remove _context from the name, capitalise them to
make them stick out as macros, and turn them into function style macros
({ }) to avoid risk of multiple expansion.

Also you need a sanity check on mode, rather than assuming 64bit.

> +
> +#define get_context_gpr(ctx, gpr)                                           \
> +    (ctx)->mode == VCPU_HVM_MODE_16B ? (ctx)->cpu_regs.x86_16.gpr :         \
> +    (ctx)->mode == VCPU_HVM_MODE_32B ? (ctx)->cpu_regs.x86_32.e##gpr :      \
> +    (ctx)->cpu_regs.x86_64.r##gpr
> +
> +#define get_context_field(ctx, field)                                       \
> +    (ctx)->mode == VCPU_HVM_MODE_16B ? (ctx)->cpu_regs.x86_16.field :       \
> +    (ctx)->mode == VCPU_HVM_MODE_32B ? (ctx)->cpu_regs.x86_32.field :       \
> +    (ctx)->cpu_regs.x86_64.field
> +
> +    memset(&seg, 0, sizeof(seg));
> +
> +    if ( !paging_mode_hap(v->domain) )
> +        v->arch.guest_table = pagetable_null();
> +
> +    v->arch.user_regs.rax = get_context_gpr(ctx, ax);
> +    v->arch.user_regs.rcx = get_context_gpr(ctx, cx);
> +    v->arch.user_regs.rdx = get_context_gpr(ctx, dx);
> +    v->arch.user_regs.rbx = get_context_gpr(ctx, bx);
> +    v->arch.user_regs.rsp = get_context_gpr(ctx, sp);
> +    v->arch.user_regs.rbp = get_context_gpr(ctx, bp);
> +    v->arch.user_regs.rsi = get_context_gpr(ctx, si);
> +    v->arch.user_regs.rdi = get_context_gpr(ctx, di);
> +    v->arch.user_regs.rip = get_context_gpr(ctx, ip);
> +    v->arch.user_regs.rflags = get_context_gpr(ctx, flags);
> +
> +    v->arch.hvm_vcpu.guest_cr[0] = get_context_field(ctx, cr0) | X86_CR0_ET;

I am not sure whether ET is worth doing here.  It is stuck high and
ignores writes on any process Xen currently functions on.

> +    hvm_update_guest_cr(v, 0);
> +    v->arch.hvm_vcpu.guest_cr[4] = get_context_field(ctx, cr4);
> +    hvm_update_guest_cr(v, 4);
> +
> +    switch ( ctx->mode )
> +    {
> +    case VCPU_HVM_MODE_32B:
> +        v->arch.hvm_vcpu.guest_efer = ctx->cpu_regs.x86_32.efer;
> +        hvm_update_guest_efer(v);
> +        v->arch.hvm_vcpu.guest_cr[3] = ctx->cpu_regs.x86_32.cr3;
> +        hvm_update_guest_cr(v, 3);
> +        break;

Newline here please.

> +    case VCPU_HVM_MODE_64B:
> +        v->arch.user_regs.r8 = ctx->cpu_regs.x86_64.r8;
> +        v->arch.user_regs.r9 = ctx->cpu_regs.x86_64.r9;
> +        v->arch.user_regs.r10 = ctx->cpu_regs.x86_64.r10;
> +        v->arch.user_regs.r11 = ctx->cpu_regs.x86_64.r11;
> +        v->arch.user_regs.r12 = ctx->cpu_regs.x86_64.r12;
> +        v->arch.user_regs.r13 = ctx->cpu_regs.x86_64.r13;
> +        v->arch.user_regs.r14 = ctx->cpu_regs.x86_64.r14;
> +        v->arch.user_regs.r15 = ctx->cpu_regs.x86_64.r15;
> +        v->arch.hvm_vcpu.guest_efer = ctx->cpu_regs.x86_64.efer;
> +        hvm_update_guest_efer(v);
> +        v->arch.hvm_vcpu.guest_cr[3] = ctx->cpu_regs.x86_64.cr3;
> +        hvm_update_guest_cr(v, 3);
> +        break;
> +    default:
> +        break;

Drop the default case if it is going to look like this.

> +    }
> +
> +    if ( hvm_paging_enabled(v) && !paging_mode_hap(v->domain) )
> +    {
> +        /* Shadow-mode CR3 change. Check PDBR and update refcounts. */
> +        struct page_info *page = get_page_from_gfn(v->domain,
> +                                 v->arch.hvm_vcpu.guest_cr[3] >> PAGE_SHIFT,
> +                                 NULL, P2M_ALLOC);
> +        if ( !page )
> +        {
> +            gdprintk(XENLOG_ERR, "Invalid CR3\n");
> +            domain_crash(v->domain);
> +            return -EINVAL;
> +        }
> +
> +        v->arch.guest_table = pagetable_from_page(page);
> +    }
> +
> +    seg.base = get_context_seg(ctx, cs, base);
> +    seg.limit = get_context_seg(ctx, cs, limit);
> +    seg.attr.bytes = get_context_seg(ctx, cs, ar);
> +    hvm_set_segment_register(v, x86_seg_cs, &seg);
> +    seg.base = get_context_seg(ctx, ds, base);
> +    seg.limit = get_context_seg(ctx, ds, limit);
> +    seg.attr.bytes = get_context_seg(ctx, ds, ar);
> +    hvm_set_segment_register(v, x86_seg_ds, &seg);
> +    seg.base = get_context_seg(ctx, ss, base);
> +    seg.limit = get_context_seg(ctx, ss, limit);
> +    seg.attr.bytes = get_context_seg(ctx, ss, ar);
> +    hvm_set_segment_register(v, x86_seg_ss, &seg);
> +    seg.base = get_context_seg(ctx, tr, base);
> +    seg.limit = get_context_seg(ctx, tr, limit);
> +    seg.attr.bytes = get_context_seg(ctx, tr, ar);
> +    hvm_set_segment_register(v, x86_seg_tr, &seg);

This block would be easier to read as 4 blocks, one for each segment,
and if the " = " in the middle were lined up.

> +
> +    /* Sync AP's TSC with BSP's. */
> +    v->arch.hvm_vcpu.cache_tsc_offset =
> +        v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
> +    hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset,
> +                             v->domain->arch.hvm_domain.sync_tsc);
> +
> +    v->arch.hvm_vcpu.msr_tsc_adjust = 0;
> +
> +    paging_update_paging_modes(v);
> +
> +    v->arch.flags |= TF_kernel_mode;

TF_kernel_mode only applies to PV guests.  HVM guests determine kernel
vs user mode based on cpl.

> +    v->is_initialised = 1;
> +    set_bit(_VPF_down, &v->pause_flags);
> +
> +    return 0;
> +#undef get_context_field
> +#undef get_context_gpr
> +#undef get_context_seg
> +}
> +
> +int arch_initialize_vcpu(struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg)
> +{
> +    struct vcpu_guest_context *ctxt;
> +    struct vcpu_hvm_context hvm_ctx;
> +    struct domain *d = current->domain;
> +    int rc;
> +
> +    if ( is_hvm_vcpu(v) )
> +    {
> +        if ( copy_from_guest(&hvm_ctx, arg, 1) )
> +            return -EFAULT;
> +
> +        domain_lock(d);
> +        rc = v->is_initialised ? -EEXIST : arch_set_info_hvm_guest(v, &hvm_ctx);
> +        domain_unlock(d);
> +    } else {

Style.

Otherwise, this looks rather neat and surprisingly non-invasive.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model.
  2015-08-07 18:41         ` Andrew Cooper
@ 2015-08-10  7:57           ` Paul Durrant
  0 siblings, 0 replies; 84+ messages in thread
From: Paul Durrant @ 2015-08-10  7:57 UTC (permalink / raw)
  To: Andrew Cooper, Wei Liu, Roger Pau Monne
  Cc: xen-devel, Stefano Stabellini, Ian Campbell, Ian Jackson

> -----Original Message-----
> From: xen-devel-bounces@lists.xen.org [mailto:xen-devel-
> bounces@lists.xen.org] On Behalf Of Andrew Cooper
> Sent: 07 August 2015 19:42
> To: Wei Liu; Roger Pau Monne
> Cc: xen-devel@lists.xenproject.org; Ian Jackson; Ian Campbell; Stefano
> Stabellini
> Subject: Re: [Xen-devel] [PATCH v4 31/31] libxl: allow the creation of HVM
> domains without a device model.
> 
> On 07/08/15 17:24, Wei Liu wrote:
> > On Fri, Aug 07, 2015 at 05:51:02PM +0200, Roger Pau Monné wrote:
> > [...]
> >>>>  It is recommended to accept the default value for new guests.  If
> >>>> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> >>>> index 1599de4..d67feb0 100644
> >>>> --- a/tools/libxc/xc_dom_x86.c
> >>>> +++ b/tools/libxc/xc_dom_x86.c
> >>>> @@ -1269,6 +1269,13 @@ static int meminit_hvm(struct
> xc_dom_image *dom)
> >>>>      if ( nr_pages > target_pages )
> >>>>          memflags |= XENMEMF_populate_on_demand;
> >>>>
> >>>> +    /* Make sure there's a MMIO hole for the special pages. */
> >>>> +    if ( dom->mmio_size == 0 )
> >>>> +    {
> >>>> +        dom->mmio_size = NR_SPECIAL_PAGES << PAGE_SHIFT;
> >>>> +        dom->mmio_start = special_pfn(0);
> >>>> +    }
> >>>> +
> >>> Better to just assert(dom->mmio_size != 0);
> >>>
> >>> It's really libxl's responsibility to generate memory layout for guest.
> >>> Libxc doesn't have all information to make the decision.
> >> As said in a previous email, libxl doesn't know the size or position of
> >> the special pages created by libxc code, so right now it's impossible
> >> for libxl to create a correct mmio hole for a HVMlite guest.
> >>
> > Then your change here doesn't solve the real problem. You can't guarantee
> > when dom->mmio_size != 0, 1) the hole is large enough to accommodate
> all
> > special pages, 2) special pages don't clash with real mmio pages.
> >
> > I still think there should be only one entity that controls what guest
> > memory layout looks like. And that entity should be the one which has
> > all the information available. In this case, libxl should be the one who
> > decides.

Good luck convincing QEMU of that! Whatever is decided for domains without a QEMU still needs to be applicable when QEMU is there.

  Paul

> 
> Layout and runtime management of guests has been in a very poor state
> since forever.
> 
> This results from a combination of things not having been written down
> to start with, new features bolted on the side, and bits moving around.
> Even at the London Hackathon in 2013, a group of us couldn't even work
> out whether it was possible for a guest with certain combinations of
> features to perform correct calculates not to exhaust its PoD pool and
> suffer a domian_crash().
> 
> This seems like a good opportunity to take a step back and reconsider
> things from scratch with the benefit of hindsight, in the hopes of
> finding a way forward which gets us into a better position.
> 
> Funnily enough, there happens to be a large collection of people
> happening very shortly in Seattle, and a rumour of some whiteboards.
> 
> We should consider:
> 
> * What there is (potentially) in a guests physical address space
> ** MMIO holes (including high), VGA hole, RMRR holes, magic emulator
> pages, magic Xen pages, ACPI reported regions, etc.
> ** Ancillary bits such as the PoD pool, Shadow pool, etc.
> * What are the architectural and ABI restrictions which exist
> * What limits exist, which are static, which are dynamic
> * What needs to be known by each entity in the system
> ** including what shouldn't be known by certain entities.
> 
> This will hopefully present a (more) clear picture of which entity
> should be making things like layout decisions, and what extra
> information they need to know.
> 
> It will also hopefully show how to go about fixing the existing runtime
> memory management issues.
> 
> ~Andrew
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 26/31] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
  2015-08-07 19:03   ` Andrew Cooper
@ 2015-08-12  8:22     ` Jan Beulich
  0 siblings, 0 replies; 84+ messages in thread
From: Jan Beulich @ 2015-08-12  8:22 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: xen-devel, Stefano Stabellini, Ian Campbell, Roger Pau Monne

>>> On 07.08.15 at 21:03, <andrew.cooper3@citrix.com> wrote:
> On 07/08/15 11:18, Roger Pau Monne wrote:
>> @@ -1135,6 +1136,161 @@ int arch_set_info_guest(
>>  #undef c
>>  }
>>  
>> +/* Called by VCPUOP_initialise for HVM guests. */
>> +static int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx)
>> +{
>> +    struct segment_register seg;
>> +
>> +#define get_context_seg(ctx, seg, f)                                        \
>> +    (ctx)->mode == VCPU_HVM_MODE_16B ? (ctx)->cpu_regs.x86_16.seg##_##f :   \
>> +    (ctx)->mode == VCPU_HVM_MODE_32B ? (ctx)->cpu_regs.x86_32.seg##_##f :   \
>> +    (ctx)->cpu_regs.x86_64.seg##_##f
> 
> I would be tempted to remove _context from the name, capitalise them to
> make them stick out as macros, and turn them into function style macros
> ({ }) to avoid risk of multiple expansion.

I'm kind of confused by this reply of yours: Neither does use of
({ }) make a macro function like (afaik this is tied to the macro
having parameters), nor can I see how its use would prevent
multiple expansion (even without being certain what exactly you
consider here). In general I'm advocating for not using compiler
extensions when their use doesn't serve a clear purpose. I.e. if
the above was to be re-written as a switch() statement, then the
need for using ({ }) might indeed arise.

Jan

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling
  2015-08-07 10:17 ` [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling Roger Pau Monne
  2015-08-07 10:49   ` Wei Liu
@ 2015-08-13 15:04   ` Ian Jackson
  2015-08-13 15:06   ` Wei Liu
  2 siblings, 0 replies; 84+ messages in thread
From: Ian Jackson @ 2015-08-13 15:04 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: xen-devel, Wei Liu, Ian Campbell, Stefano Stabellini

Roger Pau Monne writes ("[PATCH v4 01/31] libxl: fix libxl__build_hvm error handling"):
> With the current code in libxl__build_hvm it is possible for the function to
> fail and still return 0.

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling
  2015-08-07 10:17 ` [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling Roger Pau Monne
  2015-08-07 10:49   ` Wei Liu
  2015-08-13 15:04   ` Ian Jackson
@ 2015-08-13 15:06   ` Wei Liu
  2015-08-16  8:01     ` Ian Campbell
  2 siblings, 1 reply; 84+ messages in thread
From: Wei Liu @ 2015-08-13 15:06 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: xen-devel, Wei Liu, Ian Jackson, Ian Campbell, Stefano Stabellini

On Fri, Aug 07, 2015 at 12:17:38PM +0200, Roger Pau Monne wrote:
> With the current code in libxl__build_hvm it is possible for the function to
> fail and still return 0.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>

This wasn't targeted 4.6 when posted, but in other thread we come to the
conclusion that we should merge it now. So:

Release-acked-by: Wei Liu <wei.liu2@citrix.com>

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling
  2015-08-13 15:06   ` Wei Liu
@ 2015-08-16  8:01     ` Ian Campbell
  0 siblings, 0 replies; 84+ messages in thread
From: Ian Campbell @ 2015-08-16  8:01 UTC (permalink / raw)
  To: Wei Liu, Roger Pau Monne; +Cc: xen-devel, Ian Jackson, Stefano Stabellini

On Thu, 2015-08-13 at 16:06 +0100, Wei Liu wrote:
> On Fri, Aug 07, 2015 at 12:17:38PM +0200, Roger Pau Monne wrote:
> > With the current code in libxl__build_hvm it is possible for the 
> > function to
> > fail and still return 0.
> > 
> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> > Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> > Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > Cc: Ian Campbell <ian.campbell@citrix.com>
> > Cc: Wei Liu <wei.liu2@citrix.com>
> 
> This wasn't targeted 4.6 when posted, but in other thread we come to 
> the
> conclusion that we should merge it now. So:
> 
> Release-acked-by: Wei Liu <wei.liu2@citrix.com>

applied.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 24/31] libxc: allow creating domains without emulated devices.
  2015-08-07 16:36   ` Andrew Cooper
@ 2015-08-17 15:55     ` Roger Pau Monné
  2015-08-18 16:25       ` Andrew Cooper
  0 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-17 15:55 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: Ian Jackson, Wei Liu, Ian Campbell, Stefano Stabellini

El 07/08/15 a les 18.36, Andrew Cooper ha escrit:
> On 07/08/15 11:18, Roger Pau Monne wrote:
>> @@ -1336,7 +1343,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>           * tot_pages will be target_pages - VGA_HOLE_SIZE after
>>           * this call.
>>           */
>> -        rc = xc_domain_set_pod_target(xch, domid, target_pages - VGA_HOLE_SIZE,
>> +        rc = xc_domain_set_pod_target(xch, domid, target_pages -
>> +                                      dom->emulation ? VGA_HOLE_SIZE : 0,
>>                                        NULL, NULL, NULL);
> 
> This might be more cleanly expressed as having d->vga_hole_size which is
> either VGA_HOLE_SIZE or 0, depending on dom->emulation.

I'm afraid I don't understand this comment. What's "d" in the phrase
above? I cannot see any local variable or argument called "d" in the
context of meminit_hvm.

Or do you mean that the dom->emulation flag should be split into
dom->disable_ioreqs and dom->vga_hole_size?

Roger.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN
  2015-08-07 17:30   ` Andrew Cooper
@ 2015-08-18 10:01     ` Roger Pau Monné
  2015-08-18 16:32       ` Andrew Cooper
  0 siblings, 1 reply; 84+ messages in thread
From: Roger Pau Monné @ 2015-08-18 10:01 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: Wei Liu, Ian Jackson, Ian Campbell, Jan Beulich, Stefano Stabellini

El 07/08/15 a les 19.30, Andrew Cooper ha escrit:
> On 07/08/15 11:18, Roger Pau Monne wrote:
>> This HVM parameter returns a PFN that contains the address of the memory
>> page where the guest command line has been placed.
>>
>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>> Cc: Ian Campbell <ian.campbell@citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>> Cc: Jan Beulich <jbeulich@suse.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>>  tools/libxc/xc_dom_x86.c        | 17 +++++++++++++++++
>>  xen/arch/x86/hvm/hvm.c          |  2 ++
>>  xen/include/public/hvm/params.h |  5 ++++-
>>  3 files changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
>> index 87bce6e..369745d 100644
>> --- a/tools/libxc/xc_dom_x86.c
>> +++ b/tools/libxc/xc_dom_x86.c
>> @@ -562,6 +562,23 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
>>      xc_hvm_param_set(xch, domid, HVM_PARAM_SHARING_RING_PFN,
>>                       special_pfn(SPECIALPAGE_SHARING));
>>  
>> +    if ( dom->cmdline )
>> +    {
>> +        xen_pfn_t cmdline_pfn = xc_dom_alloc_page(dom, "command line");
>> +        char *cmdline = xc_map_foreign_range(xch, domid, PAGE_SIZE,
>> +                                             PROT_READ | PROT_WRITE,
>> +                                             cmdline_pfn);
>> +        if ( cmdline == NULL ) {
> 
> Mix of coding styles.
> 
>> +            DOMPRINTF("Unable to map command line page");
>> +            goto error_out;
>> +        }
>> +
>> +        strncpy(cmdline, dom->cmdline, MAX_GUEST_CMDLINE);
>> +        cmdline[MAX_GUEST_CMDLINE - 1] = '\0';
>> +        munmap(cmdline, PAGE_SIZE);
>> +        xc_hvm_param_set(xch, domid, HVM_PARAM_CMDLINE_PFN, cmdline_pfn);
> 
> I am still very much on the fence about the use of HVM parameters here,
> especially as this is one-shot information which will be freed by the
> guest boot process.
> 
> How much of an inconvenience would it be to specify:
> 
> %ebx is a phyaddr of a structure looking like:
> 
> struct dmlike_start_info {
>     uint32_t magic;
>     uint32_t flags; /* so as not to shoot ourselves in the foot */
>     uint32_t cmdline_paddr;
>     uint32_t nr_modules;
>     uint32_t modlist_paddr;
> };
> 
> And a
> 
> struct dmlite_modlist_entry {
>     uint64_t paddr;
>     uint64_t size;
> };
> 
> This avoids enforcing page alignment on the two bits of information.  I
> don't forsee the structures needing to change in the future, and in the
> typical case can fit in a few hundred bytes rather than two pages.

I agree, using two pages was overkill for this, specially taking into
account that the command line cannot exceed 1024 chars.

The above structure looks fine, I would note that the command line is
limited to 1024 characters, so that leaves us with a maximum of 190
modules if we want to limit all this metainfo to one page only, which
IMHO is more than enough.

Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 24/31] libxc: allow creating domains without emulated devices.
  2015-08-17 15:55     ` Roger Pau Monné
@ 2015-08-18 16:25       ` Andrew Cooper
  0 siblings, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-18 16:25 UTC (permalink / raw)
  To: Roger Pau Monné, xen-devel
  Cc: Ian Jackson, Wei Liu, Ian Campbell, Stefano Stabellini



On 17/08/15 08:55, Roger Pau Monné wrote:
> El 07/08/15 a les 18.36, Andrew Cooper ha escrit:
>> On 07/08/15 11:18, Roger Pau Monne wrote:
>>> @@ -1336,7 +1343,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
>>>            * tot_pages will be target_pages - VGA_HOLE_SIZE after
>>>            * this call.
>>>            */
>>> -        rc = xc_domain_set_pod_target(xch, domid, target_pages - VGA_HOLE_SIZE,
>>> +        rc = xc_domain_set_pod_target(xch, domid, target_pages -
>>> +                                      dom->emulation ? VGA_HOLE_SIZE : 0,
>>>                                         NULL, NULL, NULL);
>> This might be more cleanly expressed as having d->vga_hole_size which is
>> either VGA_HOLE_SIZE or 0, depending on dom->emulation.
> I'm afraid I don't understand this comment. What's "d" in the phrase
> above? I cannot see any local variable or argument called "d" in the
> context of meminit_hvm.

I meant introducing a new variable, dom->vga_hole_size, which gets set 
to 0 or VGA_HOLE_SIZE earlier on.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN
  2015-08-18 10:01     ` Roger Pau Monné
@ 2015-08-18 16:32       ` Andrew Cooper
  0 siblings, 0 replies; 84+ messages in thread
From: Andrew Cooper @ 2015-08-18 16:32 UTC (permalink / raw)
  To: Roger Pau Monné, xen-devel
  Cc: Wei Liu, Ian Jackson, Ian Campbell, Jan Beulich, Stefano Stabellini

On 18/08/15 03:01, Roger Pau Monné wrote:
> El 07/08/15 a les 19.30, Andrew Cooper ha escrit:
>> On 07/08/15 11:18, Roger Pau Monne wrote:
>>> This HVM parameter returns a PFN that contains the address of the memory
>>> page where the guest command line has been placed.
>>>
>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>>> Cc: Ian Campbell <ian.campbell@citrix.com>
>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>> Cc: Jan Beulich <jbeulich@suse.com>
>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>> ---
>>>   tools/libxc/xc_dom_x86.c        | 17 +++++++++++++++++
>>>   xen/arch/x86/hvm/hvm.c          |  2 ++
>>>   xen/include/public/hvm/params.h |  5 ++++-
>>>   3 files changed, 23 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
>>> index 87bce6e..369745d 100644
>>> --- a/tools/libxc/xc_dom_x86.c
>>> +++ b/tools/libxc/xc_dom_x86.c
>>> @@ -562,6 +562,23 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
>>>       xc_hvm_param_set(xch, domid, HVM_PARAM_SHARING_RING_PFN,
>>>                        special_pfn(SPECIALPAGE_SHARING));
>>>   
>>> +    if ( dom->cmdline )
>>> +    {
>>> +        xen_pfn_t cmdline_pfn = xc_dom_alloc_page(dom, "command line");
>>> +        char *cmdline = xc_map_foreign_range(xch, domid, PAGE_SIZE,
>>> +                                             PROT_READ | PROT_WRITE,
>>> +                                             cmdline_pfn);
>>> +        if ( cmdline == NULL ) {
>> Mix of coding styles.
>>
>>> +            DOMPRINTF("Unable to map command line page");
>>> +            goto error_out;
>>> +        }
>>> +
>>> +        strncpy(cmdline, dom->cmdline, MAX_GUEST_CMDLINE);
>>> +        cmdline[MAX_GUEST_CMDLINE - 1] = '\0';
>>> +        munmap(cmdline, PAGE_SIZE);
>>> +        xc_hvm_param_set(xch, domid, HVM_PARAM_CMDLINE_PFN, cmdline_pfn);
>> I am still very much on the fence about the use of HVM parameters here,
>> especially as this is one-shot information which will be freed by the
>> guest boot process.
>>
>> How much of an inconvenience would it be to specify:
>>
>> %ebx is a phyaddr of a structure looking like:
>>
>> struct dmlike_start_info {
>>      uint32_t magic;
>>      uint32_t flags; /* so as not to shoot ourselves in the foot */
>>      uint32_t cmdline_paddr;
>>      uint32_t nr_modules;
>>      uint32_t modlist_paddr;
>> };
>>
>> And a
>>
>> struct dmlite_modlist_entry {
>>      uint64_t paddr;
>>      uint64_t size;
>> };
>>
>> This avoids enforcing page alignment on the two bits of information.  I
>> don't forsee the structures needing to change in the future, and in the
>> typical case can fit in a few hundred bytes rather than two pages.
> I agree, using two pages was overkill for this, specially taking into
> account that the command line cannot exceed 1024 chars.

This is a silly restriction, and should not be propagated.  Here, it 
should simply be specified as a NUL-terminated octet stream.  Linux in 
perfectly capable of dealing with a longer command line.

>
> The above structure looks fine, I would note that the command line is
> limited to 1024 characters, so that leaves us with a maximum of 190
> modules if we want to limit all this metainfo to one page only, which
> IMHO is more than enough.

Just because the information would typically be less than 1 page doesn't 
impose any form of 4K upper limit.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

end of thread, other threads:[~2015-08-18 16:32 UTC | newest]

Thread overview: 84+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-07 10:17 [PATCH v4 00/31] Introduce HVM without dm and new boot ABI Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 01/31] libxl: fix libxl__build_hvm error handling Roger Pau Monne
2015-08-07 10:49   ` Wei Liu
2015-08-07 10:55     ` Roger Pau Monné
2015-08-07 11:03       ` Wei Liu
2015-08-07 11:28         ` Roger Pau Monné
2015-08-07 11:43           ` Wei Liu
2015-08-13 15:04   ` Ian Jackson
2015-08-13 15:06   ` Wei Liu
2015-08-16  8:01     ` Ian Campbell
2015-08-07 10:17 ` [PATCH v4 02/31] libxc: split x86 HVM setup_guest into smaller logical functions Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 03/31] libxc: unify xc_dom_p2m_{host/guest} Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 04/31] libxc: introduce the notion of a container type Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 05/31] libxc: introduce a domain loader for HVM guest firmware Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 06/31] libxc: make arch_setup_meminit a xc_dom_arch hook Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 07/31] libxc: make arch_setup_boot{init/late} xc_dom_arch hooks Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 08/31] libxc: rework BSP initialization Roger Pau Monne
2015-08-07 11:31   ` Wei Liu
2015-08-07 12:04     ` Roger Pau Monné
2015-08-07 12:06       ` Wei Liu
2015-08-07 15:30         ` Andrew Cooper
2015-08-07 15:22   ` Andrew Cooper
2015-08-07 10:17 ` [PATCH v4 09/31] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests Roger Pau Monne
2015-08-07 12:00   ` Wei Liu
2015-08-07 15:58   ` Andrew Cooper
2015-08-07 10:17 ` [PATCH v4 10/31] libxl: switch HVM domain building to use xc_dom_* helpers Roger Pau Monne
2015-08-07 12:12   ` Wei Liu
2015-08-07 10:17 ` [PATCH v4 11/31] libxc: remove dead HVM building code Roger Pau Monne
2015-08-07 12:12   ` Wei Liu
2015-08-07 15:59   ` Andrew Cooper
2015-08-07 10:17 ` [PATCH v4 12/31] xen/x86: add bitmap of enabled emulated devices Roger Pau Monne
2015-08-07 16:08   ` Andrew Cooper
2015-08-07 10:17 ` [PATCH v4 13/31] xen/x86: allow disabling the emulated local apic Roger Pau Monne
2015-08-07 14:09   ` Boris Ostrovsky
2015-08-07 15:41     ` Roger Pau Monné
2015-08-07 16:11       ` Boris Ostrovsky
2015-08-07 16:18         ` Roger Pau Monné
2015-08-07 16:29   ` Andrew Cooper
2015-08-07 10:17 ` [PATCH v4 14/31] xen/x86: allow disabling the emulated HPET Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 15/31] xen/x86: allow disabling the pmtimer Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 16/31] xen/x86: allow disabling the emulated RTC Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 17/31] xen/x86: allow disabling the emulated IO APIC Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 18/31] xen/x86: allow disabling the emulated PIC Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 19/31] xen/x86: allow disabling the emulated pmu Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 20/31] xen/x86: allow disabling the emulated VGA Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 21/31] xen/x86: allow disabling the emulated IOMMU Roger Pau Monne
2015-08-07 10:17 ` [PATCH v4 22/31] xen/x86: allow disabling all emulated devices inside of Xen Roger Pau Monne
2015-08-07 16:32   ` Andrew Cooper
2015-08-07 10:18 ` [PATCH v4 23/31] elfnotes: intorduce a new PHYS_ENTRY elfnote Roger Pau Monne
2015-08-07 16:37   ` Andrew Cooper
2015-08-07 16:44   ` Wei Liu
2015-08-07 10:18 ` [PATCH v4 24/31] libxc: allow creating domains without emulated devices Roger Pau Monne
2015-08-07 12:18   ` Wei Liu
2015-08-07 16:36   ` Andrew Cooper
2015-08-17 15:55     ` Roger Pau Monné
2015-08-18 16:25       ` Andrew Cooper
2015-08-07 10:18 ` [PATCH v4 25/31] xen: allow HVM guests to use XENMEM_memory_map Roger Pau Monne
2015-08-07 12:22   ` Wei Liu
2015-08-07 15:44     ` Roger Pau Monné
2015-08-07 15:55       ` Wei Liu
2015-08-07 16:00         ` Roger Pau Monné
2015-08-07 10:18 ` [PATCH v4 26/31] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs Roger Pau Monne
2015-08-07 19:03   ` Andrew Cooper
2015-08-12  8:22     ` Jan Beulich
2015-08-07 10:18 ` [PATCH v4 27/31] xenconsole: try to attach to PV console if HVM fails Roger Pau Monne
2015-08-07 12:25   ` Wei Liu
2015-08-07 10:18 ` [PATCH v4 28/31] libxc/xen: introduce HVM_PARAM_CMDLINE_PFN Roger Pau Monne
2015-08-07 12:32   ` Wei Liu
2015-08-07 17:30   ` Andrew Cooper
2015-08-18 10:01     ` Roger Pau Monné
2015-08-18 16:32       ` Andrew Cooper
2015-08-07 10:18 ` [PATCH v4 29/31] libxc/xen: introduce HVM_PARAM_MODLIST_PFN Roger Pau Monne
2015-08-07 12:36   ` Wei Liu
2015-08-07 10:18 ` [PATCH v4 30/31] libxc: switch xc_dom_elfloader to be used with HVMlite domains Roger Pau Monne
2015-08-07 17:43   ` Andrew Cooper
2015-08-07 10:18 ` [PATCH v4 31/31] libxl: allow the creation of HVM domains without a device model Roger Pau Monne
2015-08-07 12:58   ` Wei Liu
2015-08-07 15:51     ` Roger Pau Monné
2015-08-07 16:24       ` Wei Liu
2015-08-07 18:41         ` Andrew Cooper
2015-08-10  7:57           ` Paul Durrant
2015-08-07 15:18   ` Konrad Rzeszutek Wilk
2015-08-07 15:57     ` Roger Pau Monné
2015-08-07 17:52       ` Andrew Cooper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.