* [PATCH v7 01/32] xen/vcpu: add missing dummy_vcpu_info to compat VCPUOP_initialise
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 18:21 ` Andrew Cooper
2015-10-05 10:05 ` Jan Beulich
2015-10-02 15:48 ` [PATCH v7 02/32] libxc: split x86 HVM setup_guest into smaller logical functions Roger Pau Monne
` (31 subsequent siblings)
32 siblings, 2 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel
Cc: Andrew Cooper, Tim Deegan, Ian Campbell, Jan Beulich,
Roger Pau Monne
This check is missing from the compat version when compared to the
non-compat version.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Tim Deegan <tim@xen.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
xen/common/compat/domain.c | 5 +++++
xen/common/domain.c | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/xen/common/compat/domain.c b/xen/common/compat/domain.c
index 3ca4ef7..5dc7d94 100644
--- a/xen/common/compat/domain.c
+++ b/xen/common/compat/domain.c
@@ -23,6 +23,8 @@ CHECK_SIZE_(struct, vcpu_info);
CHECK_vcpu_register_vcpu_info;
#undef xen_vcpu_register_vcpu_info
+extern vcpu_info_t dummy_vcpu_info;
+
int compat_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg)
{
struct domain *d = current->domain;
@@ -38,6 +40,9 @@ int compat_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) ar
{
struct compat_vcpu_guest_context *cmp_ctxt;
+ if ( v->vcpu_info == &dummy_vcpu_info )
+ return -EINVAL;
+
if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL )
{
rc = -ENOMEM;
diff --git a/xen/common/domain.c b/xen/common/domain.c
index cda60a9..cec0dcf 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -70,7 +70,7 @@ integer_param("hardware_dom", hardware_domid);
struct vcpu *idle_vcpu[NR_CPUS] __read_mostly;
-static vcpu_info_t dummy_vcpu_info;
+vcpu_info_t dummy_vcpu_info;
static void __domain_finalise_shutdown(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] 105+ messages in thread
* Re: [PATCH v7 01/32] xen/vcpu: add missing dummy_vcpu_info to compat VCPUOP_initialise
2015-10-02 15:48 ` [PATCH v7 01/32] xen/vcpu: add missing dummy_vcpu_info to compat VCPUOP_initialise Roger Pau Monne
@ 2015-10-02 18:21 ` Andrew Cooper
2015-10-05 10:05 ` Jan Beulich
1 sibling, 0 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-10-02 18:21 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel; +Cc: Tim Deegan, Ian Campbell, Jan Beulich
On 02/10/15 16:48, Roger Pau Monne wrote:
> This check is missing from the compat version when compared to the
> non-compat version.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Tim Deegan <tim@xen.org>
> 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] 105+ messages in thread
* Re: [PATCH v7 01/32] xen/vcpu: add missing dummy_vcpu_info to compat VCPUOP_initialise
2015-10-02 15:48 ` [PATCH v7 01/32] xen/vcpu: add missing dummy_vcpu_info to compat VCPUOP_initialise Roger Pau Monne
2015-10-02 18:21 ` Andrew Cooper
@ 2015-10-05 10:05 ` Jan Beulich
2015-10-05 16:18 ` Roger Pau Monné
1 sibling, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-10-05 10:05 UTC (permalink / raw)
To: Roger Pau Monne; +Cc: Andrew Cooper, Tim Deegan, Ian Campbell, xen-devel
>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
> --- a/xen/common/compat/domain.c
> +++ b/xen/common/compat/domain.c
> @@ -23,6 +23,8 @@ CHECK_SIZE_(struct, vcpu_info);
> CHECK_vcpu_register_vcpu_info;
> #undef xen_vcpu_register_vcpu_info
>
> +extern vcpu_info_t dummy_vcpu_info;
This need to be put in a header included by both producer and
consumer, so the declaration can't go out of sync with the
definition (without causing build failure).
Jan
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 01/32] xen/vcpu: add missing dummy_vcpu_info to compat VCPUOP_initialise
2015-10-05 10:05 ` Jan Beulich
@ 2015-10-05 16:18 ` Roger Pau Monné
0 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-05 16:18 UTC (permalink / raw)
To: Jan Beulich; +Cc: Andrew Cooper, Tim Deegan, Ian Campbell, xen-devel
El 05/10/15 a les 12.05, Jan Beulich ha escrit:
>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>> --- a/xen/common/compat/domain.c
>> +++ b/xen/common/compat/domain.c
>> @@ -23,6 +23,8 @@ CHECK_SIZE_(struct, vcpu_info);
>> CHECK_vcpu_register_vcpu_info;
>> #undef xen_vcpu_register_vcpu_info
>>
>> +extern vcpu_info_t dummy_vcpu_info;
>
> This need to be put in a header included by both producer and
> consumer, so the declaration can't go out of sync with the
> definition (without causing build failure).
Done. I've re-sent the patch individually.
Roger.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 02/32] libxc: split x86 HVM setup_guest into smaller logical functions
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 01/32] xen/vcpu: add missing dummy_vcpu_info to compat VCPUOP_initialise Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 03/32] libxc: unify xc_dom_p2m_{host/guest} Roger Pau Monne
` (30 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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 ea250dd..4d3736b 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++ )
@@ -564,7 +525,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");
@@ -577,6 +585,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 )
@@ -665,34 +711,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;
}
@@ -703,9 +727,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;
@@ -716,24 +739,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] 105+ messages in thread
* [PATCH v7 03/32] libxc: unify xc_dom_p2m_{host/guest}
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 01/32] xen/vcpu: add missing dummy_vcpu_info to compat VCPUOP_initialise Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 02/32] libxc: split x86 HVM setup_guest into smaller logical functions Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 04/32] libxc: introduce the notion of a container type Roger Pau Monne
` (29 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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 602c5cd..e794a13 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -373,19 +373,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 e2f3792..f3962cd 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 == XEN_PAE_YES )
{
@@ -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 ( (!dom->pvh_enabled) &&
(addr >= dom->pgtables_seg.vstart) &&
(addr < dom->pgtables_seg.vend) )
@@ -316,7 +316,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;
@@ -375,7 +375,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++;
}
@@ -387,7 +387,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++;
}
@@ -399,7 +399,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++;
}
@@ -407,7 +407,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) )
@@ -490,9 +490,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 )
@@ -536,9 +536,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 )
@@ -606,7 +606,7 @@ static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr)
dom->parms.pae == XEN_PAE_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);
@@ -645,7 +645,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);
@@ -1018,7 +1018,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 b514377..286df93 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -739,8 +739,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] 105+ messages in thread
* [PATCH v7 04/32] libxc: introduce the notion of a container type
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (2 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 03/32] libxc: unify xc_dom_p2m_{host/guest} Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 05/32] libxc: introduce a domain loader for HVM guest firmware Roger Pau Monne
` (28 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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 e794a13..30fa8c5 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -177,6 +177,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 f3962cd..d306475 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -1069,6 +1069,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 286df93..01172b0 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -620,6 +620,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] 105+ messages in thread
* [PATCH v7 05/32] libxc: introduce a domain loader for HVM guest firmware
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (3 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 04/32] libxc: introduce the notion of a container type Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-07 16:55 ` [PATCH v8 " Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 06/32] libxc: make arch_setup_meminit a xc_dom_arch hook Roger Pau Monne
` (27 subsequent siblings)
32 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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 a0f899b..baaadd6 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 30fa8c5..88c5c80 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)
@@ -183,6 +184,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 d7045f6..de788c7 100644
--- a/xen/include/xen/libelf.h
+++ b/xen/include/xen/libelf.h
@@ -431,6 +431,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] 105+ messages in thread
* [PATCH v8 05/32] libxc: introduce a domain loader for HVM guest firmware
2015-10-02 15:48 ` [PATCH v7 05/32] libxc: introduce a domain loader for HVM guest firmware Roger Pau Monne
@ 2015-10-07 16:55 ` Roger Pau Monne
2015-10-08 9:22 ` Ian Campbell
2015-10-08 10:12 ` Ian Campbell
0 siblings, 2 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-07 16:55 UTC (permalink / raw)
To: xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
Ian Jackson, 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.
Since the order in which loaders are tested cannot be arranged, prevent the
current elfloader from trying to boot a kernel that doesn't contain Xen
ELFNOTES.
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: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v7:
- Prevent elfloader from loading kernels that don't have Xen elfnotes.
Another solution is to force an order in the way loaders are tested,
but that's a more complex solution.
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_elfloader.c | 22 ++-
tools/libxc/xc_dom_hvmloader.c | 313 +++++++++++++++++++++++++++++++++++++++++
xen/include/xen/libelf.h | 1 +
5 files changed, 344 insertions(+), 1 deletion(-)
create mode 100644 tools/libxc/xc_dom_hvmloader.c
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index a0f899b..baaadd6 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 30fa8c5..88c5c80 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)
@@ -183,6 +184,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_elfloader.c b/tools/libxc/xc_dom_elfloader.c
index 82524c9..36a115e 100644
--- a/tools/libxc/xc_dom_elfloader.c
+++ b/tools/libxc/xc_dom_elfloader.c
@@ -106,7 +106,27 @@ static elf_negerrnoval check_elf_kernel(struct xc_dom_image *dom, bool verbose)
static elf_negerrnoval xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
{
- return check_elf_kernel(dom, 0);
+ struct elf_binary elf;
+ int rc;
+
+ 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 it contains Xen ELFNOTES,
+ * or else we might be trying to load a plain ELF.
+ */
+ elf_parse_binary(&elf);
+ rc = elf_xen_parse(&elf, &dom->parms);
+ if ( rc != 0 )
+ return rc;
+
+ return 0;
}
static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
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 d7045f6..de788c7 100644
--- a/xen/include/xen/libelf.h
+++ b/xen/include/xen/libelf.h
@@ -431,6 +431,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] 105+ messages in thread
* Re: [PATCH v8 05/32] libxc: introduce a domain loader for HVM guest firmware
2015-10-07 16:55 ` [PATCH v8 " Roger Pau Monne
@ 2015-10-08 9:22 ` Ian Campbell
2015-10-08 9:26 ` Roger Pau Monné
2015-10-08 10:12 ` Ian Campbell
1 sibling, 1 reply; 105+ messages in thread
From: Ian Campbell @ 2015-10-08 9:22 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel
Cc: Wei Liu, Andrew Cooper, Ian Jackson, Stefano Stabellini
On Wed, 2015-10-07 at 18:55 +0200, Roger Pau Monne wrote:
> 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.
>
> Since the order in which loaders are tested cannot be arranged, prevent the
> current elfloader from trying to boot a kernel that doesn't contain Xen
> ELFNOTES.
>
> 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: Andrew Cooper <andrew.cooper3@citrix.com>
I only seem to have received this single patch from v8.
Is the intention that this should simply replace the equivalent patch in v7
or did the others somehow go astray?
Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v8 05/32] libxc: introduce a domain loader for HVM guest firmware
2015-10-08 9:22 ` Ian Campbell
@ 2015-10-08 9:26 ` Roger Pau Monné
0 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-08 9:26 UTC (permalink / raw)
To: Ian Campbell, xen-devel
Cc: Wei Liu, Andrew Cooper, Ian Jackson, Stefano Stabellini
El 08/10/15 a les 11.22, Ian Campbell ha escrit:
> On Wed, 2015-10-07 at 18:55 +0200, Roger Pau Monne wrote:
>> 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.
>>
>> Since the order in which loaders are tested cannot be arranged, prevent the
>> current elfloader from trying to boot a kernel that doesn't contain Xen
>> ELFNOTES.
>>
>> 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: Andrew Cooper <andrew.cooper3@citrix.com>
>
> I only seem to have received this single patch from v8.
>
> Is the intention that this should simply replace the equivalent patch in v7
> or did the others somehow go astray?
Yes, this patch it's supposed to replace the v7 version, I haven't sent
the full series. Maybe I should have numbered it 7.1 or something less
ambiguous.
I've done this in order to make it easier to commit 2-11 while I work on
the comments in the rest of the series.
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v8 05/32] libxc: introduce a domain loader for HVM guest firmware
2015-10-07 16:55 ` [PATCH v8 " Roger Pau Monne
2015-10-08 9:22 ` Ian Campbell
@ 2015-10-08 10:12 ` Ian Campbell
2015-10-08 10:43 ` Roger Pau Monné
1 sibling, 1 reply; 105+ messages in thread
From: Ian Campbell @ 2015-10-08 10:12 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel
Cc: Wei Liu, Andrew Cooper, Ian Jackson, Stefano Stabellini
On Wed, 2015-10-07 at 18:55 +0200, Roger Pau Monne wrote:
> 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.
>
> Since the order in which loaders are tested cannot be arranged, prevent the
> current elfloader from trying to boot a kernel that doesn't contain Xen
> ELFNOTES.
I think it relies (probably implicitly and probably not very defined) on
the link order.
It is possible to control this (somewhat) because the __init used on
register_loader turns into __attribute__((constructor)), which takes an
(optional) priority. You can also (I think) use __attribute__
((init_priority (2000))).
All of which is enormous faff. Having xc_dom_register_loader() take a
priority, or putting one in struct xc_dom_loader would be less so.
Apart fromall that, I'm happy with the idea that the elfloader shouldn't be
selected to load things which it cannot work with.
However I'm unsure that the presence or absence of ELF notes is sufficient,
since there is at least the legacy SHT_NOTE section and then __xen_guest
section (see the tail of elf_xen_parse) as well.
It may well be that the code you've got actually covers these cases and
it's just the commentary which doesn't. I think this is probably the case
(since elf_xen_parse calls elf_xen_note_check after handling all those
cases).
There is an additional subtlety with ARM not having notes, but I think your
checks will pass and therefore to the right thing.
>
> 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: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> Changes since v7:
> - Prevent elfloader from loading kernels that don't have Xen elfnotes.
> Another solution is to force an order in the way loaders are tested,
> but that's a more complex solution.
>
> 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_elfloader.c | 22 ++-
> tools/libxc/xc_dom_hvmloader.c | 313
> +++++++++++++++++++++++++++++++++++++++++
> xen/include/xen/libelf.h | 1 +
> 5 files changed, 344 insertions(+), 1 deletion(-)
> create mode 100644 tools/libxc/xc_dom_hvmloader.c
>
> diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
> index a0f899b..baaadd6 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 30fa8c5..88c5c80 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)
>
> @@ -183,6 +184,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_elfloader.c
> b/tools/libxc/xc_dom_elfloader.c
> index 82524c9..36a115e 100644
> --- a/tools/libxc/xc_dom_elfloader.c
> +++ b/tools/libxc/xc_dom_elfloader.c
> @@ -106,7 +106,27 @@ static elf_negerrnoval check_elf_kernel(struct
> xc_dom_image *dom, bool verbose)
>
> static elf_negerrnoval xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
> {
> - return check_elf_kernel(dom, 0);
> + struct elf_binary elf;
> + int rc;
> +
> + 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 it contains Xen ELFNOTES,
> + * or else we might be trying to load a plain ELF.
> + */
> + elf_parse_binary(&elf);
> + rc = elf_xen_parse(&elf, &dom->parms);
> + if ( rc != 0 )
> + return rc;
Can you confirm that I'm right and there is no need to cleanup of free this
elf object?
It's a bit of a shame to now have to parse the ELF twice. How abusive would
to be to declare that when a xc_dom ->probe hook returns success it is
entitled to rely on the contents of dom->loader_private being preserved
until ->parse is called. In turn this would imply that the first successful
probe would be used rather than e.g. probing everything and then picking a
winner from the successful applicants.
That feels a bit abusive though.
We could give ->probe a void **private_out which is guaranteed to be passed
to the ->parse if this loader is selected.
Perhaps I'm over thinking this.
I've only looked at this aspect which is new in v8, since others were ok
with the rest in v7. (You were right to drop the acks though)
Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v8 05/32] libxc: introduce a domain loader for HVM guest firmware
2015-10-08 10:12 ` Ian Campbell
@ 2015-10-08 10:43 ` Roger Pau Monné
2015-10-08 11:04 ` Ian Campbell
0 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-08 10:43 UTC (permalink / raw)
To: Ian Campbell, xen-devel
Cc: Wei Liu, Andrew Cooper, Ian Jackson, Stefano Stabellini
El 08/10/15 a les 12.12, Ian Campbell ha escrit:
> On Wed, 2015-10-07 at 18:55 +0200, Roger Pau Monne wrote:
>> 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.
>>
>> Since the order in which loaders are tested cannot be arranged, prevent the
>> current elfloader from trying to boot a kernel that doesn't contain Xen
>> ELFNOTES.
>
> I think it relies (probably implicitly and probably not very defined) on
> the link order.
>
> It is possible to control this (somewhat) because the __init used on
> register_loader turns into __attribute__((constructor)), which takes an
> (optional) priority. You can also (I think) use __attribute__
> ((init_priority (2000))).
>
> All of which is enormous faff. Having xc_dom_register_loader() take a
> priority, or putting one in struct xc_dom_loader would be less so.
>
> Apart fromall that, I'm happy with the idea that the elfloader shouldn't be
> selected to load things which it cannot work with.
>
> However I'm unsure that the presence or absence of ELF notes is sufficient,
> since there is at least the legacy SHT_NOTE section and then __xen_guest
> section (see the tail of elf_xen_parse) as well.
AFAICT NetBSD still uses the __xen_guest section, and it works fine with
this change:
http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/arch/amd64/amd64/locore.S?rev=1.78&content-type=text/plain&only_with_tag=MAIN
elfloader recognizes the kernel and it's able to load it without issues.
xc_dom_parse_elf_kernel already calls elf_xen_parse later on, while
trying to load the kernel, so the functionality it's exactly the same,
it's just that we now simply refuse to try to load a kernel without
elfnotes with elfloader.
Without this change the elfloader would try to load a kernel without
elfnotes just to fail later while parsing it.
> It may well be that the code you've got actually covers these cases and
> it's just the commentary which doesn't. I think this is probably the case
> (since elf_xen_parse calls elf_xen_note_check after handling all those
> cases).
>
> There is an additional subtlety with ARM not having notes, but I think your
> checks will pass and therefore to the right thing.
>>
>> 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: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> Changes since v7:
>> - Prevent elfloader from loading kernels that don't have Xen elfnotes.
>> Another solution is to force an order in the way loaders are tested,
>> but that's a more complex solution.
>>
>> 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_elfloader.c | 22 ++-
>> tools/libxc/xc_dom_hvmloader.c | 313
>> +++++++++++++++++++++++++++++++++++++++++
>> xen/include/xen/libelf.h | 1 +
>> 5 files changed, 344 insertions(+), 1 deletion(-)
>> create mode 100644 tools/libxc/xc_dom_hvmloader.c
>>
>> diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
>> index a0f899b..baaadd6 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 30fa8c5..88c5c80 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)
>>
>> @@ -183,6 +184,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_elfloader.c
>> b/tools/libxc/xc_dom_elfloader.c
>> index 82524c9..36a115e 100644
>> --- a/tools/libxc/xc_dom_elfloader.c
>> +++ b/tools/libxc/xc_dom_elfloader.c
>> @@ -106,7 +106,27 @@ static elf_negerrnoval check_elf_kernel(struct
>> xc_dom_image *dom, bool verbose)
>>
>> static elf_negerrnoval xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
>> {
>> - return check_elf_kernel(dom, 0);
>> + struct elf_binary elf;
>> + int rc;
>> +
>> + 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 it contains Xen ELFNOTES,
>> + * or else we might be trying to load a plain ELF.
>> + */
>> + elf_parse_binary(&elf);
>> + rc = elf_xen_parse(&elf, &dom->parms);
>> + if ( rc != 0 )
>> + return rc;
>
> Can you confirm that I'm right and there is no need to cleanup of free this
> elf object?
AFAICT yes, there's no function to free an elf object, and I haven't
spotted any memory allocations in the functions called
(elf_init/elf_parse_binary/elf_xen_parse).
> It's a bit of a shame to now have to parse the ELF twice. How abusive would
> to be to declare that when a xc_dom ->probe hook returns success it is
> entitled to rely on the contents of dom->loader_private being preserved
> until ->parse is called. In turn this would imply that the first successful
> probe would be used rather than e.g. probing everything and then picking a
> winner from the successful applicants.
We already do this, we stop testing once a probe returns 0 (see
xc_dom_find_loader), and use that as the loader, so there's no
functional change in this aspect. IMHO, this approach is not very
intrusive, would you like me implement it in a followup patch or rather
do it in the series?
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v8 05/32] libxc: introduce a domain loader for HVM guest firmware
2015-10-08 10:43 ` Roger Pau Monné
@ 2015-10-08 11:04 ` Ian Campbell
2015-10-08 11:12 ` Andrew Cooper
2015-10-08 11:13 ` Wei Liu
0 siblings, 2 replies; 105+ messages in thread
From: Ian Campbell @ 2015-10-08 11:04 UTC (permalink / raw)
To: Roger Pau Monné, xen-devel
Cc: Wei Liu, Andrew Cooper, Ian Jackson, Stefano Stabellini
On Thu, 2015-10-08 at 12:43 +0200, Roger Pau Monné wrote:
> > However I'm unsure that the presence or absence of ELF notes is sufficient,
> > since there is at least the legacy SHT_NOTE section and then __xen_guest
> > section (see the tail of elf_xen_parse) as well.
>
> AFAICT NetBSD still uses the __xen_guest section, and it works fine with
> this change:
>
> http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/arch/amd64/amd64/locore.S?rev=1.78&content-type=text/plain&only_with_tag=MAIN
>
> elfloader recognizes the kernel and it's able to load it without issues.
>
> xc_dom_parse_elf_kernel already calls elf_xen_parse later on, while
> trying to load the kernel, so the functionality it's exactly the same,
> it's just that we now simply refuse to try to load a kernel without
> elfnotes with elfloader.
>
> Without this change the elfloader would try to load a kernel without
> elfnotes just to fail later while parsing it.
Great, thanks for confirming.
> > It's a bit of a shame to now have to parse the ELF twice. How abusive would
> > to be to declare that when a xc_dom ->probe hook returns success it is
> > entitled to rely on the contents of dom->loader_private being preserved
> > until ->parse is called. In turn this would imply that the first successful
> > probe would be used rather than e.g. probing everything and then picking a
> > winner from the successful applicants.
>
> We already do this, we stop testing once a probe returns 0 (see
> xc_dom_find_loader), and use that as the loader, so there's no
> functional change in this aspect. IMHO, this approach is not very
> intrusive, would you like me implement it in a followup patch or rather
> do it in the series?
I think this series is big enough that we need to start draining the
pipeline. So lets address this later.
On the basis that v7 was Reviewed by Andy and Acked by Wei and that I've
looked at the delta (only) from that:
Acked-by: Ian Campbell <ian.campbell@citrix.com>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v8 05/32] libxc: introduce a domain loader for HVM guest firmware
2015-10-08 11:04 ` Ian Campbell
@ 2015-10-08 11:12 ` Andrew Cooper
2015-10-08 11:13 ` Wei Liu
1 sibling, 0 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-10-08 11:12 UTC (permalink / raw)
To: Ian Campbell, Roger Pau Monné, xen-devel
Cc: Wei Liu, Ian Jackson, Stefano Stabellini
On 08/10/15 12:04, Ian Campbell wrote:
> On Thu, 2015-10-08 at 12:43 +0200, Roger Pau Monné wrote:
>>> However I'm unsure that the presence or absence of ELF notes is sufficient,
>>> since there is at least the legacy SHT_NOTE section and then __xen_guest
>>> section (see the tail of elf_xen_parse) as well.
>> AFAICT NetBSD still uses the __xen_guest section, and it works fine with
>> this change:
>>
>> http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/arch/amd64/amd64/locore.S?rev=1.78&content-type=text/plain&only_with_tag=MAIN
>>
>> elfloader recognizes the kernel and it's able to load it without issues.
>>
>> xc_dom_parse_elf_kernel already calls elf_xen_parse later on, while
>> trying to load the kernel, so the functionality it's exactly the same,
>> it's just that we now simply refuse to try to load a kernel without
>> elfnotes with elfloader.
>>
>> Without this change the elfloader would try to load a kernel without
>> elfnotes just to fail later while parsing it.
> Great, thanks for confirming.
>
>>> It's a bit of a shame to now have to parse the ELF twice. How abusive would
>>> to be to declare that when a xc_dom ->probe hook returns success it is
>>> entitled to rely on the contents of dom->loader_private being preserved
>>> until ->parse is called. In turn this would imply that the first successful
>>> probe would be used rather than e.g. probing everything and then picking a
>>> winner from the successful applicants.
>> We already do this, we stop testing once a probe returns 0 (see
>> xc_dom_find_loader), and use that as the loader, so there's no
>> functional change in this aspect. IMHO, this approach is not very
>> intrusive, would you like me implement it in a followup patch or rather
>> do it in the series?
> I think this series is big enough that we need to start draining the
> pipeline. So lets address this later.
>
> On the basis that v7 was Reviewed by Andy and Acked by Wei and that I've
> looked at the delta (only) from that:
>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
v8 also 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] 105+ messages in thread
* Re: [PATCH v8 05/32] libxc: introduce a domain loader for HVM guest firmware
2015-10-08 11:04 ` Ian Campbell
2015-10-08 11:12 ` Andrew Cooper
@ 2015-10-08 11:13 ` Wei Liu
1 sibling, 0 replies; 105+ messages in thread
From: Wei Liu @ 2015-10-08 11:13 UTC (permalink / raw)
To: Ian Campbell
Cc: Wei Liu, Stefano Stabellini, Andrew Cooper, Ian Jackson,
xen-devel, Roger Pau Monné
On Thu, Oct 08, 2015 at 12:04:30PM +0100, Ian Campbell wrote:
> On Thu, 2015-10-08 at 12:43 +0200, Roger Pau Monné wrote:
> > > However I'm unsure that the presence or absence of ELF notes is sufficient,
> > > since there is at least the legacy SHT_NOTE section and then __xen_guest
> > > section (see the tail of elf_xen_parse) as well.
> >
> > AFAICT NetBSD still uses the __xen_guest section, and it works fine with
> > this change:
> >
> > http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/arch/amd64/amd64/locore.S?rev=1.78&content-type=text/plain&only_with_tag=MAIN
> >
> > elfloader recognizes the kernel and it's able to load it without issues.
> >
> > xc_dom_parse_elf_kernel already calls elf_xen_parse later on, while
> > trying to load the kernel, so the functionality it's exactly the same,
> > it's just that we now simply refuse to try to load a kernel without
> > elfnotes with elfloader.
> >
> > Without this change the elfloader would try to load a kernel without
> > elfnotes just to fail later while parsing it.
>
> Great, thanks for confirming.
>
> > > It's a bit of a shame to now have to parse the ELF twice. How abusive would
> > > to be to declare that when a xc_dom ->probe hook returns success it is
> > > entitled to rely on the contents of dom->loader_private being preserved
> > > until ->parse is called. In turn this would imply that the first successful
> > > probe would be used rather than e.g. probing everything and then picking a
> > > winner from the successful applicants.
> >
> > We already do this, we stop testing once a probe returns 0 (see
> > xc_dom_find_loader), and use that as the loader, so there's no
> > functional change in this aspect. IMHO, this approach is not very
> > intrusive, would you like me implement it in a followup patch or rather
> > do it in the series?
>
> I think this series is big enough that we need to start draining the
> pipeline. So lets address this later.
>
> On the basis that v7 was Reviewed by Andy and Acked by Wei and that I've
> looked at the delta (only) from that:
>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
>
v8
Acked-by: Wei Liu <wei.liu2@citrix.com>
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 06/32] libxc: make arch_setup_meminit a xc_dom_arch hook
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (4 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 05/32] libxc: introduce a domain loader for HVM guest firmware Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 07/32] libxc: make arch_setup_boot{init/late} xc_dom_arch hooks Roger Pau Monne
` (26 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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 88c5c80..01739fa 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -221,6 +221,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;
@@ -398,7 +401,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 aeaba54..e8a0756 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 d306475..fbedf85 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -668,38 +668,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 {
@@ -731,7 +699,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;
@@ -755,7 +722,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;
@@ -1076,6 +1043,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] 105+ messages in thread
* [PATCH v7 07/32] libxc: make arch_setup_boot{init/late} xc_dom_arch hooks
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (5 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 06/32] libxc: make arch_setup_meminit a xc_dom_arch hook Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 08/32] libxc: rework BSP initialization Roger Pau Monne
` (25 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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 01739fa..ced6ae2 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -220,6 +220,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);
@@ -399,11 +401,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 e8a0756..ec3a757 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 fbedf85..b48dc1b 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -922,7 +922,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;
@@ -961,7 +963,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;
@@ -1057,6 +1059,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 = {
@@ -1071,6 +1075,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] 105+ messages in thread
* [PATCH v7 08/32] libxc: rework BSP initialization
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (6 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 07/32] libxc: make arch_setup_boot{init/late} xc_dom_arch hooks Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 09/32] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests Roger Pau Monne
` (24 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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 in order to
introduce a new builder, 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>
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 v5:
- Reword commit message to remove a reference to "next patch".
Changes since v4:
- Add Andrew Cooper Reviewed-by.
---
tools/libxc/include/xc_dom.h | 2 +-
tools/libxc/xc_dom_arm.c | 26 ++++++++++++++++++------
tools/libxc/xc_dom_boot.c | 23 +--------------------
tools/libxc/xc_dom_x86.c | 48 ++++++++++++++++++++++++++++----------------
4 files changed, 53 insertions(+), 46 deletions(-)
diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index ced6ae2..2498cf7 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -219,7 +219,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 ec3a757..397eef0 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -119,9 +119,11 @@ 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;
+ int rc;
DOMPRINTF_CALLED(dom->xch);
@@ -154,12 +156,19 @@ 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;
+ int rc;
DOMPRINTF_CALLED(dom->xch);
/* clear everything */
@@ -189,7 +198,12 @@ 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);
- 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;
}
/* ------------------------------------------------------------------------ */
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 b48dc1b..ab88996 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -584,10 +584,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);
@@ -611,26 +613,33 @@ 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);
- if ( dom->pvh_enabled )
- return 0;
-
- ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_32;
- ctxt->user_regs.es = FLAT_KERNEL_DS_X86_32;
- ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_32;
- ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_32;
- ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_32;
- ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_32;
+ if ( !dom->pvh_enabled )
+ {
+ ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_32;
+ ctxt->user_regs.es = FLAT_KERNEL_DS_X86_32;
+ ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_32;
+ ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_32;
+ ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_32;
+ ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_32;
+
+ ctxt->kernel_ss = ctxt->user_regs.ss;
+ ctxt->kernel_sp = ctxt->user_regs.esp;
+ }
- ctxt->kernel_ss = ctxt->user_regs.ss;
- ctxt->kernel_sp = ctxt->user_regs.esp;
+ 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;
+ 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);
@@ -663,7 +672,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] 105+ messages in thread
* [PATCH v7 09/32] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (7 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 08/32] libxc: rework BSP initialization Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 10/32] libxl: switch HVM domain building to use xc_dom_* helpers Roger Pau Monne
` (23 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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>
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 v6:
- Fix incorrect printf conversion specification.
Changes since v5:
- Set tr limit to 0x67.
- Use "goto out" consistently in vcpu_hvm.
- Unconditionally call free(full_ctx) before exiting vcpu_hvm.
- Add Wei Liu Ack.
Changes since v4:
- Replace a malloc+memset with a calloc.
- Remove a != NULL check.
- Add Andrew Cooper Reviewed-by.
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 | 618 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 613 insertions(+), 11 deletions(-)
diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 2498cf7..e52b023 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -186,6 +186,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 ab88996..dd331bf 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))
@@ -462,6 +484,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)
@@ -680,6 +831,102 @@ 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);
+ goto out;
+ }
+
+ full_ctx = calloc(1, 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);
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ 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 = 0x67;
+ 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:
+ free(full_ctx);
+ return rc;
+}
+
/* ------------------------------------------------------------------------ */
static int x86_compat(xc_interface *xch, domid_t domid, char *guest_type)
@@ -760,7 +1007,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;
@@ -771,9 +1018,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;
@@ -783,7 +1030,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;
}
}
@@ -868,7 +1115,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++ )
@@ -881,11 +1128,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;
@@ -895,7 +1142,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;
@@ -936,6 +1183,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%lx)",
+ 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,
+ new_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,
+ new_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)
@@ -1050,6 +1623,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. */
@@ -1093,10 +1672,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] 105+ messages in thread
* [PATCH v7 10/32] libxl: switch HVM domain building to use xc_dom_* helpers
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (8 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 09/32] libxc: introduce a xc_dom_arch for hvm-3.0-x86_32 guests Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 11/32] libxc: remove dead HVM building code Roger Pau Monne
` (22 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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>
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 v6:
- Fix uninitialized usage of rc in libxl__build_hvm.
Changes since v4:
- Add Wei Liu Acked-by.
---
tools/libxl/libxl_arch.h | 2 +-
tools/libxl/libxl_arm.c | 2 +-
tools/libxl/libxl_dm.c | 18 ++--
tools/libxl/libxl_dom.c | 228 +++++++++++++++++++++++++------------------
tools/libxl/libxl_internal.h | 4 +-
tools/libxl/libxl_vnuma.c | 12 ++-
tools/libxl/libxl_x86.c | 8 +-
7 files changed, 157 insertions(+), 117 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_arm.c b/tools/libxl/libxl_arm.c
index 0af8010..1195b37 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -974,7 +974,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)
{
return 0;
}
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 71a1a3e..8e337de 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 01172b0..a9925b7 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -603,6 +603,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)
{
@@ -693,48 +750,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");
+ ret = libxl__build_dom(gc, domid, info, state, dom);
+ if (ret != 0)
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");
- 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;
@@ -794,39 +812,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;
}
@@ -840,7 +858,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;
@@ -866,8 +884,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;
@@ -881,8 +904,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;
}
}
@@ -898,8 +921,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;
}
}
@@ -913,52 +936,63 @@ 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");
+ rc = ERROR_NOMEM;
+ 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;
@@ -967,7 +1001,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;
@@ -977,37 +1011,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,
@@ -1017,15 +1048,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 c2413c2..c5df398 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1609,7 +1609,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
@@ -3772,7 +3772,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 896f34c..9276126 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] 105+ messages in thread
* [PATCH v7 11/32] libxc: remove dead HVM building code
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (9 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 10/32] libxl: switch HVM domain building to use xc_dom_* helpers Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices Roger Pau Monne
` (21 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@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 v4:
- Add Wei Liu Acked-by and Andrew Cooper Reviewed-by.
---
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 | 808 --------------------------------------
tools/libxc/xg_private.c | 9 -
tools/python/xen/lowlevel/xc/xc.c | 81 ----
6 files changed, 992 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 baaadd6..818f2e4 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 4d3736b..0000000
--- a/tools/libxc/xc_hvm_build_x86.c
+++ /dev/null
@@ -1,808 +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,
- new_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,
- new_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 67afed4..b441777 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -906,77 +906,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)
@@ -2362,16 +2291,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] 105+ messages in thread
* [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (10 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 11/32] libxc: remove dead HVM building code Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-05 9:34 ` Andrew Cooper
` (2 more replies)
2015-10-02 15:48 ` [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic Roger Pau Monne
` (20 subsequent siblings)
32 siblings, 3 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
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>
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: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <george.dunlap@eu.citrix.com>
---
Changes since v6:
- Define XEN_X86_EMU_ALL to contain all the possible emulated devices.
- Remove full stops form the printks added to arch_domain_create.
- Add Wei Liu Acked-by.
- Added a check to x86 arch_domain_create in order to make sure a non-null
config is always provided.
- Check that emulation_flags is always 0 for PV guests.
- Fix x86 callers of domain_create in order to make sure a non-null arch
config is always provided.
- Removed XEN_X86_EMU_PMU.
- Removed Andrew Cooper's Reviewed-by, since the hypervisor side code has
changed substantially.
Changes since v4:
- Add a check to make sure the emulation bitmap is sane (undefined bits are
all 0s).
- Add Andrew Cooper Reviewed-by.
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 | 5 ++++-
xen/arch/x86/domain.c | 19 +++++++++++++++++++
xen/arch/x86/mm.c | 7 ++++---
xen/arch/x86/setup.c | 3 ++-
xen/common/schedule.c | 8 +++++++-
xen/include/asm-x86/domain.h | 12 ++++++++++++
xen/include/public/arch-x86/xen.h | 23 ++++++++++++++++++++++-
7 files changed, 70 insertions(+), 7 deletions(-)
diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
index 9276126..e71f80e 100644
--- a/tools/libxl/libxl_x86.c
+++ b/tools/libxl/libxl_x86.c
@@ -7,7 +7,10 @@ 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_ALL;
+ else
+ xc_config->emulation_flags = 0;
return 0;
}
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index dc3bb08..79182a4 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -496,6 +496,9 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
int i, paging_initialised = 0;
int rc = -ENOMEM;
+ if ( config == NULL )
+ return -EINVAL;
+
d->arch.s3_integrity = !!(domcr_flags & DOMCRF_s3_integrity);
INIT_LIST_HEAD(&d->arch.pdev_list);
@@ -517,6 +520,22 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
d->domain_id);
}
+ if ( (config->emulation_flags & ~XEN_X86_EMU_ALL) != 0 )
+ {
+ printk(XENLOG_G_ERR "d%d: Invalid emulation bitmap: %#x\n",
+ d->domain_id, config->emulation_flags);
+ return -EINVAL;
+ }
+ if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL) ||
+ (is_pv_domain(d) && config->emulation_flags != 0) )
+ {
+ printk(XENLOG_G_ERR "d%d: Xen does not allow %s domain creation with "
+ "the current selection of emulators: %#x\n", d->domain_id,
+ is_hvm_domain(d) ? "HVM" : "PV", 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/arch/x86/mm.c b/xen/arch/x86/mm.c
index 327b837..b0873f6 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -255,6 +255,7 @@ static l4_pgentry_t __read_mostly split_l4e;
void __init arch_init_memory(void)
{
unsigned long i, pfn, rstart_pfn, rend_pfn, iostart_pfn, ioend_pfn;
+ struct xen_arch_domainconfig config = { .emulation_flags = 0 };
/* Basic guest-accessible flags: PRESENT, R/W, USER, A/D, AVAIL[0,1,2] */
base_disallow_mask = ~(_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|
@@ -272,7 +273,7 @@ void __init arch_init_memory(void)
* Hidden PCI devices will also be associated with this domain
* (but be [partly] controlled by Dom0 nevertheless).
*/
- dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0, NULL);
+ dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0, &config);
BUG_ON(IS_ERR(dom_xen));
INIT_LIST_HEAD(&dom_xen->arch.pdev_list);
@@ -281,14 +282,14 @@ void __init arch_init_memory(void)
* This domain owns I/O pages that are within the range of the page_info
* array. Mappings occur at the priv of the caller.
*/
- dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0, NULL);
+ dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0, &config);
BUG_ON(IS_ERR(dom_io));
/*
* Initialise our COW domain.
* This domain owns sharable pages.
*/
- dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0, NULL);
+ dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0, &config);
BUG_ON(IS_ERR(dom_cow));
/* First 1MB of RAM is historically marked as I/O. */
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 3f4868e..7efcb9d 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -582,6 +582,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
.parity = 'n',
.stop_bits = 1
};
+ struct xen_arch_domainconfig config = { .emulation_flags = 0 };
/* Critical region without IDT or TSS. Any fault is deadly! */
@@ -1394,7 +1395,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
* x86 doesn't support arch-configuration. So it's fine to pass
* NULL.
*/
- dom0 = domain_create(0, domcr_flags, 0, NULL);
+ dom0 = domain_create(0, domcr_flags, 0, &config);
if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
panic("Error creating domain 0");
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 5ffa1a1..aeb911e 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
/* Initialise the data structures. */
void __init scheduler_init(void)
{
+#ifdef CONFIG_X86
+ struct xen_arch_domainconfig config = { .emulation_flags = 0 };
+#endif
struct domain *idle_domain;
int i;
@@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
}
- /* There is no need of arch-specific configuration for an idle domain */
+#ifdef CONFIG_X86
+ idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
+#else
idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
+#endif
BUG_ON(IS_ERR(idle_domain));
idle_domain->vcpu = idle_vcpu;
idle_domain->max_vcpus = nr_cpu_ids;
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index f1d7ed6..84ae4c1 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -387,8 +387,20 @@ struct arch_domain
/* Mem_access emulation control */
bool_t mem_access_emulate_enabled;
bool_t mem_access_emulate_each_rep;
+
+ /* 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_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..c97a9b4 100644
--- a/xen/include/public/arch-x86/xen.h
+++ b/xen/include/public/arch-x86/xen.h
@@ -268,7 +268,28 @@ 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_VGA 6
+#define XEN_X86_EMU_VGA (1U<<_XEN_X86_EMU_VGA)
+#define _XEN_X86_EMU_IOMMU 7
+#define XEN_X86_EMU_IOMMU (1U<<_XEN_X86_EMU_IOMMU)
+
+#define XEN_X86_EMU_ALL (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_VGA | XEN_X86_EMU_IOMMU)
+ 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] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-02 15:48 ` [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices Roger Pau Monne
@ 2015-10-05 9:34 ` Andrew Cooper
2015-10-05 16:40 ` Roger Pau Monné
2015-10-06 11:05 ` George Dunlap
2015-10-08 10:23 ` Jan Beulich
2015-10-15 1:48 ` Boris Ostrovsky
2 siblings, 2 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-10-05 9:34 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Ian Jackson, Jan Beulich
On 02/10/15 16:48, 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>
> 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: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: George Dunlap <george.dunlap@eu.citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, with 2 small
suggestions.
> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
> index 5ffa1a1..aeb911e 100644
> --- a/xen/common/schedule.c
> +++ b/xen/common/schedule.c
> @@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
> /* Initialise the data structures. */
> void __init scheduler_init(void)
> {
> +#ifdef CONFIG_X86
> + struct xen_arch_domainconfig config = { .emulation_flags = 0 };
> +#endif
> struct domain *idle_domain;
> int i;
>
> @@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
> sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
> }
>
> - /* There is no need of arch-specific configuration for an idle domain */
> +#ifdef CONFIG_X86
> + idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
> +#else
> idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
> +#endif
You could get away without this ifdefary if you have
#else
void *config = NULL;
In the previous hunk.
> BUG_ON(IS_ERR(idle_domain));
> idle_domain->vcpu = idle_vcpu;
> idle_domain->max_vcpus = nr_cpu_ids;
> diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
> index f1d7ed6..84ae4c1 100644
> --- a/xen/include/asm-x86/domain.h
> +++ b/xen/include/asm-x86/domain.h
> @@ -387,8 +387,20 @@ struct arch_domain
> /* Mem_access emulation control */
> bool_t mem_access_emulate_enabled;
> bool_t mem_access_emulate_each_rep;
> +
> + /* 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_vvga(d) ((d)->arch.emulation_flags & XEN_X86_EMU_VGA)
> +#define has_viommu(d) ((d)->arch.emulation_flags & XEN_X86_EMU_IOMMU)
It might be an idea to wrap these with (!! ...) to turn them into proper
boolean values.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-05 9:34 ` Andrew Cooper
@ 2015-10-05 16:40 ` Roger Pau Monné
2015-10-05 16:43 ` Andrew Cooper
2015-10-06 11:05 ` George Dunlap
1 sibling, 1 reply; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-05 16:40 UTC (permalink / raw)
To: Andrew Cooper, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Ian Jackson, Jan Beulich
El 05/10/15 a les 11.34, Andrew Cooper ha escrit:
> On 02/10/15 16:48, 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>
>> 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: Jan Beulich <jbeulich@suse.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>> Cc: George Dunlap <george.dunlap@eu.citrix.com>
>
> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, with 2 small
> suggestions.
>
>> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
>> index 5ffa1a1..aeb911e 100644
>> --- a/xen/common/schedule.c
>> +++ b/xen/common/schedule.c
>> @@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
>> /* Initialise the data structures. */
>> void __init scheduler_init(void)
>> {
>> +#ifdef CONFIG_X86
>> + struct xen_arch_domainconfig config = { .emulation_flags = 0 };
>> +#endif
>> struct domain *idle_domain;
>> int i;
>>
>> @@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
>> sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
>> }
>>
>> - /* There is no need of arch-specific configuration for an idle domain */
>> +#ifdef CONFIG_X86
>> + idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
>> +#else
>> idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
>> +#endif
>
> You could get away without this ifdefary if you have
>
> #else
> void *config = NULL;
But then the above chunk would become:
#ifdef CONFIG_X86
struct xen_arch_domainconfig x86_config = { .emulation_flags = 0 };
void *config = &x86_config;
#else
void *config = NULL;
#endif
and the call to domain_create would be:
idle_domain = domain_create(DOMID_IDLE, 0, 0, config);
TBH I don't mind either way.
>
> In the previous hunk.
>
>> BUG_ON(IS_ERR(idle_domain));
>> idle_domain->vcpu = idle_vcpu;
>> idle_domain->max_vcpus = nr_cpu_ids;
>> diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
>> index f1d7ed6..84ae4c1 100644
>> --- a/xen/include/asm-x86/domain.h
>> +++ b/xen/include/asm-x86/domain.h
>> @@ -387,8 +387,20 @@ struct arch_domain
>> /* Mem_access emulation control */
>> bool_t mem_access_emulate_enabled;
>> bool_t mem_access_emulate_each_rep;
>> +
>> + /* 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_vvga(d) ((d)->arch.emulation_flags & XEN_X86_EMU_VGA)
>> +#define has_viommu(d) ((d)->arch.emulation_flags & XEN_X86_EMU_IOMMU)
>
> It might be an idea to wrap these with (!! ...) to turn them into proper
> boolean values.
Thanks for catching this, will fix.
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-05 16:40 ` Roger Pau Monné
@ 2015-10-05 16:43 ` Andrew Cooper
0 siblings, 0 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-10-05 16:43 UTC (permalink / raw)
To: Roger Pau Monné, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Ian Jackson, Jan Beulich
On 05/10/15 17:40, Roger Pau Monné wrote:
> El 05/10/15 a les 11.34, Andrew Cooper ha escrit:
>> On 02/10/15 16:48, 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>
>>> 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: Jan Beulich <jbeulich@suse.com>
>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>> Cc: George Dunlap <george.dunlap@eu.citrix.com>
>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, with 2 small
>> suggestions.
>>
>>> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
>>> index 5ffa1a1..aeb911e 100644
>>> --- a/xen/common/schedule.c
>>> +++ b/xen/common/schedule.c
>>> @@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
>>> /* Initialise the data structures. */
>>> void __init scheduler_init(void)
>>> {
>>> +#ifdef CONFIG_X86
>>> + struct xen_arch_domainconfig config = { .emulation_flags = 0 };
>>> +#endif
>>> struct domain *idle_domain;
>>> int i;
>>>
>>> @@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
>>> sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
>>> }
>>>
>>> - /* There is no need of arch-specific configuration for an idle domain */
>>> +#ifdef CONFIG_X86
>>> + idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
>>> +#else
>>> idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
>>> +#endif
>> You could get away without this ifdefary if you have
>>
>> #else
>> void *config = NULL;
> But then the above chunk would become:
>
> #ifdef CONFIG_X86
> struct xen_arch_domainconfig x86_config = { .emulation_flags = 0 };
> void *config = &x86_config;
You can be more sneaky than that if you wish.
struct xen_arch_domainconfig config[1] = { { .emulation_flags = 0 } };
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-05 9:34 ` Andrew Cooper
2015-10-05 16:40 ` Roger Pau Monné
@ 2015-10-06 11:05 ` George Dunlap
2015-10-07 11:55 ` Roger Pau Monné
1 sibling, 1 reply; 105+ messages in thread
From: George Dunlap @ 2015-10-06 11:05 UTC (permalink / raw)
To: Andrew Cooper, Roger Pau Monne, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Ian Jackson, Jan Beulich
On 05/10/15 10:34, Andrew Cooper wrote:
> On 02/10/15 16:48, 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>
>> 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: Jan Beulich <jbeulich@suse.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>> Cc: George Dunlap <george.dunlap@eu.citrix.com>
>
> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, with 2 small
> suggestions.
>
>> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
>> index 5ffa1a1..aeb911e 100644
>> --- a/xen/common/schedule.c
>> +++ b/xen/common/schedule.c
>> @@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
>> /* Initialise the data structures. */
>> void __init scheduler_init(void)
>> {
>> +#ifdef CONFIG_X86
>> + struct xen_arch_domainconfig config = { .emulation_flags = 0 };
>> +#endif
>> struct domain *idle_domain;
>> int i;
>>
>> @@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
>> sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
>> }
>>
>> - /* There is no need of arch-specific configuration for an idle domain */
>> +#ifdef CONFIG_X86
>> + idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
>> +#else
>> idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
>> +#endif
>
> You could get away without this ifdefary if you have
>
> #else
> void *config = NULL;
>
> In the previous hunk.
It would be even better if you could do what arm does, and accept NULL
configurations for the idle, xen, io, and cow domains.
-George
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-06 11:05 ` George Dunlap
@ 2015-10-07 11:55 ` Roger Pau Monné
2015-10-07 12:15 ` Jan Beulich
2015-10-07 13:32 ` George Dunlap
0 siblings, 2 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-07 11:55 UTC (permalink / raw)
To: George Dunlap, Andrew Cooper, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Ian Jackson, Jan Beulich
El 06/10/15 a les 13.05, George Dunlap ha escrit:
> On 05/10/15 10:34, Andrew Cooper wrote:
>> On 02/10/15 16:48, 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>
>>> 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: Jan Beulich <jbeulich@suse.com>
>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>> Cc: George Dunlap <george.dunlap@eu.citrix.com>
>>
>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, with 2 small
>> suggestions.
>>
>>> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
>>> index 5ffa1a1..aeb911e 100644
>>> --- a/xen/common/schedule.c
>>> +++ b/xen/common/schedule.c
>>> @@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
>>> /* Initialise the data structures. */
>>> void __init scheduler_init(void)
>>> {
>>> +#ifdef CONFIG_X86
>>> + struct xen_arch_domainconfig config = { .emulation_flags = 0 };
>>> +#endif
>>> struct domain *idle_domain;
>>> int i;
>>>
>>> @@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
>>> sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
>>> }
>>>
>>> - /* There is no need of arch-specific configuration for an idle domain */
>>> +#ifdef CONFIG_X86
>>> + idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
>>> +#else
>>> idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
>>> +#endif
>>
>> You could get away without this ifdefary if you have
>>
>> #else
>> void *config = NULL;
>>
>> In the previous hunk.
>
> It would be even better if you could do what arm does, and accept NULL
> configurations for the idle, xen, io, and cow domains.
I'm not sure of that. HVM domains certainly require config to be
provided, while PV domains could do without it. IMHO it's better for
consistency of interfaces to always require a valid arch config rather
than make it depend on the domain type.
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-07 11:55 ` Roger Pau Monné
@ 2015-10-07 12:15 ` Jan Beulich
2015-10-07 13:32 ` George Dunlap
1 sibling, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2015-10-07 12:15 UTC (permalink / raw)
To: George Dunlap, Roger Pau Monné
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Andrew Cooper, Ian Jackson, xen-devel
>>> On 07.10.15 at 13:55, <roger.pau@citrix.com> wrote:
> El 06/10/15 a les 13.05, George Dunlap ha escrit:
>> On 05/10/15 10:34, Andrew Cooper wrote:
>>> On 02/10/15 16:48, Roger Pau Monne wrote:
>>>> --- a/xen/common/schedule.c
>>>> +++ b/xen/common/schedule.c
>>>> @@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
>>>> /* Initialise the data structures. */
>>>> void __init scheduler_init(void)
>>>> {
>>>> +#ifdef CONFIG_X86
>>>> + struct xen_arch_domainconfig config = { .emulation_flags = 0 };
>>>> +#endif
>>>> struct domain *idle_domain;
>>>> int i;
>>>>
>>>> @@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
>>>> sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
>>>> }
>>>>
>>>> - /* There is no need of arch-specific configuration for an idle domain */
>>>> +#ifdef CONFIG_X86
>>>> + idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
>>>> +#else
>>>> idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
>>>> +#endif
>>>
>>> You could get away without this ifdefary if you have
>>>
>>> #else
>>> void *config = NULL;
>>>
>>> In the previous hunk.
>>
>> It would be even better if you could do what arm does, and accept NULL
>> configurations for the idle, xen, io, and cow domains.
>
> I'm not sure of that. HVM domains certainly require config to be
> provided, while PV domains could do without it. IMHO it's better for
> consistency of interfaces to always require a valid arch config rather
> than make it depend on the domain type.
FWIW, I agree with George's view here.
Jan
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-07 11:55 ` Roger Pau Monné
2015-10-07 12:15 ` Jan Beulich
@ 2015-10-07 13:32 ` George Dunlap
2015-10-07 14:01 ` Andrew Cooper
1 sibling, 1 reply; 105+ messages in thread
From: George Dunlap @ 2015-10-07 13:32 UTC (permalink / raw)
To: Roger Pau Monné, Andrew Cooper, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Ian Jackson, Jan Beulich
On 07/10/15 12:55, Roger Pau Monné wrote:
> El 06/10/15 a les 13.05, George Dunlap ha escrit:
>> On 05/10/15 10:34, Andrew Cooper wrote:
>>> On 02/10/15 16:48, 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>
>>>> 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: Jan Beulich <jbeulich@suse.com>
>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>> Cc: George Dunlap <george.dunlap@eu.citrix.com>
>>>
>>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, with 2 small
>>> suggestions.
>>>
>>>> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
>>>> index 5ffa1a1..aeb911e 100644
>>>> --- a/xen/common/schedule.c
>>>> +++ b/xen/common/schedule.c
>>>> @@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
>>>> /* Initialise the data structures. */
>>>> void __init scheduler_init(void)
>>>> {
>>>> +#ifdef CONFIG_X86
>>>> + struct xen_arch_domainconfig config = { .emulation_flags = 0 };
>>>> +#endif
>>>> struct domain *idle_domain;
>>>> int i;
>>>>
>>>> @@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
>>>> sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
>>>> }
>>>>
>>>> - /* There is no need of arch-specific configuration for an idle domain */
>>>> +#ifdef CONFIG_X86
>>>> + idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
>>>> +#else
>>>> idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
>>>> +#endif
>>>
>>> You could get away without this ifdefary if you have
>>>
>>> #else
>>> void *config = NULL;
>>>
>>> In the previous hunk.
>>
>> It would be even better if you could do what arm does, and accept NULL
>> configurations for the idle, xen, io, and cow domains.
>
> I'm not sure of that. HVM domains certainly require config to be
> provided, while PV domains could do without it. IMHO it's better for
> consistency of interfaces to always require a valid arch config rather
> than make it depend on the domain type.
ARM requires a config for all *real* domains -- including all guests and
dom0; there's an ASSERT in xen/arm/domain.c:arch_domain_create() to that
effect. Nonetheless, it accepts NULL for the four "domains" I mentioned
above, because they aren't real domains. Consistency says it would be
better if x86 behaved like arm (requiring config for real HVM and PV
domains, but not for fake domains).
-George
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-07 13:32 ` George Dunlap
@ 2015-10-07 14:01 ` Andrew Cooper
2015-10-08 9:13 ` Roger Pau Monné
0 siblings, 1 reply; 105+ messages in thread
From: Andrew Cooper @ 2015-10-07 14:01 UTC (permalink / raw)
To: George Dunlap, Roger Pau Monné, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Ian Jackson, Jan Beulich
On 07/10/15 14:32, George Dunlap wrote:
> On 07/10/15 12:55, Roger Pau Monné wrote:
>> El 06/10/15 a les 13.05, George Dunlap ha escrit:
>>> On 05/10/15 10:34, Andrew Cooper wrote:
>>>> On 02/10/15 16:48, 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>
>>>>> 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: Jan Beulich <jbeulich@suse.com>
>>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>>> Cc: George Dunlap <george.dunlap@eu.citrix.com>
>>>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, with 2 small
>>>> suggestions.
>>>>
>>>>> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
>>>>> index 5ffa1a1..aeb911e 100644
>>>>> --- a/xen/common/schedule.c
>>>>> +++ b/xen/common/schedule.c
>>>>> @@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
>>>>> /* Initialise the data structures. */
>>>>> void __init scheduler_init(void)
>>>>> {
>>>>> +#ifdef CONFIG_X86
>>>>> + struct xen_arch_domainconfig config = { .emulation_flags = 0 };
>>>>> +#endif
>>>>> struct domain *idle_domain;
>>>>> int i;
>>>>>
>>>>> @@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
>>>>> sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
>>>>> }
>>>>>
>>>>> - /* There is no need of arch-specific configuration for an idle domain */
>>>>> +#ifdef CONFIG_X86
>>>>> + idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
>>>>> +#else
>>>>> idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
>>>>> +#endif
>>>> You could get away without this ifdefary if you have
>>>>
>>>> #else
>>>> void *config = NULL;
>>>>
>>>> In the previous hunk.
>>> It would be even better if you could do what arm does, and accept NULL
>>> configurations for the idle, xen, io, and cow domains.
>> I'm not sure of that. HVM domains certainly require config to be
>> provided, while PV domains could do without it. IMHO it's better for
>> consistency of interfaces to always require a valid arch config rather
>> than make it depend on the domain type.
> ARM requires a config for all *real* domains -- including all guests and
> dom0; there's an ASSERT in xen/arm/domain.c:arch_domain_create() to that
> effect. Nonetheless, it accepts NULL for the four "domains" I mentioned
> above, because they aren't real domains. Consistency says it would be
> better if x86 behaved like arm (requiring config for real HVM and PV
> domains, but not for fake domains).
I have to say that I am leaning towards the same opinion.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-07 14:01 ` Andrew Cooper
@ 2015-10-08 9:13 ` Roger Pau Monné
0 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-08 9:13 UTC (permalink / raw)
To: Andrew Cooper, George Dunlap, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Ian Jackson, Jan Beulich
El 07/10/15 a les 16.01, Andrew Cooper ha escrit:
> On 07/10/15 14:32, George Dunlap wrote:
>> On 07/10/15 12:55, Roger Pau Monné wrote:
>>> El 06/10/15 a les 13.05, George Dunlap ha escrit:
>>>> On 05/10/15 10:34, Andrew Cooper wrote:
>>>>> On 02/10/15 16:48, 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>
>>>>>> 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: Jan Beulich <jbeulich@suse.com>
>>>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>>>> Cc: George Dunlap <george.dunlap@eu.citrix.com>
>>>>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, with 2 small
>>>>> suggestions.
>>>>>
>>>>>> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
>>>>>> index 5ffa1a1..aeb911e 100644
>>>>>> --- a/xen/common/schedule.c
>>>>>> +++ b/xen/common/schedule.c
>>>>>> @@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
>>>>>> /* Initialise the data structures. */
>>>>>> void __init scheduler_init(void)
>>>>>> {
>>>>>> +#ifdef CONFIG_X86
>>>>>> + struct xen_arch_domainconfig config = { .emulation_flags = 0 };
>>>>>> +#endif
>>>>>> struct domain *idle_domain;
>>>>>> int i;
>>>>>>
>>>>>> @@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
>>>>>> sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
>>>>>> }
>>>>>>
>>>>>> - /* There is no need of arch-specific configuration for an idle domain */
>>>>>> +#ifdef CONFIG_X86
>>>>>> + idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
>>>>>> +#else
>>>>>> idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
>>>>>> +#endif
>>>>> You could get away without this ifdefary if you have
>>>>>
>>>>> #else
>>>>> void *config = NULL;
>>>>>
>>>>> In the previous hunk.
>>>> It would be even better if you could do what arm does, and accept NULL
>>>> configurations for the idle, xen, io, and cow domains.
>>> I'm not sure of that. HVM domains certainly require config to be
>>> provided, while PV domains could do without it. IMHO it's better for
>>> consistency of interfaces to always require a valid arch config rather
>>> than make it depend on the domain type.
>> ARM requires a config for all *real* domains -- including all guests and
>> dom0; there's an ASSERT in xen/arm/domain.c:arch_domain_create() to that
>> effect. Nonetheless, it accepts NULL for the four "domains" I mentioned
>> above, because they aren't real domains. Consistency says it would be
>> better if x86 behaved like arm (requiring config for real HVM and PV
>> domains, but not for fake domains).
>
> I have to say that I am leaning towards the same opinion.
Ack, I also prefer this way if ARM already does it.
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-02 15:48 ` [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices Roger Pau Monne
2015-10-05 9:34 ` Andrew Cooper
@ 2015-10-08 10:23 ` Jan Beulich
2015-10-08 10:35 ` Roger Pau Monné
2015-10-15 1:48 ` Boris Ostrovsky
2 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-10-08 10:23 UTC (permalink / raw)
To: Roger Pau Monne
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Andrew Cooper, Ian Jackson, xen-devel
>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
> @@ -517,6 +520,22 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
> d->domain_id);
> }
>
> + if ( (config->emulation_flags & ~XEN_X86_EMU_ALL) != 0 )
> + {
> + printk(XENLOG_G_ERR "d%d: Invalid emulation bitmap: %#x\n",
> + d->domain_id, config->emulation_flags);
> + return -EINVAL;
> + }
> + if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL) ||
> + (is_pv_domain(d) && config->emulation_flags != 0) )
How about PVH? At this point of the series I'm sure it also needs all flags
clear? In which case this should become
if ( is_hvm_domain(d) ? (config->emulation_flags != XEN_X86_EMU_ALL)
: (config->emulation_flags != 0) )
Jan
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-08 10:23 ` Jan Beulich
@ 2015-10-08 10:35 ` Roger Pau Monné
0 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-08 10:35 UTC (permalink / raw)
To: Jan Beulich
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Andrew Cooper, Ian Jackson, xen-devel
El 08/10/15 a les 12.23, Jan Beulich ha escrit:
>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>> @@ -517,6 +520,22 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
>> d->domain_id);
>> }
>>
>> + if ( (config->emulation_flags & ~XEN_X86_EMU_ALL) != 0 )
>> + {
>> + printk(XENLOG_G_ERR "d%d: Invalid emulation bitmap: %#x\n",
>> + d->domain_id, config->emulation_flags);
>> + return -EINVAL;
>> + }
>> + if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL) ||
>> + (is_pv_domain(d) && config->emulation_flags != 0) )
>
> How about PVH? At this point of the series I'm sure it also needs all flags
> clear? In which case this should become
>
> if ( is_hvm_domain(d) ? (config->emulation_flags != XEN_X86_EMU_ALL)
> : (config->emulation_flags != 0) )
Right, PVH domains return false for both is_hvm_domain and is_pv_domain.
Roger.
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-02 15:48 ` [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices Roger Pau Monne
2015-10-05 9:34 ` Andrew Cooper
2015-10-08 10:23 ` Jan Beulich
@ 2015-10-15 1:48 ` Boris Ostrovsky
2015-10-15 7:34 ` Jan Beulich
2015-10-30 12:00 ` Roger Pau Monné
2 siblings, 2 replies; 105+ messages in thread
From: Boris Ostrovsky @ 2015-10-15 1:48 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Andrew Cooper, Ian Jackson, Jan Beulich
On 10/02/2015 11:48 AM, 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.
>
...
> diff --git a/xen/include/public/arch-x86/xen.h b/xen/include/public/arch-x86/xen.h
> index 2ecc9c9..c97a9b4 100644
> --- a/xen/include/public/arch-x86/xen.h
> +++ b/xen/include/public/arch-x86/xen.h
> @@ -268,7 +268,28 @@ 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_VGA 6
> +#define XEN_X86_EMU_VGA (1U<<_XEN_X86_EMU_VGA)
> +#define _XEN_X86_EMU_IOMMU 7
> +#define XEN_X86_EMU_IOMMU (1U<<_XEN_X86_EMU_IOMMU)
What about PIT? Should we (initially) disable it as well?
I (by mistake) enabled it in my guest and crashed the hypervisor due to
unprotected access to vlapic in pt_update_irq(). I started fixing it but
then realized that perhaps we shouldn't have PIT at all. Which did solve
my problems.
(Regardless of whether we have PIT we should probably guard
vlapic_accept_pit_interrupt() in pit_irq_masked() with has_vlapic())
-boris
> +
> +#define XEN_X86_EMU_ALL (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_VGA | XEN_X86_EMU_IOMMU)
> + uint32_t emulation_flags;
> };
> #endif
>
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-15 1:48 ` Boris Ostrovsky
@ 2015-10-15 7:34 ` Jan Beulich
2015-10-30 12:00 ` Roger Pau Monné
1 sibling, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2015-10-15 7:34 UTC (permalink / raw)
To: Roger Pau Monne, Boris Ostrovsky
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Andrew Cooper, Ian Jackson, xen-devel
>>> On 15.10.15 at 03:48, <boris.ostrovsky@oracle.com> wrote:
> On 10/02/2015 11:48 AM, Roger Pau Monne wrote:
>> --- a/xen/include/public/arch-x86/xen.h
>> +++ b/xen/include/public/arch-x86/xen.h
>> @@ -268,7 +268,28 @@ 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_VGA 6
>> +#define XEN_X86_EMU_VGA (1U<<_XEN_X86_EMU_VGA)
>> +#define _XEN_X86_EMU_IOMMU 7
>> +#define XEN_X86_EMU_IOMMU (1U<<_XEN_X86_EMU_IOMMU)
>
> What about PIT? Should we (initially) disable it as well?
Definitely - good that you spotted it missing.
Jan
> I (by mistake) enabled it in my guest and crashed the hypervisor due to
> unprotected access to vlapic in pt_update_irq(). I started fixing it but
> then realized that perhaps we shouldn't have PIT at all. Which did solve
> my problems.
>
> (Regardless of whether we have PIT we should probably guard
> vlapic_accept_pit_interrupt() in pit_irq_masked() with has_vlapic())
>
> -boris
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices
2015-10-15 1:48 ` Boris Ostrovsky
2015-10-15 7:34 ` Jan Beulich
@ 2015-10-30 12:00 ` Roger Pau Monné
1 sibling, 0 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-30 12:00 UTC (permalink / raw)
To: Boris Ostrovsky, xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, George Dunlap,
Andrew Cooper, Ian Jackson, Jan Beulich
El 15/10/15 a les 3.48, Boris Ostrovsky ha escrit:
> On 10/02/2015 11:48 AM, 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.
>>
>
> ...
>
>> diff --git a/xen/include/public/arch-x86/xen.h
>> b/xen/include/public/arch-x86/xen.h
>> index 2ecc9c9..c97a9b4 100644
>> --- a/xen/include/public/arch-x86/xen.h
>> +++ b/xen/include/public/arch-x86/xen.h
>> @@ -268,7 +268,28 @@ 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_VGA 6
>> +#define XEN_X86_EMU_VGA (1U<<_XEN_X86_EMU_VGA)
>> +#define _XEN_X86_EMU_IOMMU 7
>> +#define XEN_X86_EMU_IOMMU (1U<<_XEN_X86_EMU_IOMMU)
>
> What about PIT? Should we (initially) disable it as well?
>
> I (by mistake) enabled it in my guest and crashed the hypervisor due to
> unprotected access to vlapic in pt_update_irq(). I started fixing it but
> then realized that perhaps we shouldn't have PIT at all. Which did solve
> my problems.
Right, thanks for catching this!
> (Regardless of whether we have PIT we should probably guard
> vlapic_accept_pit_interrupt() in pit_irq_masked() with has_vlapic())
I'm not able to find any of the functions you reference in the paragraph
above in the Xen source code.
Roger.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (11 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 18:23 ` Andrew Cooper
` (2 more replies)
2015-10-02 15:48 ` [PATCH v7 14/32] xen/x86: allow disabling the emulated local apic Roger Pau Monne
` (19 subsequent siblings)
32 siblings, 3 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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
The HVM related code (SVM, VMX) generally assumed that a local apic is
always present. With the introduction of a HVM mode were the local apic can
be removed, some of this broken code paths arised.
The SVM exit/resume paths unconditionally checked the state of the lapic,
which is wrong if it's been disabled by hardware, fix this by adding the
necessary checks. On the VMX side, make sure we don't add mappings for a
local apic if it's disabled.
In the generic vlapic code, add checks to prevent setting the TSC deadline
timer if the lapic is disabled, and also prevent trying to inject interrupts
from the PIC is the lapic is also disabled.
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 | 18 ++++++++++--------
xen/arch/x86/hvm/vlapic.c | 7 ++++++-
xen/arch/x86/hvm/vmx/vmx.c | 3 ++-
3 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 8de41fa..404634b 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,12 @@ 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 +2700,13 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
}
out:
- if ( vcpu_guestmode )
- /* Don't clobber TPR of the nested guest. */
+ if ( vcpu_guestmode || vlapic_hw_disabled(vlapic) )
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..229f122 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -1042,7 +1042,9 @@ 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_hw_disabled(vlapic) )
+ return;
+
if ( !vlapic_lvtt_tdt(vlapic) )
{
HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "ignore tsc deadline msr write");
@@ -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 -ENODEV;
+
TRACE_2D(TRC_HVM_EMUL_LAPIC_PIC_INTR,
(v == v->domain->arch.hvm_domain.i8259_target),
v ? __vlapic_accept_pic_intr(v) : -1);
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index bbec0e8..63b7a24 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2412,7 +2412,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] 105+ messages in thread
* Re: [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic
2015-10-02 15:48 ` [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic Roger Pau Monne
@ 2015-10-02 18:23 ` Andrew Cooper
2015-10-05 10:14 ` Jan Beulich
2015-10-02 20:33 ` Boris Ostrovsky
2015-10-08 10:36 ` Jan Beulich
2 siblings, 1 reply; 105+ messages in thread
From: Andrew Cooper @ 2015-10-02 18:23 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 02/10/15 16:48, Roger Pau Monne wrote:
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index bbec0e8..63b7a24 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -2412,7 +2412,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 )
0 is a valid (albeit very unlikely) mfn. The unused sentinel value
should be INVALID_MFN. It appears that all the current uses of
apic_access_mfn are buggy.
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic
2015-10-02 18:23 ` Andrew Cooper
@ 2015-10-05 10:14 ` Jan Beulich
0 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2015-10-05 10:14 UTC (permalink / raw)
To: Andrew Cooper
Cc: Kevin Tian, Suravee Suthikulpanit, Eddie Dong,
Aravind Gopalakrishnan, JunNakajima, xen-devel, Boris Ostrovsky,
Roger Pau Monne
>>> On 02.10.15 at 20:23, <andrew.cooper3@citrix.com> wrote:
> On 02/10/15 16:48, Roger Pau Monne wrote:
>> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
>> index bbec0e8..63b7a24 100644
>> --- a/xen/arch/x86/hvm/vmx/vmx.c
>> +++ b/xen/arch/x86/hvm/vmx/vmx.c
>> @@ -2412,7 +2412,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 )
>
> 0 is a valid (albeit very unlikely) mfn. The unused sentinel value
> should be INVALID_MFN. It appears that all the current uses of
> apic_access_mfn are buggy.
>From a purely theoretical pov 0 is indeed a valid MFN. However,
on x86 we don't hand memory below 1M to the allocator, so this
is only theoretically (or one could call it latently) buggy.
Jan
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic
2015-10-02 15:48 ` [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic Roger Pau Monne
2015-10-02 18:23 ` Andrew Cooper
@ 2015-10-02 20:33 ` Boris Ostrovsky
2015-10-08 10:36 ` Jan Beulich
2 siblings, 0 replies; 105+ messages in thread
From: Boris Ostrovsky @ 2015-10-02 20:33 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel
Cc: Kevin Tian, Jan Beulich, Andrew Cooper, Eddie Dong,
Aravind Gopalakrishnan, Jun Nakajima, Suravee Suthikulpanit
On 10/02/2015 11:48 AM, Roger Pau Monne wrote:
> The HVM related code (SVM, VMX) generally assumed that a local apic is
> always present. With the introduction of a HVM mode were the local apic can
> be removed, some of this broken code paths arised.
>
> The SVM exit/resume paths unconditionally checked the state of the lapic,
> which is wrong if it's been disabled by hardware, fix this by adding the
> necessary checks. On the VMX side, make sure we don't add mappings for a
> local apic if it's disabled.
>
> In the generic vlapic code, add checks to prevent setting the TSC deadline
> timer if the lapic is disabled, and also prevent trying to inject interrupts
> from the PIC is the lapic is also disabled.
>
> 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 | 18 ++++++++++--------
> xen/arch/x86/hvm/vlapic.c | 7 ++++++-
> xen/arch/x86/hvm/vmx/vmx.c | 3 ++-
> 3 files changed, 18 insertions(+), 10 deletions(-)
>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic
2015-10-02 15:48 ` [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic Roger Pau Monne
2015-10-02 18:23 ` Andrew Cooper
2015-10-02 20:33 ` Boris Ostrovsky
@ 2015-10-08 10:36 ` Jan Beulich
2 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2015-10-08 10:36 UTC (permalink / raw)
To: Roger Pau Monne
Cc: Kevin Tian, Suravee Suthikulpanit, AndrewCooper, Eddie Dong,
Aravind Gopalakrishnan, Jun Nakajima, xen-devel, Boris Ostrovsky
>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -2412,7 +2412,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;
Considering that when cpu_has_vmx_virtualize_apic_accesses
this field will always be non-zero by the time we get here, I think
you'd better replace the original condition than amend it.
Jan
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 14/32] xen/x86: allow disabling the emulated local apic
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (12 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 13/32] xen/vlapic: fixes for HVM code when running without a vlapic Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-05 9:41 ` Andrew Cooper
2015-10-14 14:33 ` Jan Beulich
2015-10-02 15:48 ` [PATCH v7 15/32] xen/x86: allow disabling the emulated HPET Roger Pau Monne
` (18 subsequent siblings)
32 siblings, 2 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel
Cc: Kevin Tian, Jan Beulich, Andrew Cooper, Eddie Dong, Jun Nakajima,
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>
Cc: Jun Nakajima <jun.nakajima@intel.com>
Cc: Eddie Dong <eddie.dong@intel.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
Changes since v6:
- Remove stall comments.
- Adds checks for has_vlapic in the msixtbl_pt_{un}register functions.
- Simplify the is_pvh_domain(d) || !has_vlapic(d) to !has_vlapic(d) when
appropriate.
- Split parts of this patch that can be considered bug fixes to a
pre-patch.
- Removed Acks since the patch changed substantially.
Changes since v5:
- Add Boris Ostrovsky Reviewed-by.
Changes since v4:
- Split the is_pvh_domain check into two, so part of the code can be shared
with the !has_lapic case.
- Add Andrew Cooper Acked-by.
---
xen/arch/x86/hvm/vlapic.c | 27 ++++++++++++++++++++++++---
xen/arch/x86/hvm/vmsi.c | 12 ++++++++++++
xen/arch/x86/hvm/vmx/vmcs.c | 5 ++++-
xen/arch/x86/hvm/vmx/vmx.c | 6 ++++++
4 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index 229f122..f8a84d5 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 -ENODEV;
+
if ( (vlapic->hw.apic_base_msr ^ value) & MSR_IA32_APICBASE_ENABLE )
{
if ( unlikely(value & MSR_IA32_APICBASE_EXTD) )
@@ -1205,6 +1208,9 @@ void vlapic_reset(struct vlapic *vlapic)
struct vcpu *v = vlapic_vcpu(vlapic);
int i;
+ if ( !has_vlapic(v->domain) )
+ return;
+
vlapic_set_reg(vlapic, APIC_ID, (v->vcpu_id * 2) << 24);
vlapic_set_reg(vlapic, APIC_LVR, VLAPIC_VERSION);
@@ -1270,6 +1276,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);
@@ -1286,6 +1295,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 )
@@ -1333,7 +1345,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 -ENODEV;
+
/* Which vlapic to load? */
vcpuid = hvm_load_instance(h);
if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
@@ -1365,7 +1380,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 -ENODEV;
+
/* Which vlapic to load? */
vcpuid = hvm_load_instance(h);
if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
@@ -1404,7 +1422,7 @@ int vlapic_init(struct vcpu *v)
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id);
- if ( is_pvh_vcpu(v) )
+ if ( !has_vlapic(v->domain) )
{
vlapic->hw.disabled = VLAPIC_HW_DISABLED;
return 0;
@@ -1457,6 +1475,9 @@ void vlapic_destroy(struct vcpu *v)
{
struct vlapic *vlapic = vcpu_vlapic(v);
+ if ( !has_vlapic(v->domain) )
+ 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..499151e 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -391,6 +391,9 @@ int msixtbl_pt_register(struct domain *d, struct pirq *pirq, uint64_t gtable)
ASSERT(spin_is_locked(&pcidevs_lock));
ASSERT(spin_is_locked(&d->event_lock));
+ if ( !has_vlapic(d) )
+ return -ENODEV;
+
/*
* xmalloc() with irq_disabled causes the failure of check_lock()
* for xenpool->lock. So we allocate an entry beforehand.
@@ -446,6 +449,9 @@ void msixtbl_pt_unregister(struct domain *d, struct pirq *pirq)
ASSERT(spin_is_locked(&pcidevs_lock));
ASSERT(spin_is_locked(&d->event_lock));
+ if ( !has_vlapic(d) )
+ return;
+
irq_desc = pirq_spin_lock_irq_desc(pirq, NULL);
if ( !irq_desc )
return;
@@ -482,6 +488,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 +502,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 15b136b..42f703a 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1002,7 +1002,7 @@ static int construct_vmcs(struct vcpu *v)
~(SECONDARY_EXEC_ENABLE_VM_FUNCTIONS |
SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS);
- if ( is_pvh_domain(d) )
+ if ( !has_vlapic(d) )
{
/* Disable virtual apics, TPR */
v->arch.hvm_vmx.secondary_exec_control &=
@@ -1014,7 +1014,10 @@ static int construct_vmcs(struct vcpu *v)
/* 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;
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 63b7a24..95e787e 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);
}
--
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] 105+ messages in thread
* Re: [PATCH v7 14/32] xen/x86: allow disabling the emulated local apic
2015-10-02 15:48 ` [PATCH v7 14/32] xen/x86: allow disabling the emulated local apic Roger Pau Monne
@ 2015-10-05 9:41 ` Andrew Cooper
2015-10-14 14:33 ` Jan Beulich
1 sibling, 0 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-10-05 9:41 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel
Cc: Kevin Tian, Eddie Dong, Jun Nakajima, Jan Beulich
On 02/10/15 16:48, Roger Pau Monne wrote:
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.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>
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] 105+ messages in thread
* Re: [PATCH v7 14/32] xen/x86: allow disabling the emulated local apic
2015-10-02 15:48 ` [PATCH v7 14/32] xen/x86: allow disabling the emulated local apic Roger Pau Monne
2015-10-05 9:41 ` Andrew Cooper
@ 2015-10-14 14:33 ` Jan Beulich
1 sibling, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2015-10-14 14:33 UTC (permalink / raw)
To: Roger Pau Monne
Cc: Andrew Cooper, Kevin Tian, Eddie Dong, Jun Nakajima, xen-devel
>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
(but awaiting an update to patch 2 for it to go in)
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 15/32] xen/x86: allow disabling the emulated HPET
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (13 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 14/32] xen/x86: allow disabling the emulated local apic Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 16/32] xen/x86: allow disabling the pmtimer Roger Pau Monne
` (17 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v6:
- Return ENODEV in hpet_load if the vhpet is disabled.
Changes since v4:
- Add Andrew Cooper Acked-by.
---
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 facab83..5e020ae 100644
--- a/xen/arch/x86/hvm/hpet.c
+++ b/xen/arch/x86/hvm/hpet.c
@@ -517,6 +517,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 = (v->arch.hvm_vcpu.guest_time ?: hvm_get_guest_time(v)) /
STIME_PER_HPET_TICK;
@@ -577,6 +580,9 @@ static int hpet_load(struct domain *d, hvm_domain_context_t *h)
uint64_t guest_time;
int i;
+ if ( !has_vhpet(d) )
+ return -ENODEV;
+
write_lock(&hp->lock);
/* Reload the HPET registers */
@@ -635,6 +641,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);
@@ -662,6 +671,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)
@@ -669,6 +679,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 6afc344..b4d8475 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1603,7 +1603,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] 105+ messages in thread
* [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (14 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 15/32] xen/x86: allow disabling the emulated HPET Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-05 9:42 ` Andrew Cooper
2015-10-14 14:37 ` Jan Beulich
2015-10-02 15:48 ` [PATCH v7 17/32] xen/x86: allow disabling the emulated RTC Roger Pau Monne
` (16 subsequent siblings)
32 siblings, 2 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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>
---
Changes since v6:
- Return ENODEV in pmtimer_load if the timer is disabled.
- hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
pmtimer is disabled.
- Return ENODEV if pmtimer_change_ioport is called with the pmtimer
disabled.
- Add a check for disabled pmtimer in pmtimer_reset. Although it's safe to
execute this function now, it might change in the future.
- Drop Andrew's Ack due to the changes.
Changes since v4:
- Add Andrew Cooper Acked-by.
---
xen/arch/x86/hvm/pmtimer.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c
index c8229e0..a06d183 100644
--- a/xen/arch/x86/hvm/pmtimer.c
+++ b/xen/arch/x86/hvm/pmtimer.c
@@ -67,6 +67,10 @@ static void pmt_update_sci(PMTState *s)
void hvm_acpi_power_button(struct domain *d)
{
PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+
+ if ( !has_vpmtimer(d) )
+ return;
+
spin_lock(&s->lock);
s->pm.pm1a_sts |= PWRBTN_STS;
pmt_update_sci(s);
@@ -76,6 +80,10 @@ void hvm_acpi_power_button(struct domain *d)
void hvm_acpi_sleep_button(struct domain *d)
{
PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+
+ if ( !has_vpmtimer(d) )
+ return;
+
spin_lock(&s->lock);
s->pm.pm1a_sts |= SLPBTN_STS;
pmt_update_sci(s);
@@ -247,6 +255,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);
/*
@@ -273,6 +284,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 -ENODEV;
+
spin_lock(&s->lock);
/* Reload the registers */
@@ -301,6 +315,9 @@ int pmtimer_change_ioport(struct domain *d, unsigned int version)
{
unsigned int old_version;
+ if ( !has_vpmtimer(d) )
+ return -ENODEV;
+
/* Check that version is changing. */
old_version = d->arch.hvm_domain.params[HVM_PARAM_ACPI_IOPORTS_LOCATION];
if ( version == old_version )
@@ -330,6 +347,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;
@@ -350,11 +370,18 @@ 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);
}
void pmtimer_reset(struct domain *d)
{
+ if ( !has_vpmtimer(d) )
+ return;
+
/* Reset the counter. */
d->arch.hvm_domain.pl_time.vpmt.pm.tmr_val = 0;
}
--
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] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-10-02 15:48 ` [PATCH v7 16/32] xen/x86: allow disabling the pmtimer Roger Pau Monne
@ 2015-10-05 9:42 ` Andrew Cooper
2015-10-14 14:37 ` Jan Beulich
1 sibling, 0 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-10-05 9:42 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel; +Cc: Jan Beulich
On 02/10/15 16:48, Roger Pau Monne wrote:
> Signed-off-by: Roger Pau Monné <roger.pau@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] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-10-02 15:48 ` [PATCH v7 16/32] xen/x86: allow disabling the pmtimer Roger Pau Monne
2015-10-05 9:42 ` Andrew Cooper
@ 2015-10-14 14:37 ` Jan Beulich
2015-10-30 12:50 ` Roger Pau Monné
1 sibling, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-10-14 14:37 UTC (permalink / raw)
To: Roger Pau Monne; +Cc: Andrew Cooper, xen-devel
>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> Changes since v6:
> - Return ENODEV in pmtimer_load if the timer is disabled.
> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
> pmtimer is disabled.
But how are those two features connected? I don't think you can
assume absence of a PM block just because there's no PM timer.
Or if you want to tie them together for now, the predicate needs
to be renamed.
> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
> disabled.
Same here.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-10-14 14:37 ` Jan Beulich
@ 2015-10-30 12:50 ` Roger Pau Monné
2015-10-30 13:16 ` Jan Beulich
0 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-30 12:50 UTC (permalink / raw)
To: Jan Beulich; +Cc: Andrew Cooper, xen-devel
El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> Cc: Jan Beulich <jbeulich@suse.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> Changes since v6:
>> - Return ENODEV in pmtimer_load if the timer is disabled.
>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>> pmtimer is disabled.
>
> But how are those two features connected? I don't think you can
> assume absence of a PM block just because there's no PM timer.
> Or if you want to tie them together for now, the predicate needs
> to be renamed.
>
>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>> disabled.
>
> Same here.
What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
flags disables all PM stuff?
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-10-30 12:50 ` Roger Pau Monné
@ 2015-10-30 13:16 ` Jan Beulich
2015-10-30 15:36 ` Andrew Cooper
0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-10-30 13:16 UTC (permalink / raw)
To: Roger Pau Monné; +Cc: Andrew Cooper, xen-devel
>>> On 30.10.15 at 13:50, <roger.pau@citrix.com> wrote:
> El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>> Cc: Jan Beulich <jbeulich@suse.com>
>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>> ---
>>> Changes since v6:
>>> - Return ENODEV in pmtimer_load if the timer is disabled.
>>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>>> pmtimer is disabled.
>>
>> But how are those two features connected? I don't think you can
>> assume absence of a PM block just because there's no PM timer.
>> Or if you want to tie them together for now, the predicate needs
>> to be renamed.
>>
>>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>>> disabled.
>>
>> Same here.
>
> What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
> flags disables all PM stuff?
Ah, right, that's a reasonable option.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-10-30 13:16 ` Jan Beulich
@ 2015-10-30 15:36 ` Andrew Cooper
2015-11-03 7:21 ` Jan Beulich
0 siblings, 1 reply; 105+ messages in thread
From: Andrew Cooper @ 2015-10-30 15:36 UTC (permalink / raw)
To: Jan Beulich, Roger Pau Monné; +Cc: xen-devel
On 30/10/15 13:16, Jan Beulich wrote:
>>>> On 30.10.15 at 13:50, <roger.pau@citrix.com> wrote:
>> El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>> ---
>>>> Changes since v6:
>>>> - Return ENODEV in pmtimer_load if the timer is disabled.
>>>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>>>> pmtimer is disabled.
>>> But how are those two features connected? I don't think you can
>>> assume absence of a PM block just because there's no PM timer.
>>> Or if you want to tie them together for now, the predicate needs
>>> to be renamed.
>>>
>>>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>>>> disabled.
>>> Same here.
>> What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
>> flags disables all PM stuff?
> Ah, right, that's a reasonable option.
It still might be a nice idea to split them in two, given future work.
To support hotplug properly (cpu, ram and pci), Xen needs to inject
GPEs, which comes from part of the PM infrastructure. To support PCI
devices in the future without the whole PM infrastructure, it would be
nice to keep the split.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-10-30 15:36 ` Andrew Cooper
@ 2015-11-03 7:21 ` Jan Beulich
2015-11-03 10:57 ` Andrew Cooper
0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-11-03 7:21 UTC (permalink / raw)
To: Andrew Cooper, roger.pau; +Cc: xen-devel
>>> On 30.10.15 at 16:36, <andrew.cooper3@citrix.com> wrote:
> On 30/10/15 13:16, Jan Beulich wrote:
>>>>> On 30.10.15 at 13:50, <roger.pau@citrix.com> wrote:
>>> El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>>> ---
>>>>> Changes since v6:
>>>>> - Return ENODEV in pmtimer_load if the timer is disabled.
>>>>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>>>>> pmtimer is disabled.
>>>> But how are those two features connected? I don't think you can
>>>> assume absence of a PM block just because there's no PM timer.
>>>> Or if you want to tie them together for now, the predicate needs
>>>> to be renamed.
>>>>
>>>>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>>>>> disabled.
>>>> Same here.
>>> What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
>>> flags disables all PM stuff?
>> Ah, right, that's a reasonable option.
>
> It still might be a nice idea to split them in two, given future work.
>
> To support hotplug properly (cpu, ram and pci), Xen needs to inject
> GPEs, which comes from part of the PM infrastructure. To support PCI
> devices in the future without the whole PM infrastructure, it would be
> nice to keep the split.
Coming back to this - I'm not sure: The hotplug aspect as you
mention it should matter for Dom0 only. DomU could (and perhaps
should) use a PV interface instead.
So I'd like to suggest quite the opposite: Don't call the thing PM,
but make it more general and call it ACPI. And instead of
separating HPET, we might have this fall under ACPI as well, or
we might have a second TIMER flag, requiring both to be set
for there to be a HPET and PMTMR. This leaves open the option
of Dom0 getting ACPI enabled (despite this then being "real",
not emulated ACPI), but TIMER left off.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-11-03 7:21 ` Jan Beulich
@ 2015-11-03 10:57 ` Andrew Cooper
2015-11-03 12:41 ` Jan Beulich
0 siblings, 1 reply; 105+ messages in thread
From: Andrew Cooper @ 2015-11-03 10:57 UTC (permalink / raw)
To: Jan Beulich, roger.pau; +Cc: xen-devel
On 03/11/15 07:21, Jan Beulich wrote:
>>>> On 30.10.15 at 16:36, <andrew.cooper3@citrix.com> wrote:
>> On 30/10/15 13:16, Jan Beulich wrote:
>>>>>> On 30.10.15 at 13:50, <roger.pau@citrix.com> wrote:
>>>> El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>>>> ---
>>>>>> Changes since v6:
>>>>>> - Return ENODEV in pmtimer_load if the timer is disabled.
>>>>>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>>>>>> pmtimer is disabled.
>>>>> But how are those two features connected? I don't think you can
>>>>> assume absence of a PM block just because there's no PM timer.
>>>>> Or if you want to tie them together for now, the predicate needs
>>>>> to be renamed.
>>>>>
>>>>>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>>>>>> disabled.
>>>>> Same here.
>>>> What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
>>>> flags disables all PM stuff?
>>> Ah, right, that's a reasonable option.
>> It still might be a nice idea to split them in two, given future work.
>>
>> To support hotplug properly (cpu, ram and pci), Xen needs to inject
>> GPEs, which comes from part of the PM infrastructure. To support PCI
>> devices in the future without the whole PM infrastructure, it would be
>> nice to keep the split.
> Coming back to this - I'm not sure: The hotplug aspect as you
> mention it should matter for Dom0 only. DomU could (and perhaps
> should) use a PV interface instead.
I disagree.
All PVH guests should use the same mechanism; making a split between
dom0 and domU will only make our lives harder.
Where reasonable, we should follow what happens on native; one of the
underlying points of PVH is to have less of an impact on the guest
side. In some cases it is indeed nasty, but has the advantage of being
well understood.
>
> So I'd like to suggest quite the opposite: Don't call the thing PM,
> but make it more general and call it ACPI. And instead of
> separating HPET, we might have this fall under ACPI as well, or
> we might have a second TIMER flag, requiring both to be set
> for there to be a HPET and PMTMR. This leaves open the option
> of Dom0 getting ACPI enabled (despite this then being "real",
> not emulated ACPI), but TIMER left off.
An HPET can exist independently of other features such as ACPI. It
should have its own option.
+1 to having an ACPI option, but as indicated above, I expect it to be
used in the longterm even for domU.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-11-03 10:57 ` Andrew Cooper
@ 2015-11-03 12:41 ` Jan Beulich
2015-11-04 16:05 ` Roger Pau Monné
2015-11-05 14:12 ` Andrew Cooper
0 siblings, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2015-11-03 12:41 UTC (permalink / raw)
To: Andrew Cooper; +Cc: xen-devel, roger.pau
>>> On 03.11.15 at 11:57, <andrew.cooper3@citrix.com> wrote:
> On 03/11/15 07:21, Jan Beulich wrote:
>>>>> On 30.10.15 at 16:36, <andrew.cooper3@citrix.com> wrote:
>>> On 30/10/15 13:16, Jan Beulich wrote:
>>>>>>> On 30.10.15 at 13:50, <roger.pau@citrix.com> wrote:
>>>>> El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>>>>> ---
>>>>>>> Changes since v6:
>>>>>>> - Return ENODEV in pmtimer_load if the timer is disabled.
>>>>>>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>>>>>>> pmtimer is disabled.
>>>>>> But how are those two features connected? I don't think you can
>>>>>> assume absence of a PM block just because there's no PM timer.
>>>>>> Or if you want to tie them together for now, the predicate needs
>>>>>> to be renamed.
>>>>>>
>>>>>>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>>>>>>> disabled.
>>>>>> Same here.
>>>>> What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
>>>>> flags disables all PM stuff?
>>>> Ah, right, that's a reasonable option.
>>> It still might be a nice idea to split them in two, given future work.
>>>
>>> To support hotplug properly (cpu, ram and pci), Xen needs to inject
>>> GPEs, which comes from part of the PM infrastructure. To support PCI
>>> devices in the future without the whole PM infrastructure, it would be
>>> nice to keep the split.
>> Coming back to this - I'm not sure: The hotplug aspect as you
>> mention it should matter for Dom0 only. DomU could (and perhaps
>> should) use a PV interface instead.
>
> I disagree.
>
> All PVH guests should use the same mechanism; making a split between
> dom0 and domU will only make our lives harder.
>
> Where reasonable, we should follow what happens on native; one of the
> underlying points of PVH is to have less of an impact on the guest
> side. In some cases it is indeed nasty, but has the advantage of being
> well understood.
What meaning would ACPI have to a PVH DomU?
>> So I'd like to suggest quite the opposite: Don't call the thing PM,
>> but make it more general and call it ACPI. And instead of
>> separating HPET, we might have this fall under ACPI as well, or
>> we might have a second TIMER flag, requiring both to be set
>> for there to be a HPET and PMTMR. This leaves open the option
>> of Dom0 getting ACPI enabled (despite this then being "real",
>> not emulated ACPI), but TIMER left off.
>
> An HPET can exist independently of other features such as ACPI. It
> should have its own option.
Without ACPI there's no defined way to discover it. Doing what
Linux does - applying chipset knowledge - won't work on PVH either,
because there's no emulated chipset. Which would leave scanning
physical memory, but if there is none, none can be found.
> +1 to having an ACPI option, but as indicated above, I expect it to be
> used in the longterm even for domU.
Again - why and how?
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-11-03 12:41 ` Jan Beulich
@ 2015-11-04 16:05 ` Roger Pau Monné
2015-11-04 16:17 ` Jan Beulich
2015-11-05 14:12 ` Andrew Cooper
1 sibling, 1 reply; 105+ messages in thread
From: Roger Pau Monné @ 2015-11-04 16:05 UTC (permalink / raw)
To: Jan Beulich, Andrew Cooper; +Cc: xen-devel
El 03/11/15 a les 13.41, Jan Beulich ha escrit:
>>>> On 03.11.15 at 11:57, <andrew.cooper3@citrix.com> wrote:
>> On 03/11/15 07:21, Jan Beulich wrote:
>>>>>> On 30.10.15 at 16:36, <andrew.cooper3@citrix.com> wrote:
>>>> On 30/10/15 13:16, Jan Beulich wrote:
>>>>>>>> On 30.10.15 at 13:50, <roger.pau@citrix.com> wrote:
>>>>>> El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>>>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>>>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>>>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>>>>>> ---
>>>>>>>> Changes since v6:
>>>>>>>> - Return ENODEV in pmtimer_load if the timer is disabled.
>>>>>>>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>>>>>>>> pmtimer is disabled.
>>>>>>> But how are those two features connected? I don't think you can
>>>>>>> assume absence of a PM block just because there's no PM timer.
>>>>>>> Or if you want to tie them together for now, the predicate needs
>>>>>>> to be renamed.
>>>>>>>
>>>>>>>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>>>>>>>> disabled.
>>>>>>> Same here.
>>>>>> What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
>>>>>> flags disables all PM stuff?
>>>>> Ah, right, that's a reasonable option.
>>>> It still might be a nice idea to split them in two, given future work.
>>>>
>>>> To support hotplug properly (cpu, ram and pci), Xen needs to inject
>>>> GPEs, which comes from part of the PM infrastructure. To support PCI
>>>> devices in the future without the whole PM infrastructure, it would be
>>>> nice to keep the split.
>>> Coming back to this - I'm not sure: The hotplug aspect as you
>>> mention it should matter for Dom0 only. DomU could (and perhaps
>>> should) use a PV interface instead.
>>
>> I disagree.
>>
>> All PVH guests should use the same mechanism; making a split between
>> dom0 and domU will only make our lives harder.
>>
>> Where reasonable, we should follow what happens on native; one of the
>> underlying points of PVH is to have less of an impact on the guest
>> side. In some cases it is indeed nasty, but has the advantage of being
>> well understood.
>
> What meaning would ACPI have to a PVH DomU?
>
>>> So I'd like to suggest quite the opposite: Don't call the thing PM,
>>> but make it more general and call it ACPI. And instead of
>>> separating HPET, we might have this fall under ACPI as well, or
>>> we might have a second TIMER flag, requiring both to be set
>>> for there to be a HPET and PMTMR. This leaves open the option
>>> of Dom0 getting ACPI enabled (despite this then being "real",
>>> not emulated ACPI), but TIMER left off.
>>
>> An HPET can exist independently of other features such as ACPI. It
>> should have its own option.
>
> Without ACPI there's no defined way to discover it. Doing what
> Linux does - applying chipset knowledge - won't work on PVH either,
> because there's no emulated chipset. Which would leave scanning
> physical memory, but if there is none, none can be found.
>
>> +1 to having an ACPI option, but as indicated above, I expect it to be
>> used in the longterm even for domU.
>
> Again - why and how?
I think that at this point in the design it's not so important to have
all the XEN_X86_EMU_* properly defined. This is not a public interface,
so we can expand/reduce them whenever we want. Would it be fine, for the
time being to just have a XEN_X86_EMU_PM and control both the PM and the
PMTMR?
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-11-04 16:05 ` Roger Pau Monné
@ 2015-11-04 16:17 ` Jan Beulich
2015-11-05 14:13 ` Andrew Cooper
0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-11-04 16:17 UTC (permalink / raw)
To: Roger Pau Monné; +Cc: Andrew Cooper, xen-devel
>>> On 04.11.15 at 17:05, <roger.pau@citrix.com> wrote:
> El 03/11/15 a les 13.41, Jan Beulich ha escrit:
>>>>> On 03.11.15 at 11:57, <andrew.cooper3@citrix.com> wrote:
>>> On 03/11/15 07:21, Jan Beulich wrote:
>>>>>>> On 30.10.15 at 16:36, <andrew.cooper3@citrix.com> wrote:
>>>>> On 30/10/15 13:16, Jan Beulich wrote:
>>>>>>>>> On 30.10.15 at 13:50, <roger.pau@citrix.com> wrote:
>>>>>>> El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>>>>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>>>>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>>>>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>>>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>>>>>>> ---
>>>>>>>>> Changes since v6:
>>>>>>>>> - Return ENODEV in pmtimer_load if the timer is disabled.
>>>>>>>>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>>>>>>>>> pmtimer is disabled.
>>>>>>>> But how are those two features connected? I don't think you can
>>>>>>>> assume absence of a PM block just because there's no PM timer.
>>>>>>>> Or if you want to tie them together for now, the predicate needs
>>>>>>>> to be renamed.
>>>>>>>>
>>>>>>>>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>>>>>>>>> disabled.
>>>>>>>> Same here.
>>>>>>> What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
>>>>>>> flags disables all PM stuff?
>>>>>> Ah, right, that's a reasonable option.
>>>>> It still might be a nice idea to split them in two, given future work.
>>>>>
>>>>> To support hotplug properly (cpu, ram and pci), Xen needs to inject
>>>>> GPEs, which comes from part of the PM infrastructure. To support PCI
>>>>> devices in the future without the whole PM infrastructure, it would be
>>>>> nice to keep the split.
>>>> Coming back to this - I'm not sure: The hotplug aspect as you
>>>> mention it should matter for Dom0 only. DomU could (and perhaps
>>>> should) use a PV interface instead.
>>>
>>> I disagree.
>>>
>>> All PVH guests should use the same mechanism; making a split between
>>> dom0 and domU will only make our lives harder.
>>>
>>> Where reasonable, we should follow what happens on native; one of the
>>> underlying points of PVH is to have less of an impact on the guest
>>> side. In some cases it is indeed nasty, but has the advantage of being
>>> well understood.
>>
>> What meaning would ACPI have to a PVH DomU?
>>
>>>> So I'd like to suggest quite the opposite: Don't call the thing PM,
>>>> but make it more general and call it ACPI. And instead of
>>>> separating HPET, we might have this fall under ACPI as well, or
>>>> we might have a second TIMER flag, requiring both to be set
>>>> for there to be a HPET and PMTMR. This leaves open the option
>>>> of Dom0 getting ACPI enabled (despite this then being "real",
>>>> not emulated ACPI), but TIMER left off.
>>>
>>> An HPET can exist independently of other features such as ACPI. It
>>> should have its own option.
>>
>> Without ACPI there's no defined way to discover it. Doing what
>> Linux does - applying chipset knowledge - won't work on PVH either,
>> because there's no emulated chipset. Which would leave scanning
>> physical memory, but if there is none, none can be found.
>>
>>> +1 to having an ACPI option, but as indicated above, I expect it to be
>>> used in the longterm even for domU.
>>
>> Again - why and how?
>
> I think that at this point in the design it's not so important to have
> all the XEN_X86_EMU_* properly defined. This is not a public interface,
> so we can expand/reduce them whenever we want. Would it be fine, for the
> time being to just have a XEN_X86_EMU_PM and control both the PM and the
> PMTMR?
I think so, yes.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-11-04 16:17 ` Jan Beulich
@ 2015-11-05 14:13 ` Andrew Cooper
0 siblings, 0 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-11-05 14:13 UTC (permalink / raw)
To: Jan Beulich, Roger Pau Monné; +Cc: xen-devel
On 04/11/15 16:17, Jan Beulich wrote:
>>>> On 04.11.15 at 17:05, <roger.pau@citrix.com> wrote:
>> El 03/11/15 a les 13.41, Jan Beulich ha escrit:
>>>>>> On 03.11.15 at 11:57, <andrew.cooper3@citrix.com> wrote:
>>>> On 03/11/15 07:21, Jan Beulich wrote:
>>>>>>>> On 30.10.15 at 16:36, <andrew.cooper3@citrix.com> wrote:
>>>>>> On 30/10/15 13:16, Jan Beulich wrote:
>>>>>>>>>> On 30.10.15 at 13:50, <roger.pau@citrix.com> wrote:
>>>>>>>> El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>>>>>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>>>>>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>>>>>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>>>>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>>>>>>>> ---
>>>>>>>>>> Changes since v6:
>>>>>>>>>> - Return ENODEV in pmtimer_load if the timer is disabled.
>>>>>>>>>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>>>>>>>>>> pmtimer is disabled.
>>>>>>>>> But how are those two features connected? I don't think you can
>>>>>>>>> assume absence of a PM block just because there's no PM timer.
>>>>>>>>> Or if you want to tie them together for now, the predicate needs
>>>>>>>>> to be renamed.
>>>>>>>>>
>>>>>>>>>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>>>>>>>>>> disabled.
>>>>>>>>> Same here.
>>>>>>>> What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
>>>>>>>> flags disables all PM stuff?
>>>>>>> Ah, right, that's a reasonable option.
>>>>>> It still might be a nice idea to split them in two, given future work.
>>>>>>
>>>>>> To support hotplug properly (cpu, ram and pci), Xen needs to inject
>>>>>> GPEs, which comes from part of the PM infrastructure. To support PCI
>>>>>> devices in the future without the whole PM infrastructure, it would be
>>>>>> nice to keep the split.
>>>>> Coming back to this - I'm not sure: The hotplug aspect as you
>>>>> mention it should matter for Dom0 only. DomU could (and perhaps
>>>>> should) use a PV interface instead.
>>>> I disagree.
>>>>
>>>> All PVH guests should use the same mechanism; making a split between
>>>> dom0 and domU will only make our lives harder.
>>>>
>>>> Where reasonable, we should follow what happens on native; one of the
>>>> underlying points of PVH is to have less of an impact on the guest
>>>> side. In some cases it is indeed nasty, but has the advantage of being
>>>> well understood.
>>> What meaning would ACPI have to a PVH DomU?
>>>
>>>>> So I'd like to suggest quite the opposite: Don't call the thing PM,
>>>>> but make it more general and call it ACPI. And instead of
>>>>> separating HPET, we might have this fall under ACPI as well, or
>>>>> we might have a second TIMER flag, requiring both to be set
>>>>> for there to be a HPET and PMTMR. This leaves open the option
>>>>> of Dom0 getting ACPI enabled (despite this then being "real",
>>>>> not emulated ACPI), but TIMER left off.
>>>> An HPET can exist independently of other features such as ACPI. It
>>>> should have its own option.
>>> Without ACPI there's no defined way to discover it. Doing what
>>> Linux does - applying chipset knowledge - won't work on PVH either,
>>> because there's no emulated chipset. Which would leave scanning
>>> physical memory, but if there is none, none can be found.
>>>
>>>> +1 to having an ACPI option, but as indicated above, I expect it to be
>>>> used in the longterm even for domU.
>>> Again - why and how?
>> I think that at this point in the design it's not so important to have
>> all the XEN_X86_EMU_* properly defined. This is not a public interface,
>> so we can expand/reduce them whenever we want. Would it be fine, for the
>> time being to just have a XEN_X86_EMU_PM and control both the PM and the
>> PMTMR?
> I think so, yes.
Also +1 for now.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 16/32] xen/x86: allow disabling the pmtimer
2015-11-03 12:41 ` Jan Beulich
2015-11-04 16:05 ` Roger Pau Monné
@ 2015-11-05 14:12 ` Andrew Cooper
1 sibling, 0 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-11-05 14:12 UTC (permalink / raw)
To: Jan Beulich; +Cc: xen-devel, roger.pau
On 03/11/15 12:41, Jan Beulich wrote:
>>>> On 03.11.15 at 11:57, <andrew.cooper3@citrix.com> wrote:
>> On 03/11/15 07:21, Jan Beulich wrote:
>>>>>> On 30.10.15 at 16:36, <andrew.cooper3@citrix.com> wrote:
>>>> On 30/10/15 13:16, Jan Beulich wrote:
>>>>>>>> On 30.10.15 at 13:50, <roger.pau@citrix.com> wrote:
>>>>>> El 14/10/15 a les 16.37, Jan Beulich ha escrit:
>>>>>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>>>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>>>>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>>>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>>>>>>> ---
>>>>>>>> Changes since v6:
>>>>>>>> - Return ENODEV in pmtimer_load if the timer is disabled.
>>>>>>>> - hvm_acpi_power_button and hvm_acpi_sleep_button become noops if the
>>>>>>>> pmtimer is disabled.
>>>>>>> But how are those two features connected? I don't think you can
>>>>>>> assume absence of a PM block just because there's no PM timer.
>>>>>>> Or if you want to tie them together for now, the predicate needs
>>>>>>> to be renamed.
>>>>>>>
>>>>>>>> - Return ENODEV if pmtimer_change_ioport is called with the pmtimer
>>>>>>>> disabled.
>>>>>>> Same here.
>>>>>> What about changing XEN_X86_EMU_PMTIMER into XEN_X86_EMU_PM and this
>>>>>> flags disables all PM stuff?
>>>>> Ah, right, that's a reasonable option.
>>>> It still might be a nice idea to split them in two, given future work.
>>>>
>>>> To support hotplug properly (cpu, ram and pci), Xen needs to inject
>>>> GPEs, which comes from part of the PM infrastructure. To support PCI
>>>> devices in the future without the whole PM infrastructure, it would be
>>>> nice to keep the split.
>>> Coming back to this - I'm not sure: The hotplug aspect as you
>>> mention it should matter for Dom0 only. DomU could (and perhaps
>>> should) use a PV interface instead.
>> I disagree.
>>
>> All PVH guests should use the same mechanism; making a split between
>> dom0 and domU will only make our lives harder.
>>
>> Where reasonable, we should follow what happens on native; one of the
>> underlying points of PVH is to have less of an impact on the guest
>> side. In some cases it is indeed nasty, but has the advantage of being
>> well understood.
> What meaning would ACPI have to a PVH DomU?
Whatever is covered in the tables provided.
For hotplug, this is at minimum a PM block which can be used to inject GPEs.
>
>>> So I'd like to suggest quite the opposite: Don't call the thing PM,
>>> but make it more general and call it ACPI. And instead of
>>> separating HPET, we might have this fall under ACPI as well, or
>>> we might have a second TIMER flag, requiring both to be set
>>> for there to be a HPET and PMTMR. This leaves open the option
>>> of Dom0 getting ACPI enabled (despite this then being "real",
>>> not emulated ACPI), but TIMER left off.
>> An HPET can exist independently of other features such as ACPI. It
>> should have its own option.
> Without ACPI there's no defined way to discover it. Doing what
> Linux does - applying chipset knowledge - won't work on PVH either,
> because there's no emulated chipset. Which would leave scanning
> physical memory, but if there is none, none can be found.
In reality, the legacy HPET always lives at 0xfed00000, so only a single
MMIO read is required to locate one.
As for the Linux chipset behaviour, that reminds me that I need to do
something similar in Xen to deny MMIO access. At the moment, if the
legacy HPET is not exposed in the ACPI tables, Xen doesn't find the HPET
but Linux does, and attempts to play with interrupts. It doesn't get
very far, but the kexec environment finds itself without a timesource,
as Linux disables legacy broadcast mode.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 17/32] xen/x86: allow disabling the emulated RTC
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (15 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 16/32] xen/x86: allow disabling the pmtimer Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 18/32] xen/x86: allow disabling the emulated IO APIC Roger Pau Monne
` (15 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v6:
- Return ENODEV in rtc_load if rtc is disabled.
- Add checks to rtc_reset and rtc_update_clock to prevent calling them if
rtc is disabled.
Changes since v4:
- Add Andrew Cooper Acked-by.
---
xen/arch/x86/hvm/rtc.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/xen/arch/x86/hvm/rtc.c b/xen/arch/x86/hvm/rtc.c
index a9efeaf..d391e38 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 -ENODEV;
+
spin_lock(&s->lock);
/* Restore the registers */
@@ -780,6 +790,9 @@ void rtc_reset(struct domain *d)
{
RTCState *s = domain_vrtc(d);
+ if ( !has_vrtc(d) )
+ return;
+
TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER);
destroy_periodic_time(&s->pt);
s->period = 0;
@@ -790,6 +803,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 +836,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);
@@ -833,6 +852,9 @@ void rtc_update_clock(struct domain *d)
{
RTCState *s = domain_vrtc(d);
+ if ( !has_vrtc(d) )
+ return;
+
spin_lock(&s->lock);
s->current_tm = gmtime(get_localtime(d));
spin_unlock(&s->lock);
--
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] 105+ messages in thread
* [PATCH v7 18/32] xen/x86: allow disabling the emulated IO APIC
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (16 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 17/32] xen/x86: allow disabling the emulated RTC Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 19/32] xen/x86: allow disabling the emulated PIC Roger Pau Monne
` (14 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v6:
- Return ENODEV in ioapic_load if the ioapic is disabled.
- Add an assert to make sure vioapic_update_EOI and
vioapic_irq_positive_edge is only called when the vioapic is enabled.
Changes since v4:
- Add Andrew Cooper Acked-by.
---
xen/arch/x86/hvm/vioapic.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index d348235..611be87 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -365,6 +365,8 @@ void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
struct hvm_hw_vioapic *vioapic = domain_vioapic(d);
union vioapic_redir_entry *ent;
+ ASSERT(has_vioapic(d));
+
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "irq %x", irq);
ASSERT(irq < VIOAPIC_NUM_PINS);
@@ -392,6 +394,8 @@ void vioapic_update_EOI(struct domain *d, u8 vector)
union vioapic_redir_entry *ent;
int gsi;
+ ASSERT(has_vioapic(d));
+
spin_lock(&d->arch.hvm_domain.irq_lock);
for ( gsi = 0; gsi < VIOAPIC_NUM_PINS; gsi++ )
@@ -424,12 +428,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 -ENODEV;
+
return hvm_load_entry(IOAPIC, h, s);
}
@@ -440,6 +452,9 @@ void vioapic_reset(struct domain *d)
struct hvm_vioapic *vioapic = d->arch.hvm_domain.vioapic;
int i;
+ if ( !has_vioapic(d) )
+ return;
+
memset(&vioapic->hvm_hw_vioapic, 0, sizeof(vioapic->hvm_hw_vioapic));
for ( i = 0; i < VIOAPIC_NUM_PINS; i++ )
vioapic->hvm_hw_vioapic.redirtbl[i].fields.mask = 1;
@@ -448,6 +463,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 +480,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] 105+ messages in thread
* [PATCH v7 19/32] xen/x86: allow disabling the emulated PIC
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (17 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 18/32] xen/x86: allow disabling the emulated IO APIC Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 20/32] xen/x86: set the vPMU interface based on the presence of a lapic Roger Pau Monne
` (13 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v6:
- Return ENODEV in vpic_load if the vpic is disabled.
- Add asserts to vpic_irq_{negative/positive}_edge and vpic_ack_pending_irq
to make sure they are not called when the vpic is disabled.
- Add a check to vpic_reset in order to prevent calling it with the vpic
disabled.
Changes since v4:
- Add Andrew Cooper Acked-by.
---
xen/arch/x86/hvm/vpic.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/xen/arch/x86/hvm/vpic.c b/xen/arch/x86/hvm/vpic.c
index 7c2edc8..6a2e87b 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 -ENODEV;
+
/* Which PIC is this? */
inst = hvm_load_instance(h);
if ( inst > 1 )
@@ -412,6 +418,9 @@ void vpic_reset(struct domain *d)
{
struct hvm_hw_vpic *vpic;
+ if ( !has_vpic(d) )
+ return;
+
/* Master PIC. */
vpic = &d->arch.hvm_domain.vpic[0];
memset(vpic, 0, sizeof(*vpic));
@@ -425,6 +434,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);
@@ -439,6 +451,7 @@ void vpic_irq_positive_edge(struct domain *d, int irq)
struct hvm_hw_vpic *vpic = &d->arch.hvm_domain.vpic[irq >> 3];
uint8_t mask = 1 << (irq & 7);
+ ASSERT(has_vpic(d));
ASSERT(irq <= 15);
ASSERT(vpic_is_locked(vpic));
@@ -456,6 +469,7 @@ void vpic_irq_negative_edge(struct domain *d, int irq)
struct hvm_hw_vpic *vpic = &d->arch.hvm_domain.vpic[irq >> 3];
uint8_t mask = 1 << (irq & 7);
+ ASSERT(has_vpic(d));
ASSERT(irq <= 15);
ASSERT(vpic_is_locked(vpic));
@@ -473,6 +487,8 @@ int vpic_ack_pending_irq(struct vcpu *v)
int irq, vector;
struct hvm_hw_vpic *vpic = &v->domain->arch.hvm_domain.vpic[0];
+ ASSERT(has_vpic(v->domain));
+
TRACE_2D(TRC_HVM_EMUL_PIC_PEND_IRQ_CALL, vlapic_accept_pic_intr(v),
vpic->int_output);
if ( !vlapic_accept_pic_intr(v) || !vpic->int_output )
--
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] 105+ messages in thread
* [PATCH v7 20/32] xen/x86: set the vPMU interface based on the presence of a lapic
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (18 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 19/32] xen/x86: allow disabling the emulated PIC Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-14 14:41 ` Jan Beulich
2015-10-02 15:48 ` [PATCH v7 21/32] xen/x86: allow disabling the emulated VGA Roger Pau Monne
` (12 subsequent siblings)
32 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne
Instead of choosing the interface to expose to guests based on the guest
type, do it based on whether the guest has an emulated local apic or not.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v6:
- Major rework of the approach.
- Drop Andrew Cooper Acked-by.
Changes since v4:
- Add Andrew Cooper Acked-by.
---
xen/arch/x86/cpu/vpmu.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
index 8af3df1..e5fe4ef 100644
--- a/xen/arch/x86/cpu/vpmu.c
+++ b/xen/arch/x86/cpu/vpmu.c
@@ -94,7 +94,7 @@ void vpmu_lvtpc_update(uint32_t val)
vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR | (val & APIC_LVT_MASKED);
/* Postpone APIC updates for PV(H) guests if PMU interrupt is pending */
- if ( is_hvm_vcpu(curr) || !vpmu->xenpmu_data ||
+ if ( has_vlapic(curr->domain) || !vpmu->xenpmu_data ||
!vpmu_is_set(vpmu, VPMU_CACHED) )
apic_write(APIC_LVTPC, vpmu->hw_lapic_lvtpc);
}
@@ -129,7 +129,7 @@ int vpmu_do_msr(unsigned int msr, uint64_t *msr_content,
* and since do_wr/rdmsr may load VPMU context we should save
* (and unload) it again.
*/
- if ( !is_hvm_vcpu(curr) && vpmu->xenpmu_data &&
+ if ( !has_vlapic(curr->domain) && vpmu->xenpmu_data &&
vpmu_is_set(vpmu, VPMU_CACHED) )
{
vpmu_set(vpmu, VPMU_CONTEXT_SAVE);
@@ -184,7 +184,7 @@ void vpmu_do_interrupt(struct cpu_user_regs *regs)
return;
/* PV(H) guest */
- if ( !is_hvm_vcpu(sampling) || (vpmu_mode & XENPMU_MODE_ALL) )
+ if ( !has_vlapic(sampling->domain) || (vpmu_mode & XENPMU_MODE_ALL) )
{
const struct cpu_user_regs *cur_regs;
uint64_t *flags = &vpmu->xenpmu_data->pmu.pmu_flags;
@@ -411,7 +411,8 @@ int vpmu_load(struct vcpu *v, bool_t from_guest)
/* Only when PMU is counting, we load PMU context immediately. */
if ( !vpmu_is_set(vpmu, VPMU_RUNNING) ||
- (!is_hvm_vcpu(vpmu_vcpu(vpmu)) && vpmu_is_set(vpmu, VPMU_CACHED)) )
+ (!has_vlapic(vpmu_vcpu(vpmu)->domain) &&
+ vpmu_is_set(vpmu, VPMU_CACHED)) )
return 0;
if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_load )
--
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] 105+ messages in thread
* Re: [PATCH v7 20/32] xen/x86: set the vPMU interface based on the presence of a lapic
2015-10-02 15:48 ` [PATCH v7 20/32] xen/x86: set the vPMU interface based on the presence of a lapic Roger Pau Monne
@ 2015-10-14 14:41 ` Jan Beulich
2015-10-14 14:59 ` Boris Ostrovsky
0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-10-14 14:41 UTC (permalink / raw)
To: Roger Pau Monne, Boris Ostrovsky; +Cc: Andrew Cooper, xen-devel
>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
> Instead of choosing the interface to expose to guests based on the guest
> type, do it based on whether the guest has an emulated local apic or not.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
depending on Boris' ack/review.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 20/32] xen/x86: set the vPMU interface based on the presence of a lapic
2015-10-14 14:41 ` Jan Beulich
@ 2015-10-14 14:59 ` Boris Ostrovsky
2015-10-14 15:06 ` Roger Pau Monné
0 siblings, 1 reply; 105+ messages in thread
From: Boris Ostrovsky @ 2015-10-14 14:59 UTC (permalink / raw)
To: Jan Beulich, Roger Pau Monne; +Cc: Andrew Cooper, xen-devel
On 10/14/2015 10:41 AM, Jan Beulich wrote:
>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>> Instead of choosing the interface to expose to guests based on the guest
>> type, do it based on whether the guest has an emulated local apic or not.
>>
>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>
> depending on Boris' ack/review.
I sent Roger additional patch a couple of days ago to make this work
(I've been using his series for a while now) so presumably he will
integrate it in the next spin (or will resend this patch).
Assuming he agrees with my changes, of course.
-boris
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 20/32] xen/x86: set the vPMU interface based on the presence of a lapic
2015-10-14 14:59 ` Boris Ostrovsky
@ 2015-10-14 15:06 ` Roger Pau Monné
2015-10-14 15:10 ` Boris Ostrovsky
0 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-14 15:06 UTC (permalink / raw)
To: Boris Ostrovsky, Jan Beulich; +Cc: Andrew Cooper, xen-devel
El 14/10/15 a les 16.59, Boris Ostrovsky ha escrit:
> On 10/14/2015 10:41 AM, Jan Beulich wrote:
>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>> Instead of choosing the interface to expose to guests based on the guest
>>> type, do it based on whether the guest has an emulated local apic or
>>> not.
>>>
>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> Acked-by: Jan Beulich <jbeulich@suse.com>
>> depending on Boris' ack/review.
>
>
> I sent Roger additional patch a couple of days ago to make this work
> (I've been using his series for a while now) so presumably he will
> integrate it in the next spin (or will resend this patch).
>
> Assuming he agrees with my changes, of course.
TBH, I still need to look into them, I've been busy with the FPU stuff.
But I'm quite sure they are fine, I will merge them with this patch and
add your signed-off to it if that's fine.
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 20/32] xen/x86: set the vPMU interface based on the presence of a lapic
2015-10-14 15:06 ` Roger Pau Monné
@ 2015-10-14 15:10 ` Boris Ostrovsky
0 siblings, 0 replies; 105+ messages in thread
From: Boris Ostrovsky @ 2015-10-14 15:10 UTC (permalink / raw)
To: Roger Pau Monné, Jan Beulich; +Cc: Andrew Cooper, xen-devel
On 10/14/2015 11:06 AM, Roger Pau Monné wrote:
> El 14/10/15 a les 16.59, Boris Ostrovsky ha escrit:
>> On 10/14/2015 10:41 AM, Jan Beulich wrote:
>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>> Instead of choosing the interface to expose to guests based on the guest
>>>> type, do it based on whether the guest has an emulated local apic or
>>>> not.
>>>>
>>>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>>> Acked-by: Jan Beulich <jbeulich@suse.com>
>>> depending on Boris' ack/review.
>>
>> I sent Roger additional patch a couple of days ago to make this work
>> (I've been using his series for a while now) so presumably he will
>> integrate it in the next spin (or will resend this patch).
>>
>> Assuming he agrees with my changes, of course.
> TBH, I still need to look into them, I've been busy with the FPU stuff.
> But I'm quite sure they are fine, I will merge them with this patch and
> add your signed-off to it if that's fine.
Sure.
-boris
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 21/32] xen/x86: allow disabling the emulated VGA
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (19 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 20/32] xen/x86: set the vPMU interface based on the presence of a lapic Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 22/32] xen/x86: allow disabling the emulated IOMMU Roger Pau Monne
` (11 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v4:
- Add Andrew Cooper Acked-by.
---
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] 105+ messages in thread
* [PATCH v7 22/32] xen/x86: allow disabling the emulated IOMMU
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (20 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 21/32] xen/x86: allow disabling the emulated VGA Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set Roger Pau Monne
` (10 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel; +Cc: Aravind Gopalakrishnan, Suravee Suthikulpanit, Roger Pau Monne
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
---
Changes since v4:
- Add Andrew Cooper Acked-by.
---
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] 105+ messages in thread
* [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (21 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 22/32] xen/x86: allow disabling the emulated IOMMU Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 18:37 ` Andrew Cooper
2015-10-14 15:54 ` Jan Beulich
2015-10-02 15:48 ` [PATCH v7 24/32] xen/x86: allow disabling all emulated devices inside of Xen Roger Pau Monne
` (9 subsequent siblings)
32 siblings, 2 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 UTC (permalink / raw)
To: xen-devel; +Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne
If certain devices (like the local or the io apic) are disabled some modes
of operation of the HVM event channel callback cannot be used. Make sure Xen
doesn't try to setup them.
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/irq.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
index 990a2ca..0f3ab6c 100644
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -330,6 +330,10 @@ void hvm_set_callback_via(struct domain *d, uint64_t via)
(via_type > HVMIRQ_callback_vector) )
via_type = HVMIRQ_callback_none;
+ if ( via_type != HVMIRQ_callback_vector &&
+ (!has_vlapic(d) || !has_vioapic(d) || !has_vpic(d)) )
+ return;
+
spin_lock(&d->arch.hvm_domain.irq_lock);
/* Tear down old callback via. */
--
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] 105+ messages in thread
* Re: [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set
2015-10-02 15:48 ` [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set Roger Pau Monne
@ 2015-10-02 18:37 ` Andrew Cooper
2015-10-05 16:44 ` Roger Pau Monné
2015-10-14 15:54 ` Jan Beulich
1 sibling, 1 reply; 105+ messages in thread
From: Andrew Cooper @ 2015-10-02 18:37 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel; +Cc: Jan Beulich
On 02/10/15 16:48, Roger Pau Monne wrote:
> If certain devices (like the local or the io apic) are disabled some modes
> of operation of the HVM event channel callback cannot be used. Make sure Xen
> doesn't try to setup them.
>
> 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/irq.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
> index 990a2ca..0f3ab6c 100644
> --- a/xen/arch/x86/hvm/irq.c
> +++ b/xen/arch/x86/hvm/irq.c
> @@ -330,6 +330,10 @@ void hvm_set_callback_via(struct domain *d, uint64_t via)
> (via_type > HVMIRQ_callback_vector) )
> via_type = HVMIRQ_callback_none;
>
> + if ( via_type != HVMIRQ_callback_vector &&
> + (!has_vlapic(d) || !has_vioapic(d) || !has_vpic(d)) )
> + return;
I think the logic needs to be slightly more complicated.
Without a vlapic, all callback types are invalid.
Without an ioapic/pic, _gsi and _pci_intx are invalid, but _vector is
possible.
Other issues with this area of code (not caused by you) are the fact
there is no error flagged from this setup, and that via_type is not
exposed in the Xen ABI. Both of these should be looked into by someone
with some copious free time, but are not impediments to this patch series.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set
2015-10-02 18:37 ` Andrew Cooper
@ 2015-10-05 16:44 ` Roger Pau Monné
0 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-05 16:44 UTC (permalink / raw)
To: Andrew Cooper, xen-devel; +Cc: Jan Beulich
El 02/10/15 a les 20.37, Andrew Cooper ha escrit:
> On 02/10/15 16:48, Roger Pau Monne wrote:
>> If certain devices (like the local or the io apic) are disabled some modes
>> of operation of the HVM event channel callback cannot be used. Make sure Xen
>> doesn't try to setup them.
>>
>> 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/irq.c | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
>> index 990a2ca..0f3ab6c 100644
>> --- a/xen/arch/x86/hvm/irq.c
>> +++ b/xen/arch/x86/hvm/irq.c
>> @@ -330,6 +330,10 @@ void hvm_set_callback_via(struct domain *d, uint64_t via)
>> (via_type > HVMIRQ_callback_vector) )
>> via_type = HVMIRQ_callback_none;
>>
>> + if ( via_type != HVMIRQ_callback_vector &&
>> + (!has_vlapic(d) || !has_vioapic(d) || !has_vpic(d)) )
>> + return;
>
> I think the logic needs to be slightly more complicated.
>
> Without a vlapic, all callback types are invalid.
Really? On PVH/HVMlite we allow using HVMIRQ_callback_vector without a
vlapic.
> Without an ioapic/pic, _gsi and _pci_intx are invalid, but _vector is
> possible.
>
> Other issues with this area of code (not caused by you) are the fact
> there is no error flagged from this setup, and that via_type is not
> exposed in the Xen ABI. Both of these should be looked into by someone
> with some copious free time, but are not impediments to this patch series.
>
> ~Andrew
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set
2015-10-02 15:48 ` [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set Roger Pau Monne
2015-10-02 18:37 ` Andrew Cooper
@ 2015-10-14 15:54 ` Jan Beulich
2015-10-14 16:01 ` Andrew Cooper
1 sibling, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-10-14 15:54 UTC (permalink / raw)
To: Roger Pau Monne; +Cc: Andrew Cooper, xen-devel
>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
> --- a/xen/arch/x86/hvm/irq.c
> +++ b/xen/arch/x86/hvm/irq.c
> @@ -330,6 +330,10 @@ void hvm_set_callback_via(struct domain *d, uint64_t
> via)
> (via_type > HVMIRQ_callback_vector) )
> via_type = HVMIRQ_callback_none;
>
> + if ( via_type != HVMIRQ_callback_vector &&
> + (!has_vlapic(d) || !has_vioapic(d) || !has_vpic(d)) )
> + return;
Why are both IO-APIC and PIC required? Doesn't one suffice, or
can't MSI-like interrupts even get delivered without either?
Jan
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set
2015-10-14 15:54 ` Jan Beulich
@ 2015-10-14 16:01 ` Andrew Cooper
2015-10-15 11:30 ` Paul Durrant
0 siblings, 1 reply; 105+ messages in thread
From: Andrew Cooper @ 2015-10-14 16:01 UTC (permalink / raw)
To: Jan Beulich, Roger Pau Monne; +Cc: xen-devel
On 14/10/15 16:54, Jan Beulich wrote:
>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>> --- a/xen/arch/x86/hvm/irq.c
>> +++ b/xen/arch/x86/hvm/irq.c
>> @@ -330,6 +330,10 @@ void hvm_set_callback_via(struct domain *d, uint64_t
>> via)
>> (via_type > HVMIRQ_callback_vector) )
>> via_type = HVMIRQ_callback_none;
>>
>> + if ( via_type != HVMIRQ_callback_vector &&
>> + (!has_vlapic(d) || !has_vioapic(d) || !has_vpic(d)) )
>> + return;
> Why are both IO-APIC and PIC required? Doesn't one suffice, or
> can't MSI-like interrupts even get delivered without either?
In real hardware, MSI-like interrupts have no interaction with the
IO-APIC or PIC.
In fact, the purpose of the IO-APIC is to turn legacy line interrupts
into MSI interrupts. The PICs were from the pre-MSI days where it
asserted the #INTR pin on the processor.
Our virtual interrupt infrastructure should behave in a consistent manor.
~Andrew
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set
2015-10-14 16:01 ` Andrew Cooper
@ 2015-10-15 11:30 ` Paul Durrant
2015-10-30 15:34 ` Roger Pau Monné
0 siblings, 1 reply; 105+ messages in thread
From: Paul Durrant @ 2015-10-15 11:30 UTC (permalink / raw)
To: Andrew Cooper, Jan Beulich, Roger Pau Monne
Cc: xen-devel@lists.xenproject.org
> -----Original Message-----
> From: xen-devel-bounces@lists.xen.org [mailto:xen-devel-
> bounces@lists.xen.org] On Behalf Of Andrew Cooper
> Sent: 14 October 2015 17:02
> To: Jan Beulich; Roger Pau Monne
> Cc: xen-devel@lists.xenproject.org
> Subject: Re: [Xen-devel] [PATCH v7 23/32] xen/x86: make sure the HVM
> callback vector is correctly set
>
> On 14/10/15 16:54, Jan Beulich wrote:
> >>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
> >> --- a/xen/arch/x86/hvm/irq.c
> >> +++ b/xen/arch/x86/hvm/irq.c
> >> @@ -330,6 +330,10 @@ void hvm_set_callback_via(struct domain *d,
> uint64_t
> >> via)
> >> (via_type > HVMIRQ_callback_vector) )
> >> via_type = HVMIRQ_callback_none;
> >>
> >> + if ( via_type != HVMIRQ_callback_vector &&
> >> + (!has_vlapic(d) || !has_vioapic(d) || !has_vpic(d)) )
> >> + return;
> > Why are both IO-APIC and PIC required? Doesn't one suffice, or
> > can't MSI-like interrupts even get delivered without either?
>
> In real hardware, MSI-like interrupts have no interaction with the
> IO-APIC or PIC.
>
> In fact, the purpose of the IO-APIC is to turn legacy line interrupts
> into MSI interrupts. The PICs were from the pre-MSI days where it
> asserted the #INTR pin on the processor.
>
> Our virtual interrupt infrastructure should behave in a consistent manor.
>
IIRC both the intx and gsi variants of the callback via go in at the vioapic level.
Paul
> ~Andrew
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set
2015-10-15 11:30 ` Paul Durrant
@ 2015-10-30 15:34 ` Roger Pau Monné
2015-10-30 15:38 ` Andrew Cooper
0 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-30 15:34 UTC (permalink / raw)
To: Paul Durrant, Andrew Cooper, Jan Beulich; +Cc: xen-devel@lists.xenproject.org
El 15/10/15 a les 13.30, Paul Durrant ha escrit:
>> -----Original Message-----
>> From: xen-devel-bounces@lists.xen.org [mailto:xen-devel-
>> bounces@lists.xen.org] On Behalf Of Andrew Cooper
>> Sent: 14 October 2015 17:02
>> To: Jan Beulich; Roger Pau Monne
>> Cc: xen-devel@lists.xenproject.org
>> Subject: Re: [Xen-devel] [PATCH v7 23/32] xen/x86: make sure the HVM
>> callback vector is correctly set
>>
>> On 14/10/15 16:54, Jan Beulich wrote:
>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>> --- a/xen/arch/x86/hvm/irq.c
>>>> +++ b/xen/arch/x86/hvm/irq.c
>>>> @@ -330,6 +330,10 @@ void hvm_set_callback_via(struct domain *d,
>> uint64_t
>>>> via)
>>>> (via_type > HVMIRQ_callback_vector) )
>>>> via_type = HVMIRQ_callback_none;
>>>>
>>>> + if ( via_type != HVMIRQ_callback_vector &&
>>>> + (!has_vlapic(d) || !has_vioapic(d) || !has_vpic(d)) )
>>>> + return;
>>> Why are both IO-APIC and PIC required? Doesn't one suffice, or
>>> can't MSI-like interrupts even get delivered without either?
>>
>> In real hardware, MSI-like interrupts have no interaction with the
>> IO-APIC or PIC.
>>
>> In fact, the purpose of the IO-APIC is to turn legacy line interrupts
>> into MSI interrupts. The PICs were from the pre-MSI days where it
>> asserted the #INTR pin on the processor.
>>
>> Our virtual interrupt infrastructure should behave in a consistent manor.
>>
>
> IIRC both the intx and gsi variants of the callback via go in at the vioapic level.
OK, so I can remove the PIC requirement.
Roger.
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set
2015-10-30 15:34 ` Roger Pau Monné
@ 2015-10-30 15:38 ` Andrew Cooper
0 siblings, 0 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-10-30 15:38 UTC (permalink / raw)
To: Roger Pau Monné, Paul Durrant, Jan Beulich
Cc: xen-devel@lists.xenproject.org
On 30/10/15 15:34, Roger Pau Monné wrote:
> El 15/10/15 a les 13.30, Paul Durrant ha escrit:
>>> -----Original Message-----
>>> From: xen-devel-bounces@lists.xen.org [mailto:xen-devel-
>>> bounces@lists.xen.org] On Behalf Of Andrew Cooper
>>> Sent: 14 October 2015 17:02
>>> To: Jan Beulich; Roger Pau Monne
>>> Cc: xen-devel@lists.xenproject.org
>>> Subject: Re: [Xen-devel] [PATCH v7 23/32] xen/x86: make sure the HVM
>>> callback vector is correctly set
>>>
>>> On 14/10/15 16:54, Jan Beulich wrote:
>>>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>>>>> --- a/xen/arch/x86/hvm/irq.c
>>>>> +++ b/xen/arch/x86/hvm/irq.c
>>>>> @@ -330,6 +330,10 @@ void hvm_set_callback_via(struct domain *d,
>>> uint64_t
>>>>> via)
>>>>> (via_type > HVMIRQ_callback_vector) )
>>>>> via_type = HVMIRQ_callback_none;
>>>>>
>>>>> + if ( via_type != HVMIRQ_callback_vector &&
>>>>> + (!has_vlapic(d) || !has_vioapic(d) || !has_vpic(d)) )
>>>>> + return;
>>>> Why are both IO-APIC and PIC required? Doesn't one suffice, or
>>>> can't MSI-like interrupts even get delivered without either?
>>> In real hardware, MSI-like interrupts have no interaction with the
>>> IO-APIC or PIC.
>>>
>>> In fact, the purpose of the IO-APIC is to turn legacy line interrupts
>>> into MSI interrupts. The PICs were from the pre-MSI days where it
>>> asserted the #INTR pin on the processor.
>>>
>>> Our virtual interrupt infrastructure should behave in a consistent manor.
>>>
>> IIRC both the intx and gsi variants of the callback via go in at the vioapic level.
> OK, so I can remove the PIC requirement.
In some copious free time, we really should see about dropping the vPIC
entirely and doing what real hardware does, and implement virtual wire
mode in the vIOAPIC for PIC emulation.
This would simplify the choice of injection options from the Xen side.
~Andrew
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 24/32] xen/x86: allow disabling all emulated devices inside of Xen
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (22 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 23/32] xen/x86: make sure the HVM callback vector is correctly set Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-19 14:23 ` Jan Beulich
2015-10-02 15:48 ` [PATCH v7 25/32] elfnotes: intorduce a new PHYS_ENTRY elfnote Roger Pau Monne
` (8 subsequent siblings)
32 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v5:
- Add Andrew Cooper Reviewed-by.
---
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 79182a4..a3b1c9b 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -526,7 +526,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
d->domain_id, config->emulation_flags);
return -EINVAL;
}
- if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL) ||
+ if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL &&
+ config->emulation_flags != 0) ||
(is_pv_domain(d) && config->emulation_flags != 0) )
{
printk(XENLOG_G_ERR "d%d: Xen does not allow %s domain creation with "
--
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] 105+ messages in thread
* Re: [PATCH v7 24/32] xen/x86: allow disabling all emulated devices inside of Xen
2015-10-02 15:48 ` [PATCH v7 24/32] xen/x86: allow disabling all emulated devices inside of Xen Roger Pau Monne
@ 2015-10-19 14:23 ` Jan Beulich
2015-10-30 16:20 ` Roger Pau Monné
0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-10-19 14:23 UTC (permalink / raw)
To: Roger Pau Monne; +Cc: Andrew Cooper, xen-devel
>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> 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>
> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> Changes since v5:
> - Add Andrew Cooper Reviewed-by.
> ---
> 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 79182a4..a3b1c9b 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -526,7 +526,8 @@ int arch_domain_create(struct domain *d, unsigned int
> domcr_flags,
> d->domain_id, config->emulation_flags);
> return -EINVAL;
> }
> - if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL) ||
> + if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL &&
> + config->emulation_flags != 0) ||
> (is_pv_domain(d) && config->emulation_flags != 0) )
Would there be any bad in simplifying this to
if ( config->emulation_flags != 0 && (!is_hvm_domain(d) || config->emulation_flags != XEN_X86_EMU_ALL) )
(i.e. allowing flags to be zero for all kinds)?
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 24/32] xen/x86: allow disabling all emulated devices inside of Xen
2015-10-19 14:23 ` Jan Beulich
@ 2015-10-30 16:20 ` Roger Pau Monné
2015-10-30 16:27 ` Jan Beulich
0 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-30 16:20 UTC (permalink / raw)
To: Jan Beulich; +Cc: Andrew Cooper, xen-devel
El 19/10/15 a les 16.23, Jan Beulich ha escrit:
>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> 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>
>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> Cc: Jan Beulich <jbeulich@suse.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> Changes since v5:
>> - Add Andrew Cooper Reviewed-by.
>> ---
>> 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 79182a4..a3b1c9b 100644
>> --- a/xen/arch/x86/domain.c
>> +++ b/xen/arch/x86/domain.c
>> @@ -526,7 +526,8 @@ int arch_domain_create(struct domain *d, unsigned int
>> domcr_flags,
>> d->domain_id, config->emulation_flags);
>> return -EINVAL;
>> }
>> - if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL) ||
>> + if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL &&
>> + config->emulation_flags != 0) ||
>> (is_pv_domain(d) && config->emulation_flags != 0) )
>
> Would there be any bad in simplifying this to
>
> if ( config->emulation_flags != 0 && (!is_hvm_domain(d) || config->emulation_flags != XEN_X86_EMU_ALL) )
>
> (i.e. allowing flags to be zero for all kinds)?
IMHO I find this harder to read, but I guess that's a question of taste,
I've replaced it with your suggestion.
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 24/32] xen/x86: allow disabling all emulated devices inside of Xen
2015-10-30 16:20 ` Roger Pau Monné
@ 2015-10-30 16:27 ` Jan Beulich
0 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2015-10-30 16:27 UTC (permalink / raw)
To: Roger Pau Monné; +Cc: Andrew Cooper, xen-devel
>>> On 30.10.15 at 17:20, <roger.pau@citrix.com> wrote:
> El 19/10/15 a les 16.23, Jan Beulich ha escrit:
>>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> 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>
>>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>>> Cc: Jan Beulich <jbeulich@suse.com>
>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>> ---
>>> Changes since v5:
>>> - Add Andrew Cooper Reviewed-by.
>>> ---
>>> 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 79182a4..a3b1c9b 100644
>>> --- a/xen/arch/x86/domain.c
>>> +++ b/xen/arch/x86/domain.c
>>> @@ -526,7 +526,8 @@ int arch_domain_create(struct domain *d, unsigned int
>>> domcr_flags,
>>> d->domain_id, config->emulation_flags);
>>> return -EINVAL;
>>> }
>>> - if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL) ||
>>> + if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL &&
>>> + config->emulation_flags != 0) ||
>>> (is_pv_domain(d) && config->emulation_flags != 0) )
>>
>> Would there be any bad in simplifying this to
>>
>> if ( config->emulation_flags != 0 && (!is_hvm_domain(d) || config->emulation_flags != XEN_X86_EMU_ALL) )
>>
>> (i.e. allowing flags to be zero for all kinds)?
>
> IMHO I find this harder to read, but I guess that's a question of taste,
> I've replaced it with your suggestion.
I have a hard time seeing how a 3 component logical expression
can be harder to read than a 5 component one.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 25/32] elfnotes: intorduce a new PHYS_ENTRY elfnote
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (23 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 24/32] xen/x86: allow disabling all emulated devices inside of Xen Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 26/32] libxc: allow creating domains without emulated devices Roger Pau Monne
` (7 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@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 v6:
- Reword a comment.
Changes since v4:
- Add Andrew Cooper Reviewed-by and Wei Liu Acked-by.
---
tools/xcutils/readnotes.c | 3 +++
xen/common/libelf/libelf-dominfo.c | 4 ++++
xen/include/public/elfnote.h | 12 +++++++++++-
3 files changed, 18 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 3de1c23..dacd4ba 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..353985f 100644
--- a/xen/include/public/elfnote.h
+++ b/xen/include/public/elfnote.h
@@ -200,9 +200,19 @@
#define XEN_ELFNOTE_SUPPORTED_FEATURES 17
/*
+ * Physical entry point into the kernel.
+ *
+ * 32bit entry point into the kernel. When requested to launch the
+ * guest kernel in a HVM container, Xen will use this entry point to
+ * launch the guest in 32bit protected mode with paging disabled.
+ * Ignored otherwise.
+ */
+#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] 105+ messages in thread
* [PATCH v7 26/32] libxc: allow creating domains without emulated devices.
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (24 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 25/32] elfnotes: intorduce a new PHYS_ENTRY elfnote Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:48 ` [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs Roger Pau Monne
` (6 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@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 v5:
- Add Andrew Cooper Reviewed-by.
Changes since v4:
- Store the size of the VGA hole inside of the xc_dom_image struct and set
it from libxl.
- Rename dom->emulation to dom->device_model (no functional change).
- Add Wei Liu Acked-by.
Changes since v3:
- Explain the meaning of the "emulation" xc_dom_image field.
---
tools/libxc/include/xc_dom.h | 4 +++
tools/libxc/xc_dom_x86.c | 73 ++++++++++++++++++++++++--------------------
tools/libxl/libxl_dom.c | 2 ++
tools/libxl/libxl_internal.h | 1 +
4 files changed, 47 insertions(+), 33 deletions(-)
diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index e52b023..720b218 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -191,6 +191,10 @@ struct xc_dom_image {
xen_pfn_t mmio_size;
xen_pfn_t lowmem_end;
xen_pfn_t highmem_end;
+ xen_pfn_t vga_hole_size;
+
+ /* If unset disables the setup of the IOREQ pages. */
+ bool device_model;
/* 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 dd331bf..85b8288 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -49,8 +49,6 @@
#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
@@ -523,12 +521,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->device_model )
+ {
+ 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++ )
@@ -560,30 +561,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->device_model )
{
- 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
@@ -1317,7 +1321,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->vga_hole_size);
if ( rc != 0 )
{
DOMPRINTF("Could not allocate memory for HVM guest as we cannot claim memory!");
@@ -1333,7 +1338,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->vga_hole_size,
NULL, NULL, NULL);
if ( rc != 0 )
{
@@ -1352,8 +1358,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->device_model )
+ 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++ )
@@ -1372,7 +1379,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->device_model )
{
cur_pages = 0xc0;
stat_normal_pages += 0xc0;
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index a9925b7..b3ac44e 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -989,6 +989,8 @@ 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->vga_hole_size = LIBXL_VGA_HOLE_SIZE;
+ dom->device_model = true;
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 c5df398..25ace27 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -101,6 +101,7 @@
#define LIBXL_HVM_EXTRA_MEMORY 2048
#define LIBXL_MIN_DOM0_MEM (128*1024)
#define LIBXL_INVALID_GFN (~(uint64_t)0)
+#define LIBXL_VGA_HOLE_SIZE 0x20
/* use 0 as the domid of the toolstack domain for now */
#define LIBXL_TOOLSTACK_DOMID 0
#define QEMU_SIGNATURE "DeviceModelRecord0002"
--
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] 105+ messages in thread
* [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (25 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 26/32] libxc: allow creating domains without emulated devices Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-05 10:28 ` Andrew Cooper
2015-10-19 15:48 ` Jan Beulich
2015-10-02 15:48 ` [PATCH v7 28/32] xenconsole: try to attach to PV console if HVM fails Roger Pau Monne
` (5 subsequent siblings)
32 siblings, 2 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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>
Signed-off-by: Andrew Cooper <andrew.cooper3@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>
---
Changes since v6:
- Add comments to clarify some initializations.
- Introduce a generic default_initialize_vcpu that's used to initialize a
ARM vCPU or a x86 PV vCPU.
- Move the undef of the SEG macro.
- Fix the size of the eflags register, it should be 32bits.
- Add a comment regarding the value of the 12-15 bits of the _ar fields.
- Remove the 16bit strucutre, the 32bit one can be used to start the cpu in
real mode.
- Add some sanity checks to the values passed in.
- Add paddings to vcpu_hvm_context so the layout on 32/64bits is the same.
- Add support for the compat version of VCPUOP_initialise.
Changes since v5:
- Fix a coding style issue.
- Merge the code from wip-dmlite-v5-refactor by Andrew in order to reduce
bloat.
- Print the offending %cr3 in case of error when using shadow.
- Reduce the scope of local variables in arch_initialize_vcpu.
- s/current->domain/v->domain/g in arch_initialize_vcpu.
- Expand the comment in public/vcpu.h to document the usage of
vcpu_hvm_context for HVM guests.
- Add myself as the copyright holder for the public hvm_vcpu.h header.
Changes since v4:
- Don't assume mode is 64B, add an explicit check.
- Don't set TF_kernel_mode, it is only needed for PV guests.
- Don't set CR0_ET unconditionally.
---
xen/arch/x86/domain.c | 185 ++++++++++++++++++++++++++++++++++++++
xen/arch/x86/hvm/hvm.c | 8 ++
xen/common/compat/domain.c | 71 +++++++++++----
xen/common/domain.c | 56 +++++++++---
xen/include/Makefile | 1 +
xen/include/asm-x86/domain.h | 3 +
xen/include/public/hvm/hvm_vcpu.h | 144 +++++++++++++++++++++++++++++
xen/include/public/vcpu.h | 6 +-
xen/include/xlat.lst | 3 +
9 files changed, 448 insertions(+), 29 deletions(-)
create mode 100644 xen/include/public/hvm/hvm_vcpu.h
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index a3b1c9b..af5feea 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>
@@ -1176,6 +1177,190 @@ int arch_set_info_guest(
#undef c
}
+/* Called by VCPUOP_initialise for HVM guests. */
+int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx)
+{
+ struct cpu_user_regs *uregs = &v->arch.user_regs;
+ struct segment_register cs, ds, ss, es, tr;
+
+ switch ( ctx->mode )
+ {
+ default:
+ return -EINVAL;
+
+ case VCPU_HVM_MODE_32B:
+ {
+ const struct vcpu_hvm_x86_32 *regs = &ctx->cpu_regs.x86_32;
+ uint32_t limit;
+
+#define SEG(s, r) \
+ (struct segment_register){ .sel = 0, .base = (r)->s ## _base, \
+ .limit = (r)->s ## _limit, .attr.bytes = (r)->s ## _ar }
+ cs = SEG(cs, regs);
+ ds = SEG(ds, regs);
+ ss = SEG(ss, regs);
+ es = SEG(es, regs);
+ tr = SEG(tr, regs);
+#undef SEG
+
+ /* Basic sanity checks. */
+ if ( cs.attr.fields.pad != 0 || ds.attr.fields.pad != 0 ||
+ ss.attr.fields.pad != 0 || es.attr.fields.pad != 0 ||
+ tr.attr.fields.pad != 0 )
+ {
+ gprintk(XENLOG_ERR, "Attribute bits 12-15 of the segments are not null\n");
+ return -EINVAL;
+ }
+
+ limit = cs.limit * (cs.attr.fields.g ? PAGE_SIZE : 1);
+ if ( regs->eip > limit )
+ {
+ gprintk(XENLOG_ERR, "EIP address is outside of the CS limit\n");
+ return -EINVAL;
+ }
+
+ if ( ds.attr.fields.dpl > cs.attr.fields.dpl )
+ {
+ gprintk(XENLOG_ERR, "DPL of DS is greater than DPL of CS\n");
+ return -EINVAL;
+ }
+
+ if ( ss.attr.fields.dpl != cs.attr.fields.dpl )
+ {
+ gprintk(XENLOG_ERR, "DPL of SS is different than DPL of CS\n");
+ return -EINVAL;
+ }
+
+ if ( es.attr.fields.dpl > cs.attr.fields.dpl )
+ {
+ gprintk(XENLOG_ERR, "DPL of ES is greater than DPL of CS\n");
+ return -EINVAL;
+ }
+
+ if ( ((regs->efer & EFER_LMA) && !(regs->efer & EFER_LME)) ||
+ ((regs->efer & EFER_LME) && !(regs->efer & EFER_LMA)) )
+ {
+ gprintk(XENLOG_ERR, "EFER.LMA and EFER.LME must be both set\n");
+ return -EINVAL;
+ }
+
+ uregs->rax = regs->eax;
+ uregs->rcx = regs->ecx;
+ uregs->rdx = regs->edx;
+ uregs->rbx = regs->ebx;
+ uregs->rsp = regs->esp;
+ uregs->rbp = regs->ebp;
+ uregs->rsi = regs->esi;
+ uregs->rdi = regs->edi;
+ uregs->rip = regs->eip;
+ uregs->rflags = regs->eflags;
+
+ v->arch.hvm_vcpu.guest_cr[0] = regs->cr0;
+ v->arch.hvm_vcpu.guest_cr[3] = regs->cr3;
+ v->arch.hvm_vcpu.guest_cr[4] = regs->cr4;
+ v->arch.hvm_vcpu.guest_efer = regs->efer;
+ }
+ break;
+
+ case VCPU_HVM_MODE_64B:
+ {
+ const struct vcpu_hvm_x86_64 *regs = &ctx->cpu_regs.x86_64;
+
+ /* Basic sanity checks. */
+ if ( !is_canonical_address(regs->rip) )
+ {
+ gprintk(XENLOG_ERR, "RIP contains a non-canonical address\n");
+ return -EINVAL;
+ }
+
+ if ( !(regs->cr0 & X86_CR0_PG) )
+ {
+ gprintk(XENLOG_ERR, "CR0 doesn't have paging enabled\n");
+ return -EINVAL;
+ }
+
+ if ( !(regs->cr4 & X86_CR4_PAE) )
+ {
+ gprintk(XENLOG_ERR, "CR4 doesn't have PAE enabled\n");
+ return -EINVAL;
+ }
+
+ if ( (regs->efer & (EFER_LME | EFER_LMA)) != (EFER_LME | EFER_LMA) )
+ {
+ gprintk(XENLOG_ERR, "EFER doesn't have LME or LMA enabled\n");
+ return -EINVAL;
+ }
+
+ uregs->rax = regs->rax;
+ uregs->rcx = regs->rcx;
+ uregs->rdx = regs->rdx;
+ uregs->rbx = regs->rbx;
+ uregs->rsp = regs->rsp;
+ uregs->rbp = regs->rbp;
+ uregs->rsi = regs->rsi;
+ uregs->rdi = regs->rdi;
+ uregs->rip = regs->rip;
+ uregs->rflags = regs->rflags;
+
+ v->arch.hvm_vcpu.guest_cr[0] = regs->cr0;
+ v->arch.hvm_vcpu.guest_cr[3] = regs->cr3;
+ v->arch.hvm_vcpu.guest_cr[4] = regs->cr4;
+ v->arch.hvm_vcpu.guest_efer = regs->efer;
+
+#define SEG(b, l, a) \
+ (struct segment_register){ .sel = 0, .base = (b), .limit = (l), \
+ .attr.bytes = (a) }
+ cs = SEG(0, ~0u, 0xa9b); /* 64bit code segment. */
+ ds = ss = es = SEG(0, ~0u, 0xc93);
+ tr = SEG(0, 0x67, 0x8b); /* 64bit TSS (busy). */
+#undef SEG
+ }
+ break;
+
+ }
+
+ hvm_update_guest_cr(v, 0);
+ hvm_update_guest_cr(v, 3);
+ hvm_update_guest_cr(v, 4);
+ hvm_update_guest_efer(v);
+
+ 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 )
+ {
+ gprintk(XENLOG_ERR, "Invalid CR3: %#lx\n",
+ v->arch.hvm_vcpu.guest_cr[3]);
+ domain_crash(v->domain);
+ return -EINVAL;
+ }
+
+ v->arch.guest_table = pagetable_from_page(page);
+ }
+
+ hvm_set_segment_register(v, x86_seg_cs, &cs);
+ hvm_set_segment_register(v, x86_seg_ds, &ds);
+ hvm_set_segment_register(v, x86_seg_ss, &ss);
+ hvm_set_segment_register(v, x86_seg_es, &es);
+ hvm_set_segment_register(v, x86_seg_tr, &tr);
+
+ /* 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);
+
+ paging_update_paging_modes(v);
+
+ v->is_initialised = 1;
+ set_bit(_VPF_down, &v->pause_flags);
+
+ return 0;
+}
+
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 b4d8475..3c890c1 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4993,6 +4993,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:
@@ -5051,6 +5055,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/compat/domain.c b/xen/common/compat/domain.c
index 5dc7d94..9cccef0 100644
--- a/xen/common/compat/domain.c
+++ b/xen/common/compat/domain.c
@@ -10,6 +10,9 @@
#include <xen/guest_access.h>
#include <xen/hypercall.h>
#include <compat/vcpu.h>
+#ifdef CONFIG_X86
+#include <compat/hvm/hvm_vcpu.h>
+#endif
#define xen_vcpu_set_periodic_timer vcpu_set_periodic_timer
CHECK_vcpu_set_periodic_timer;
@@ -23,8 +26,43 @@ CHECK_SIZE_(struct, vcpu_info);
CHECK_vcpu_register_vcpu_info;
#undef xen_vcpu_register_vcpu_info
+#ifdef CONFIG_X86
+#define xen_vcpu_hvm_context vcpu_hvm_context
+#define xen_vcpu_hvm_x86_32 vcpu_hvm_x86_32
+#define xen_vcpu_hvm_x86_64 vcpu_hvm_x86_64
+CHECK_vcpu_hvm_context;
+#undef xen_vcpu_hvm_x86_64
+#undef xen_vcpu_hvm_x86_32
+#undef xen_vcpu_hvm_context
+#endif
+
extern vcpu_info_t dummy_vcpu_info;
+static int default_initialize_vcpu(struct vcpu *v,
+ XEN_GUEST_HANDLE_PARAM(void) arg)
+{
+ struct compat_vcpu_guest_context *cmp_ctxt;
+ struct domain *d = v->domain;
+ int rc;
+
+ if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL )
+ return -ENOMEM;
+
+ if ( copy_from_guest(cmp_ctxt, arg, 1) )
+ {
+ xfree(cmp_ctxt);
+ return -EFAULT;
+ }
+
+ domain_lock(d);
+ rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, cmp_ctxt);
+ domain_unlock(d);
+
+ xfree(cmp_ctxt);
+
+ return rc;
+}
+
int compat_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg)
{
struct domain *d = current->domain;
@@ -38,33 +76,36 @@ int compat_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) ar
{
case VCPUOP_initialise:
{
- struct compat_vcpu_guest_context *cmp_ctxt;
-
if ( v->vcpu_info == &dummy_vcpu_info )
return -EINVAL;
- if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL )
+#if defined(CONFIG_X86)
+ if ( is_hvm_vcpu(v) )
{
- rc = -ENOMEM;
- break;
- }
+ struct vcpu_hvm_context hvm_ctx;
- if ( copy_from_guest(cmp_ctxt, arg, 1) )
+ 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
{
- xfree(cmp_ctxt);
- rc = -EFAULT;
- break;
+ rc = default_initialize_vcpu(v, arg);
}
-
- domain_lock(d);
- rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, cmp_ctxt);
- domain_unlock(d);
+#elif defined(CONFIG_ARM)
+ rc = default_initialize_vcpu(v, arg);
+#else
+ #error Unsupported architecture
+#endif
if ( rc == -ERESTART )
rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iuh",
cmd, vcpuid, arg);
- xfree(cmp_ctxt);
break;
}
diff --git a/xen/common/domain.c b/xen/common/domain.c
index cec0dcf..33b67a6 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -1207,11 +1207,35 @@ void unmap_vcpu_info(struct vcpu *v)
put_page_and_type(mfn_to_page(mfn));
}
+static int default_initialize_vcpu(struct vcpu *v,
+ XEN_GUEST_HANDLE_PARAM(void) arg)
+{
+ struct vcpu_guest_context *ctxt;
+ struct domain *d = v->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;
+}
+
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 )
@@ -1223,20 +1247,28 @@ 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) )
+#if defined(CONFIG_X86)
+ if ( is_hvm_vcpu(v) )
{
- free_vcpu_guest_context(ctxt);
- return -EFAULT;
- }
+ struct vcpu_hvm_context hvm_ctx;
- domain_lock(d);
- rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, ctxt);
- domain_unlock(d);
+ if ( copy_from_guest(&hvm_ctx, arg, 1) )
+ return -EFAULT;
- free_vcpu_guest_context(ctxt);
+ domain_lock(d);
+ rc = v->is_initialised ? -EEXIST :
+ arch_set_info_hvm_guest(v, &hvm_ctx);
+ domain_unlock(d);
+ }
+ else
+ {
+ rc = default_initialize_vcpu(v, arg);
+ }
+#elif defined(CONFIG_ARM)
+ rc = default_initialize_vcpu(v, arg);
+#else
+ #error Unsupported architecture
+#endif
if ( rc == -ERESTART )
rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iuh",
diff --git a/xen/include/Makefile b/xen/include/Makefile
index 6664107..301245a 100644
--- a/xen/include/Makefile
+++ b/xen/include/Makefile
@@ -26,6 +26,7 @@ headers-$(CONFIG_X86) += compat/arch-x86/pmu.h
headers-$(CONFIG_X86) += compat/arch-x86/xen-mca.h
headers-$(CONFIG_X86) += compat/arch-x86/xen.h
headers-$(CONFIG_X86) += compat/arch-x86/xen-$(compat-arch-y).h
+headers-$(CONFIG_X86) += compat/hvm/hvm_vcpu.h
headers-y += compat/arch-$(compat-arch-y).h compat/pmu.h compat/xlat.h
headers-$(FLASK_ENABLE) += compat/xsm/flask_op.h
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 84ae4c1..3ba7d37 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -10,6 +10,7 @@
#include <asm/mce.h>
#include <public/vcpu.h>
#include <public/hvm/hvm_info_table.h>
+#include <public/hvm/hvm_vcpu.h>
#define has_32bit_shinfo(d) ((d)->arch.has_32bit_shinfo)
#define is_pv_32bit_domain(d) ((d)->arch.is_32bit_pv)
@@ -599,6 +600,8 @@ static inline void free_vcpu_guest_context(struct vcpu_guest_context *vgc)
vfree(vgc);
}
+int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx);
+
#endif /* __ASM_DOMAIN_H__ */
/*
diff --git a/xen/include/public/hvm/hvm_vcpu.h b/xen/include/public/hvm/hvm_vcpu.h
new file mode 100644
index 0000000..c841461
--- /dev/null
+++ b/xen/include/public/hvm/hvm_vcpu.h
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ *
+ * Copyright (c) 2015, Roger Pau Monne <roger.pau@citrix.com>
+ */
+
+#ifndef __XEN_PUBLIC_HVM_HVM_VCPU_H__
+#define __XEN_PUBLIC_HVM_HVM_VCPU_H__
+
+#include "../xen.h"
+
+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;
+ uint32_t eflags;
+
+ uint32_t cr0;
+ uint32_t cr3;
+ uint32_t cr4;
+
+ uint32_t pad1;
+
+ /*
+ * EFER should only be used to set the NXE bit (if required)
+ * when starting a vCPU in 32bit mode with paging enabled or
+ * to set the LME/LMA bits in order to start the vCPU in
+ * compatibility mode.
+ */
+ uint64_t efer;
+
+ uint32_t cs_base;
+ uint32_t ds_base;
+ uint32_t ss_base;
+ uint32_t es_base;
+ uint32_t tr_base;
+ uint32_t cs_limit;
+ uint32_t ds_limit;
+ uint32_t ss_limit;
+ uint32_t es_limit;
+ uint32_t tr_limit;
+ uint16_t cs_ar;
+ uint16_t ds_ar;
+ uint16_t ss_ar;
+ uint16_t es_ar;
+ uint16_t tr_ar;
+
+ uint16_t pad2[2];
+};
+
+/*
+ * 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)
+ * Bits [12,15]: unused, must be blank.
+ *
+ * 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_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 rip;
+ uint64_t rflags;
+
+ uint64_t cr0;
+ uint64_t cr3;
+ uint64_t cr4;
+ uint64_t efer;
+
+ /*
+ * Using VCPU_HVM_MODE_64B implies that the vCPU is launched
+ * directly in long mode, so the cached parts of the segment
+ * registers get set to match that environment.
+ *
+ * If the user wants to launch the vCPU in compatibility mode
+ * the 32-bit structure should be used instead.
+ */
+};
+
+struct vcpu_hvm_context {
+#define VCPU_HVM_MODE_32B 0 /* 32bit fields of the structure will be used. */
+#define VCPU_HVM_MODE_64B 1 /* 64bit fields of the structure will be used. */
+ uint32_t mode;
+
+ uint32_t pad;
+
+ /* CPU registers. */
+ union {
+ 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/public/vcpu.h b/xen/include/public/vcpu.h
index 898b89f..692b87a 100644
--- a/xen/include/public/vcpu.h
+++ b/xen/include/public/vcpu.h
@@ -41,8 +41,10 @@
* Initialise a VCPU. Each VCPU can be initialised only once. A
* newly-initialised VCPU will not run until it is brought up by VCPUOP_up.
*
- * @extra_arg == pointer to vcpu_guest_context structure containing initial
- * state for the VCPU.
+ * @extra_arg == For PV or ARM guests this is a pointer to a vcpu_guest_context
+ * structure containing the initial state for the VCPU. For x86
+ * HVM based guests this is a pointer to a vcpu_hvm_context
+ * structure.
*/
#define VCPUOP_initialise 0
diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst
index 3795059..fda1137 100644
--- a/xen/include/xlat.lst
+++ b/xen/include/xlat.lst
@@ -56,6 +56,9 @@
? grant_entry_header grant_table.h
? grant_entry_v2 grant_table.h
? gnttab_swap_grant_ref grant_table.h
+? vcpu_hvm_context hvm/hvm_vcpu.h
+? vcpu_hvm_x86_32 hvm/hvm_vcpu.h
+? vcpu_hvm_x86_64 hvm/hvm_vcpu.h
? kexec_exec kexec.h
! kexec_image kexec.h
! kexec_range kexec.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] 105+ messages in thread
* Re: [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
2015-10-02 15:48 ` [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs Roger Pau Monne
@ 2015-10-05 10:28 ` Andrew Cooper
2015-10-08 13:35 ` Roger Pau Monné
2015-10-19 15:48 ` Jan Beulich
1 sibling, 1 reply; 105+ messages in thread
From: Andrew Cooper @ 2015-10-05 10:28 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel; +Cc: Stefano Stabellini, Ian Campbell, Jan Beulich
On 02/10/15 16:48, 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>
> Signed-off-by: Andrew Cooper <andrew.cooper3@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>
> ---
> Changes since v6:
> - Add comments to clarify some initializations.
> - Introduce a generic default_initialize_vcpu that's used to initialize a
> ARM vCPU or a x86 PV vCPU.
> - Move the undef of the SEG macro.
> - Fix the size of the eflags register, it should be 32bits.
> - Add a comment regarding the value of the 12-15 bits of the _ar fields.
> - Remove the 16bit strucutre, the 32bit one can be used to start the cpu in
> real mode.
> - Add some sanity checks to the values passed in.
> - Add paddings to vcpu_hvm_context so the layout on 32/64bits is the same.
> - Add support for the compat version of VCPUOP_initialise.
>
> Changes since v5:
> - Fix a coding style issue.
> - Merge the code from wip-dmlite-v5-refactor by Andrew in order to reduce
> bloat.
> - Print the offending %cr3 in case of error when using shadow.
> - Reduce the scope of local variables in arch_initialize_vcpu.
> - s/current->domain/v->domain/g in arch_initialize_vcpu.
> - Expand the comment in public/vcpu.h to document the usage of
> vcpu_hvm_context for HVM guests.
> - Add myself as the copyright holder for the public hvm_vcpu.h header.
>
> Changes since v4:
> - Don't assume mode is 64B, add an explicit check.
> - Don't set TF_kernel_mode, it is only needed for PV guests.
> - Don't set CR0_ET unconditionally.
> ---
> xen/arch/x86/domain.c | 185 ++++++++++++++++++++++++++++++++++++++
> xen/arch/x86/hvm/hvm.c | 8 ++
> xen/common/compat/domain.c | 71 +++++++++++----
> xen/common/domain.c | 56 +++++++++---
> xen/include/Makefile | 1 +
> xen/include/asm-x86/domain.h | 3 +
> xen/include/public/hvm/hvm_vcpu.h | 144 +++++++++++++++++++++++++++++
> xen/include/public/vcpu.h | 6 +-
> xen/include/xlat.lst | 3 +
> 9 files changed, 448 insertions(+), 29 deletions(-)
> create mode 100644 xen/include/public/hvm/hvm_vcpu.h
>
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index a3b1c9b..af5feea 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>
> @@ -1176,6 +1177,190 @@ int arch_set_info_guest(
> #undef c
> }
>
> +/* Called by VCPUOP_initialise for HVM guests. */
> +int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx)
> +{
> + struct cpu_user_regs *uregs = &v->arch.user_regs;
> + struct segment_register cs, ds, ss, es, tr;
> +
> + switch ( ctx->mode )
> + {
> + default:
> + return -EINVAL;
> +
> + case VCPU_HVM_MODE_32B:
> + {
> + const struct vcpu_hvm_x86_32 *regs = &ctx->cpu_regs.x86_32;
> + uint32_t limit;
> +
> +#define SEG(s, r) \
> + (struct segment_register){ .sel = 0, .base = (r)->s ## _base, \
> + .limit = (r)->s ## _limit, .attr.bytes = (r)->s ## _ar }
> + cs = SEG(cs, regs);
> + ds = SEG(ds, regs);
> + ss = SEG(ss, regs);
> + es = SEG(es, regs);
> + tr = SEG(tr, regs);
> +#undef SEG
> +
> + /* Basic sanity checks. */
> + if ( cs.attr.fields.pad != 0 || ds.attr.fields.pad != 0 ||
> + ss.attr.fields.pad != 0 || es.attr.fields.pad != 0 ||
> + tr.attr.fields.pad != 0 )
> + {
> + gprintk(XENLOG_ERR, "Attribute bits 12-15 of the segments are not null\n");
I would use 'zero' as opposed to 'null' here. There is nothing to do
with pointers here.
> + return -EINVAL;
> + }
> +
> + limit = cs.limit * (cs.attr.fields.g ? PAGE_SIZE : 1);
This will overflow in the common case. Calculation of the limit is a
little awkward. I believe this should do:
limit = cs.limit
if ( cs.attr.fields.g )
limit = (limit << 12) | 0xfff;
In the case that g is set and cs is a flat segment, limit should have
the value ~0U, rather than 0 which is what your calculation will achieve.
> + if ( regs->eip > limit )
> + {
> + gprintk(XENLOG_ERR, "EIP address is outside of the CS limit\n");
In all cases, please print out the values, to make the error message
more helpful.
e.g. "EIP (%08x) outside CS limit (%08x)"
> + return -EINVAL;
> + }
> +
> + if ( ds.attr.fields.dpl > cs.attr.fields.dpl )
> + {
> + gprintk(XENLOG_ERR, "DPL of DS is greater than DPL of CS\n");
> + return -EINVAL;
> + }
> +
> + if ( ss.attr.fields.dpl != cs.attr.fields.dpl )
> + {
> + gprintk(XENLOG_ERR, "DPL of SS is different than DPL of CS\n");
> + return -EINVAL;
> + }
> +
> + if ( es.attr.fields.dpl > cs.attr.fields.dpl )
> + {
> + gprintk(XENLOG_ERR, "DPL of ES is greater than DPL of CS\n");
> + return -EINVAL;
> + }
> +
> + if ( ((regs->efer & EFER_LMA) && !(regs->efer & EFER_LME)) ||
> + ((regs->efer & EFER_LME) && !(regs->efer & EFER_LMA)) )
This simplifies to ( (!!(regs->efer & EFER_LMA)) ^ (!!(regs->efer &
EFER_LME)) )
> + {
> + gprintk(XENLOG_ERR, "EFER.LMA and EFER.LME must be both set\n");
And this should say "both the same", rather than both set.
Having said this, I still don't think it is sensible to require that LMA
is set, seeing as it is strictly a read-only bit in EFER. I would
suggest keying on LME alone, and automatically ORing in LMA, which
matches the behaviour of hardware more closely.
> + return -EINVAL;
> + }
> +
> + uregs->rax = regs->eax;
> + uregs->rcx = regs->ecx;
> + uregs->rdx = regs->edx;
> + uregs->rbx = regs->ebx;
> + uregs->rsp = regs->esp;
> + uregs->rbp = regs->ebp;
> + uregs->rsi = regs->esi;
> + uregs->rdi = regs->edi;
> + uregs->rip = regs->eip;
> + uregs->rflags = regs->eflags;
> +
> + v->arch.hvm_vcpu.guest_cr[0] = regs->cr0;
> + v->arch.hvm_vcpu.guest_cr[3] = regs->cr3;
> + v->arch.hvm_vcpu.guest_cr[4] = regs->cr4;
> + v->arch.hvm_vcpu.guest_efer = regs->efer;
> + }
> + break;
> +
> + case VCPU_HVM_MODE_64B:
> + {
> + const struct vcpu_hvm_x86_64 *regs = &ctx->cpu_regs.x86_64;
> +
> + /* Basic sanity checks. */
> + if ( !is_canonical_address(regs->rip) )
> + {
> + gprintk(XENLOG_ERR, "RIP contains a non-canonical address\n");
> + return -EINVAL;
> + }
> +
> + if ( !(regs->cr0 & X86_CR0_PG) )
> + {
> + gprintk(XENLOG_ERR, "CR0 doesn't have paging enabled\n");
> + return -EINVAL;
> + }
> +
> + if ( !(regs->cr4 & X86_CR4_PAE) )
> + {
> + gprintk(XENLOG_ERR, "CR4 doesn't have PAE enabled\n");
> + return -EINVAL;
> + }
> +
> + if ( (regs->efer & (EFER_LME | EFER_LMA)) != (EFER_LME | EFER_LMA) )
> + {
> + gprintk(XENLOG_ERR, "EFER doesn't have LME or LMA enabled\n");
> + return -EINVAL;
> + }
> +
> + uregs->rax = regs->rax;
> + uregs->rcx = regs->rcx;
> + uregs->rdx = regs->rdx;
> + uregs->rbx = regs->rbx;
> + uregs->rsp = regs->rsp;
> + uregs->rbp = regs->rbp;
> + uregs->rsi = regs->rsi;
> + uregs->rdi = regs->rdi;
> + uregs->rip = regs->rip;
> + uregs->rflags = regs->rflags;
> +
> + v->arch.hvm_vcpu.guest_cr[0] = regs->cr0;
> + v->arch.hvm_vcpu.guest_cr[3] = regs->cr3;
> + v->arch.hvm_vcpu.guest_cr[4] = regs->cr4;
> + v->arch.hvm_vcpu.guest_efer = regs->efer;
> +
> +#define SEG(b, l, a) \
> + (struct segment_register){ .sel = 0, .base = (b), .limit = (l), \
> + .attr.bytes = (a) }
> + cs = SEG(0, ~0u, 0xa9b); /* 64bit code segment. */
> + ds = ss = es = SEG(0, ~0u, 0xc93);
> + tr = SEG(0, 0x67, 0x8b); /* 64bit TSS (busy). */
> +#undef SEG
I would be tempted to get rid of this macro entirely. The other macro
was to hide all the regs-> references, but this is entirely from constants.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
2015-10-05 10:28 ` Andrew Cooper
@ 2015-10-08 13:35 ` Roger Pau Monné
2015-10-08 15:21 ` Jan Beulich
0 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-08 13:35 UTC (permalink / raw)
To: Andrew Cooper, xen-devel; +Cc: Stefano Stabellini, Ian Campbell, Jan Beulich
El 05/10/15 a les 12.28, Andrew Cooper ha escrit:
> On 02/10/15 16:48, 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>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@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>
>> ---
>> Changes since v6:
>> - Add comments to clarify some initializations.
>> - Introduce a generic default_initialize_vcpu that's used to initialize a
>> ARM vCPU or a x86 PV vCPU.
>> - Move the undef of the SEG macro.
>> - Fix the size of the eflags register, it should be 32bits.
>> - Add a comment regarding the value of the 12-15 bits of the _ar fields.
>> - Remove the 16bit strucutre, the 32bit one can be used to start the cpu in
>> real mode.
>> - Add some sanity checks to the values passed in.
>> - Add paddings to vcpu_hvm_context so the layout on 32/64bits is the same.
>> - Add support for the compat version of VCPUOP_initialise.
>>
>> Changes since v5:
>> - Fix a coding style issue.
>> - Merge the code from wip-dmlite-v5-refactor by Andrew in order to reduce
>> bloat.
>> - Print the offending %cr3 in case of error when using shadow.
>> - Reduce the scope of local variables in arch_initialize_vcpu.
>> - s/current->domain/v->domain/g in arch_initialize_vcpu.
>> - Expand the comment in public/vcpu.h to document the usage of
>> vcpu_hvm_context for HVM guests.
>> - Add myself as the copyright holder for the public hvm_vcpu.h header.
>>
>> Changes since v4:
>> - Don't assume mode is 64B, add an explicit check.
>> - Don't set TF_kernel_mode, it is only needed for PV guests.
>> - Don't set CR0_ET unconditionally.
>> ---
>> xen/arch/x86/domain.c | 185 ++++++++++++++++++++++++++++++++++++++
>> xen/arch/x86/hvm/hvm.c | 8 ++
>> xen/common/compat/domain.c | 71 +++++++++++----
>> xen/common/domain.c | 56 +++++++++---
>> xen/include/Makefile | 1 +
>> xen/include/asm-x86/domain.h | 3 +
>> xen/include/public/hvm/hvm_vcpu.h | 144 +++++++++++++++++++++++++++++
>> xen/include/public/vcpu.h | 6 +-
>> xen/include/xlat.lst | 3 +
>> 9 files changed, 448 insertions(+), 29 deletions(-)
>> create mode 100644 xen/include/public/hvm/hvm_vcpu.h
>>
>> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
>> index a3b1c9b..af5feea 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>
>> @@ -1176,6 +1177,190 @@ int arch_set_info_guest(
>> #undef c
>> }
>>
>> +/* Called by VCPUOP_initialise for HVM guests. */
>> +int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx)
>> +{
>> + struct cpu_user_regs *uregs = &v->arch.user_regs;
>> + struct segment_register cs, ds, ss, es, tr;
>> +
>> + switch ( ctx->mode )
>> + {
>> + default:
>> + return -EINVAL;
>> +
>> + case VCPU_HVM_MODE_32B:
>> + {
>> + const struct vcpu_hvm_x86_32 *regs = &ctx->cpu_regs.x86_32;
>> + uint32_t limit;
>> +
>> +#define SEG(s, r) \
>> + (struct segment_register){ .sel = 0, .base = (r)->s ## _base, \
>> + .limit = (r)->s ## _limit, .attr.bytes = (r)->s ## _ar }
>> + cs = SEG(cs, regs);
>> + ds = SEG(ds, regs);
>> + ss = SEG(ss, regs);
>> + es = SEG(es, regs);
>> + tr = SEG(tr, regs);
>> +#undef SEG
>> +
>> + /* Basic sanity checks. */
>> + if ( cs.attr.fields.pad != 0 || ds.attr.fields.pad != 0 ||
>> + ss.attr.fields.pad != 0 || es.attr.fields.pad != 0 ||
>> + tr.attr.fields.pad != 0 )
>> + {
>> + gprintk(XENLOG_ERR, "Attribute bits 12-15 of the segments are not null\n");
>
> I would use 'zero' as opposed to 'null' here. There is nothing to do
> with pointers here.
Done.
>> + return -EINVAL;
>> + }
>> +
>> + limit = cs.limit * (cs.attr.fields.g ? PAGE_SIZE : 1);
>
> This will overflow in the common case. Calculation of the limit is a
> little awkward. I believe this should do:
>
> limit = cs.limit
> if ( cs.attr.fields.g )
> limit = (limit << 12) | 0xfff;
>
> In the case that g is set and cs is a flat segment, limit should have
> the value ~0U, rather than 0 which is what your calculation will achieve.
Fixed.
>> + if ( regs->eip > limit )
>> + {
>> + gprintk(XENLOG_ERR, "EIP address is outside of the CS limit\n");
>
> In all cases, please print out the values, to make the error message
> more helpful.
>
> e.g. "EIP (%08x) outside CS limit (%08x)"
>
>> + return -EINVAL;
>> + }
>> +
>> + if ( ds.attr.fields.dpl > cs.attr.fields.dpl )
>> + {
>> + gprintk(XENLOG_ERR, "DPL of DS is greater than DPL of CS\n");
>> + return -EINVAL;
>> + }
>> +
>> + if ( ss.attr.fields.dpl != cs.attr.fields.dpl )
>> + {
>> + gprintk(XENLOG_ERR, "DPL of SS is different than DPL of CS\n");
>> + return -EINVAL;
>> + }
>> +
>> + if ( es.attr.fields.dpl > cs.attr.fields.dpl )
>> + {
>> + gprintk(XENLOG_ERR, "DPL of ES is greater than DPL of CS\n");
>> + return -EINVAL;
>> + }
>> +
>> + if ( ((regs->efer & EFER_LMA) && !(regs->efer & EFER_LME)) ||
>> + ((regs->efer & EFER_LME) && !(regs->efer & EFER_LMA)) )
>
> This simplifies to ( (!!(regs->efer & EFER_LMA)) ^ (!!(regs->efer &
> EFER_LME)) )
>
>> + {
>> + gprintk(XENLOG_ERR, "EFER.LMA and EFER.LME must be both set\n");
>
> And this should say "both the same", rather than both set.
I've fixed all the error messages to be more descriptive.
> Having said this, I still don't think it is sensible to require that LMA
> is set, seeing as it is strictly a read-only bit in EFER. I would
> suggest keying on LME alone, and automatically ORing in LMA, which
> matches the behaviour of hardware more closely.
I've done as suggested and made LMA optional, Xen will set it by default
when LME is set by the user.
>> + return -EINVAL;
>> + }
>> +
>> + uregs->rax = regs->eax;
>> + uregs->rcx = regs->ecx;
>> + uregs->rdx = regs->edx;
>> + uregs->rbx = regs->ebx;
>> + uregs->rsp = regs->esp;
>> + uregs->rbp = regs->ebp;
>> + uregs->rsi = regs->esi;
>> + uregs->rdi = regs->edi;
>> + uregs->rip = regs->eip;
>> + uregs->rflags = regs->eflags;
>> +
>> + v->arch.hvm_vcpu.guest_cr[0] = regs->cr0;
>> + v->arch.hvm_vcpu.guest_cr[3] = regs->cr3;
>> + v->arch.hvm_vcpu.guest_cr[4] = regs->cr4;
>> + v->arch.hvm_vcpu.guest_efer = regs->efer;
>> + }
>> + break;
>> +
>> + case VCPU_HVM_MODE_64B:
>> + {
>> + const struct vcpu_hvm_x86_64 *regs = &ctx->cpu_regs.x86_64;
>> +
>> + /* Basic sanity checks. */
>> + if ( !is_canonical_address(regs->rip) )
>> + {
>> + gprintk(XENLOG_ERR, "RIP contains a non-canonical address\n");
>> + return -EINVAL;
>> + }
>> +
>> + if ( !(regs->cr0 & X86_CR0_PG) )
>> + {
>> + gprintk(XENLOG_ERR, "CR0 doesn't have paging enabled\n");
>> + return -EINVAL;
>> + }
>> +
>> + if ( !(regs->cr4 & X86_CR4_PAE) )
>> + {
>> + gprintk(XENLOG_ERR, "CR4 doesn't have PAE enabled\n");
>> + return -EINVAL;
>> + }
>> +
>> + if ( (regs->efer & (EFER_LME | EFER_LMA)) != (EFER_LME | EFER_LMA) )
>> + {
>> + gprintk(XENLOG_ERR, "EFER doesn't have LME or LMA enabled\n");
>> + return -EINVAL;
>> + }
>> +
>> + uregs->rax = regs->rax;
>> + uregs->rcx = regs->rcx;
>> + uregs->rdx = regs->rdx;
>> + uregs->rbx = regs->rbx;
>> + uregs->rsp = regs->rsp;
>> + uregs->rbp = regs->rbp;
>> + uregs->rsi = regs->rsi;
>> + uregs->rdi = regs->rdi;
>> + uregs->rip = regs->rip;
>> + uregs->rflags = regs->rflags;
>> +
>> + v->arch.hvm_vcpu.guest_cr[0] = regs->cr0;
>> + v->arch.hvm_vcpu.guest_cr[3] = regs->cr3;
>> + v->arch.hvm_vcpu.guest_cr[4] = regs->cr4;
>> + v->arch.hvm_vcpu.guest_efer = regs->efer;
>> +
>> +#define SEG(b, l, a) \
>> + (struct segment_register){ .sel = 0, .base = (b), .limit = (l), \
>> + .attr.bytes = (a) }
>> + cs = SEG(0, ~0u, 0xa9b); /* 64bit code segment. */
>> + ds = ss = es = SEG(0, ~0u, 0xc93);
>> + tr = SEG(0, 0x67, 0x8b); /* 64bit TSS (busy). */
>> +#undef SEG
>
> I would be tempted to get rid of this macro entirely. The other macro
> was to hide all the regs-> references, but this is entirely from constants.
IMHO I think it makes the code easier to understand, but I'm not going
to argue about it. Does anyone else has a preference whether to remove
the macro or not?
Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
2015-10-08 13:35 ` Roger Pau Monné
@ 2015-10-08 15:21 ` Jan Beulich
2015-10-08 15:33 ` Andrew Cooper
0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-10-08 15:21 UTC (permalink / raw)
To: Andrew Cooper, Roger Pau Monné
Cc: xen-devel, Stefano Stabellini, Ian Campbell
>>> On 08.10.15 at 15:35, <roger.pau@citrix.com> wrote:
> El 05/10/15 a les 12.28, Andrew Cooper ha escrit:
>> On 02/10/15 16:48, Roger Pau Monne wrote:
>>> +#define SEG(b, l, a) \
>>> + (struct segment_register){ .sel = 0, .base = (b), .limit = (l), \
>>> + .attr.bytes = (a) }
>>> + cs = SEG(0, ~0u, 0xa9b); /* 64bit code segment. */
>>> + ds = ss = es = SEG(0, ~0u, 0xc93);
>>> + tr = SEG(0, 0x67, 0x8b); /* 64bit TSS (busy). */
>>> +#undef SEG
>>
>> I would be tempted to get rid of this macro entirely. The other macro
>> was to hide all the regs-> references, but this is entirely from constants.
>
> IMHO I think it makes the code easier to understand, but I'm not going
> to argue about it. Does anyone else has a preference whether to remove
> the macro or not?
I'd be slightly in favor of keeping it, unless Andrew is heavily opposed.
Jan
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
2015-10-08 15:21 ` Jan Beulich
@ 2015-10-08 15:33 ` Andrew Cooper
0 siblings, 0 replies; 105+ messages in thread
From: Andrew Cooper @ 2015-10-08 15:33 UTC (permalink / raw)
To: Jan Beulich, Roger Pau Monné
Cc: xen-devel, Stefano Stabellini, Ian Campbell
On 08/10/15 16:21, Jan Beulich wrote:
>>>> On 08.10.15 at 15:35, <roger.pau@citrix.com> wrote:
>> El 05/10/15 a les 12.28, Andrew Cooper ha escrit:
>>> On 02/10/15 16:48, Roger Pau Monne wrote:
>>>> +#define SEG(b, l, a) \
>>>> + (struct segment_register){ .sel = 0, .base = (b), .limit = (l), \
>>>> + .attr.bytes = (a) }
>>>> + cs = SEG(0, ~0u, 0xa9b); /* 64bit code segment. */
>>>> + ds = ss = es = SEG(0, ~0u, 0xc93);
>>>> + tr = SEG(0, 0x67, 0x8b); /* 64bit TSS (busy). */
>>>> +#undef SEG
>>> I would be tempted to get rid of this macro entirely. The other macro
>>> was to hide all the regs-> references, but this is entirely from constants.
>> IMHO I think it makes the code easier to understand, but I'm not going
>> to argue about it. Does anyone else has a preference whether to remove
>> the macro or not?
> I'd be slightly in favor of keeping it, unless Andrew is heavily opposed.
Not sufficiently fussed. Keep it.
~Andrew
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
2015-10-02 15:48 ` [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs Roger Pau Monne
2015-10-05 10:28 ` Andrew Cooper
@ 2015-10-19 15:48 ` Jan Beulich
2015-11-05 12:06 ` Roger Pau Monné
1 sibling, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2015-10-19 15:48 UTC (permalink / raw)
To: Roger Pau Monne
Cc: Andrew Cooper, Stefano Stabellini, Ian Campbell, xen-devel
>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
> @@ -1176,6 +1177,190 @@ int arch_set_info_guest(
> #undef c
> }
>
> +/* Called by VCPUOP_initialise for HVM guests. */
> +int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx)
const ... *ctx
> +{
> + struct cpu_user_regs *uregs = &v->arch.user_regs;
> + struct segment_register cs, ds, ss, es, tr;
> +
> + switch ( ctx->mode )
> + {
> + default:
> + return -EINVAL;
> +
> + case VCPU_HVM_MODE_32B:
> + {
> + const struct vcpu_hvm_x86_32 *regs = &ctx->cpu_regs.x86_32;
> + uint32_t limit;
> +
> +#define SEG(s, r) \
> + (struct segment_register){ .sel = 0, .base = (r)->s ## _base, \
> + .limit = (r)->s ## _limit, .attr.bytes = (r)->s ## _ar }
> + cs = SEG(cs, regs);
> + ds = SEG(ds, regs);
> + ss = SEG(ss, regs);
> + es = SEG(es, regs);
> + tr = SEG(tr, regs);
> +#undef SEG
> +
> + /* Basic sanity checks. */
> + if ( cs.attr.fields.pad != 0 || ds.attr.fields.pad != 0 ||
> + ss.attr.fields.pad != 0 || es.attr.fields.pad != 0 ||
> + tr.attr.fields.pad != 0 )
> + {
> + gprintk(XENLOG_ERR, "Attribute bits 12-15 of the segments are not null\n");
> + return -EINVAL;
> + }
> +
> + limit = cs.limit * (cs.attr.fields.g ? PAGE_SIZE : 1);
> + if ( regs->eip > limit )
> + {
> + gprintk(XENLOG_ERR, "EIP address is outside of the CS limit\n");
> + return -EINVAL;
> + }
> +
> + if ( ds.attr.fields.dpl > cs.attr.fields.dpl )
Checks like this imo need to take into account cases where the effect
of a null selector loaded into the register is intended (in which case I
would assume DPL to not matter). Speaking of which - with all these
DPL checks done, what about non-code segments loaded into CS or
other illegal things? Question is whether the
hvm_set_segment_register() calls below could be made take care of
these instead of having to enumerate everything here.
> --- a/xen/common/compat/domain.c
> +++ b/xen/common/compat/domain.c
> @@ -10,6 +10,9 @@
> #include <xen/guest_access.h>
> #include <xen/hypercall.h>
> #include <compat/vcpu.h>
> +#ifdef CONFIG_X86
> +#include <compat/hvm/hvm_vcpu.h>
> +#endif
I'd avoid such #if-s in this file, since it's only x86 that uses compat
code right now.
> --- a/xen/common/domain.c
> +++ b/xen/common/domain.c
> @@ -1207,11 +1207,35 @@ void unmap_vcpu_info(struct vcpu *v)
> put_page_and_type(mfn_to_page(mfn));
> }
>
> +static int default_initialize_vcpu(struct vcpu *v,
> + XEN_GUEST_HANDLE_PARAM(void) arg)
> +{
> + struct vcpu_guest_context *ctxt;
> + struct domain *d = v->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;
> +}
> +
> 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 )
> @@ -1223,20 +1247,28 @@ 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) )
> +#if defined(CONFIG_X86)
Looks like you went from one extreme to the other: Now there's no
per-arch function anymore, and hence you need this ugly #ifdef-ery.
Why don't you add default_initialize_vcpu() as a non-static function,
to be called by or (on ARM) used as arch_initialize_vcpu()?
> --- a/xen/include/asm-x86/domain.h
> +++ b/xen/include/asm-x86/domain.h
> @@ -10,6 +10,7 @@
> #include <asm/mce.h>
> #include <public/vcpu.h>
> #include <public/hvm/hvm_info_table.h>
> +#include <public/hvm/hvm_vcpu.h>
Please avoid this in headers so widely included:
> @@ -599,6 +600,8 @@ static inline void free_vcpu_guest_context(struct vcpu_guest_context *vgc)
> vfree(vgc);
> }
>
> +int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx);
If you replace the typedef name by the actual structure, and if you
forward declare the structure, you don't have any build issue, but
you will avoid almost every file including the new header.
> +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;
> + uint32_t eflags;
> +
> + uint32_t cr0;
> + uint32_t cr3;
> + uint32_t cr4;
> +
> + uint32_t pad1;
> +
> + /*
> + * EFER should only be used to set the NXE bit (if required)
> + * when starting a vCPU in 32bit mode with paging enabled or
> + * to set the LME/LMA bits in order to start the vCPU in
> + * compatibility mode.
> + */
> + uint64_t efer;
> +
> + uint32_t cs_base;
> + uint32_t ds_base;
> + uint32_t ss_base;
> + uint32_t es_base;
> + uint32_t tr_base;
> + uint32_t cs_limit;
> + uint32_t ds_limit;
> + uint32_t ss_limit;
> + uint32_t es_limit;
> + uint32_t tr_limit;
> + uint16_t cs_ar;
> + uint16_t ds_ar;
> + uint16_t ss_ar;
> + uint16_t es_ar;
> + uint16_t tr_ar;
> +
> + uint16_t pad2[2];
[3] perhaps?
Also I don't think I've seen you check these padding fields to be zero,
implying that we wouldn't be able to assign meaning to them later on.
> --- a/xen/include/xlat.lst
> +++ b/xen/include/xlat.lst
> @@ -56,6 +56,9 @@
> ? grant_entry_header grant_table.h
> ? grant_entry_v2 grant_table.h
> ? gnttab_swap_grant_ref grant_table.h
> +? vcpu_hvm_context hvm/hvm_vcpu.h
> +? vcpu_hvm_x86_32 hvm/hvm_vcpu.h
> +? vcpu_hvm_x86_64 hvm/hvm_vcpu.h
Do you really need all three added here, instead of just the
top level one?
Jan
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs
2015-10-19 15:48 ` Jan Beulich
@ 2015-11-05 12:06 ` Roger Pau Monné
0 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-11-05 12:06 UTC (permalink / raw)
To: Jan Beulich; +Cc: Andrew Cooper, Stefano Stabellini, Ian Campbell, xen-devel
El 19/10/15 a les 17.48, Jan Beulich ha escrit:
>>>> On 02.10.15 at 17:48, <roger.pau@citrix.com> wrote:
>> @@ -1176,6 +1177,190 @@ int arch_set_info_guest(
>> #undef c
>> }
>>
>> +/* Called by VCPUOP_initialise for HVM guests. */
>> +int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx)
>
> const ... *ctx
Sure.
>> +{
>> + struct cpu_user_regs *uregs = &v->arch.user_regs;
>> + struct segment_register cs, ds, ss, es, tr;
>> +
>> + switch ( ctx->mode )
>> + {
>> + default:
>> + return -EINVAL;
>> +
>> + case VCPU_HVM_MODE_32B:
>> + {
>> + const struct vcpu_hvm_x86_32 *regs = &ctx->cpu_regs.x86_32;
>> + uint32_t limit;
>> +
>> +#define SEG(s, r) \
>> + (struct segment_register){ .sel = 0, .base = (r)->s ## _base, \
>> + .limit = (r)->s ## _limit, .attr.bytes = (r)->s ## _ar }
>> + cs = SEG(cs, regs);
>> + ds = SEG(ds, regs);
>> + ss = SEG(ss, regs);
>> + es = SEG(es, regs);
>> + tr = SEG(tr, regs);
>> +#undef SEG
>> +
>> + /* Basic sanity checks. */
>> + if ( cs.attr.fields.pad != 0 || ds.attr.fields.pad != 0 ||
>> + ss.attr.fields.pad != 0 || es.attr.fields.pad != 0 ||
>> + tr.attr.fields.pad != 0 )
>> + {
>> + gprintk(XENLOG_ERR, "Attribute bits 12-15 of the segments are not null\n");
>> + return -EINVAL;
>> + }
>> +
>> + limit = cs.limit * (cs.attr.fields.g ? PAGE_SIZE : 1);
>> + if ( regs->eip > limit )
>> + {
>> + gprintk(XENLOG_ERR, "EIP address is outside of the CS limit\n");
>> + return -EINVAL;
>> + }
>> +
>> + if ( ds.attr.fields.dpl > cs.attr.fields.dpl )
>
> Checks like this imo need to take into account cases where the effect
> of a null selector loaded into the register is intended (in which case I
> would assume DPL to not matter). Speaking of which - with all these
> DPL checks done, what about non-code segments loaded into CS or
> other illegal things? Question is whether the
> hvm_set_segment_register() calls below could be made take care of
> these instead of having to enumerate everything here.
hvm_set_segment_register is just an inline wrapper around
hvm_funcs.set_segment_register. I could turn that into a proper function
with checks, but it's a shame because hvm_load_segment_selector also
performs some of this checks, but it requires a valid GDT to be loaded
in order to use it which we don't have.
I don't mind adding some more checks to the current ones:
- Check that all segments that are not null selectors have the
'present' bit set.
- Check that CS.type matches a code segment.
- Check that all segments except CS don't have the 'code' type.
- Don't perform the DPL check if the segment is a null selector.
I'm adding a small inline stub to do this checks.
>> --- a/xen/common/compat/domain.c
>> +++ b/xen/common/compat/domain.c
>> @@ -10,6 +10,9 @@
>> #include <xen/guest_access.h>
>> #include <xen/hypercall.h>
>> #include <compat/vcpu.h>
>> +#ifdef CONFIG_X86
>> +#include <compat/hvm/hvm_vcpu.h>
>> +#endif
>
> I'd avoid such #if-s in this file, since it's only x86 that uses compat
> code right now.
OK, knowing that the compat code is only used in x86 helps to simplify
some of this code also.
>> --- a/xen/common/domain.c
>> +++ b/xen/common/domain.c
>> @@ -1207,11 +1207,35 @@ void unmap_vcpu_info(struct vcpu *v)
>> put_page_and_type(mfn_to_page(mfn));
>> }
>>
>> +static int default_initialize_vcpu(struct vcpu *v,
>> + XEN_GUEST_HANDLE_PARAM(void) arg)
>> +{
>> + struct vcpu_guest_context *ctxt;
>> + struct domain *d = v->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;
>> +}
>> +
>> 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 )
>> @@ -1223,20 +1247,28 @@ 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) )
>> +#if defined(CONFIG_X86)
>
> Looks like you went from one extreme to the other: Now there's no
> per-arch function anymore, and hence you need this ugly #ifdef-ery.
> Why don't you add default_initialize_vcpu() as a non-static function,
> to be called by or (on ARM) used as arch_initialize_vcpu()?
OK, I think I've managed to fix some of this mess by re-adding the
arch_initialize_vcpu function, at least we don't have all this
ifdef-ery in the common domain.c any more.
>> --- a/xen/include/asm-x86/domain.h
>> +++ b/xen/include/asm-x86/domain.h
>> @@ -10,6 +10,7 @@
>> #include <asm/mce.h>
>> #include <public/vcpu.h>
>> #include <public/hvm/hvm_info_table.h>
>> +#include <public/hvm/hvm_vcpu.h>
>
> Please avoid this in headers so widely included:
>
>> @@ -599,6 +600,8 @@ static inline void free_vcpu_guest_context(struct vcpu_guest_context *vgc)
>> vfree(vgc);
>> }
>>
>> +int arch_set_info_hvm_guest(struct vcpu *v, vcpu_hvm_context_t *ctx);
>
> If you replace the typedef name by the actual structure, and if you
> forward declare the structure, you don't have any build issue, but
> you will avoid almost every file including the new header.
Done.
>
>> +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;
>> + uint32_t eflags;
>> +
>> + uint32_t cr0;
>> + uint32_t cr3;
>> + uint32_t cr4;
>> +
>> + uint32_t pad1;
>> +
>> + /*
>> + * EFER should only be used to set the NXE bit (if required)
>> + * when starting a vCPU in 32bit mode with paging enabled or
>> + * to set the LME/LMA bits in order to start the vCPU in
>> + * compatibility mode.
>> + */
>> + uint64_t efer;
>> +
>> + uint32_t cs_base;
>> + uint32_t ds_base;
>> + uint32_t ss_base;
>> + uint32_t es_base;
>> + uint32_t tr_base;
>> + uint32_t cs_limit;
>> + uint32_t ds_limit;
>> + uint32_t ss_limit;
>> + uint32_t es_limit;
>> + uint32_t tr_limit;
>> + uint16_t cs_ar;
>> + uint16_t ds_ar;
>> + uint16_t ss_ar;
>> + uint16_t es_ar;
>> + uint16_t tr_ar;
>> +
>> + uint16_t pad2[2];
>
> [3] perhaps?
Right, not sure why I've missed that one, probably changed some fields
and I didn't update the explicit padding to match.
>
> Also I don't think I've seen you check these padding fields to be zero,
> implying that we wouldn't be able to assign meaning to them later on.
Done.
>
>> --- a/xen/include/xlat.lst
>> +++ b/xen/include/xlat.lst
>> @@ -56,6 +56,9 @@
>> ? grant_entry_header grant_table.h
>> ? grant_entry_v2 grant_table.h
>> ? gnttab_swap_grant_ref grant_table.h
>> +? vcpu_hvm_context hvm/hvm_vcpu.h
>> +? vcpu_hvm_x86_32 hvm/hvm_vcpu.h
>> +? vcpu_hvm_x86_64 hvm/hvm_vcpu.h
>
> Do you really need all three added here, instead of just the
> top level one?
Unless I add all 3 here I get the following error:
/root/src/xen/xen/include/compat/xlat.h:540:5: error: data definition has no type or storage class [-Werror]
CHECK_compat_vcpu_hvm_x86_32; \
^
domain.c:30:1: note: in expansion of macro ‘CHECK_vcpu_hvm_context’
CHECK_vcpu_hvm_context;
^
/root/src/xen/xen/include/compat/xlat.h:540:5: error: type defaults to ‘int’ in declaration of ‘CHECK_compat_vcpu_hvm_x86_32’ [-Werror]
CHECK_compat_vcpu_hvm_x86_32; \
^
domain.c:30:1: note: in expansion of macro ‘CHECK_vcpu_hvm_context’
CHECK_vcpu_hvm_context;
^
/root/src/xen/xen/include/compat/xlat.h:541:5: error: data definition has no type or storage class [-Werror]
CHECK_compat_vcpu_hvm_x86_64
^
domain.c:30:1: note: in expansion of macro ‘CHECK_vcpu_hvm_context’
CHECK_vcpu_hvm_context;
^
/root/src/xen/xen/include/compat/xlat.h:541:5: error: type defaults to ‘int’ in declaration of ‘CHECK_compat_vcpu_hvm_x86_64’ [-Werror]
CHECK_compat_vcpu_hvm_x86_64
^
domain.c:30:1: note: in expansion of macro ‘CHECK_vcpu_hvm_context’
CHECK_vcpu_hvm_context;
^
cc1: all warnings being treated as errors
Thanks, Roger.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 28/32] xenconsole: try to attach to PV console if HVM fails
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (26 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 27/32] xen/x86: allow HVM guests to use hypercalls to bring up vCPUs Roger Pau Monne
@ 2015-10-02 15:48 ` Roger Pau Monne
2015-10-02 15:49 ` [PATCH v7 29/32] libxc/xen: introduce a start info structure for HVMlite guests Roger Pau Monne
` (4 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:48 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>
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 v4:
- Add Wei Liu Acked-by.
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] 105+ messages in thread
* [PATCH v7 29/32] libxc/xen: introduce a start info structure for HVMlite guests
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (27 preceding siblings ...)
2015-10-02 15:48 ` [PATCH v7 28/32] xenconsole: try to attach to PV console if HVM fails Roger Pau Monne
@ 2015-10-02 15:49 ` Roger Pau Monne
2015-10-05 10:36 ` Andrew Cooper
2015-10-06 9:26 ` Wei Liu
2015-10-02 15:49 ` [PATCH v7 30/32] libxc: switch xc_dom_elfloader to be used with HVMlite domains Roger Pau Monne
` (3 subsequent siblings)
32 siblings, 2 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:49 UTC (permalink / raw)
To: xen-devel
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
Ian Jackson, Jan Beulich, Roger Pau Monne
This structure contains the physical address of the command line, as well as
the physical address of the list of loaded modules. The physical address of
this structure is passed to the guest at boot time in the %ebx register.
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 v6:
- Add a check to make sure the start info data is placed below 4GB.
- Make sure byte addresses are treated as uintptr_t.
- Fix single-line comment.
Changes since v5:
- Change some of the calculations performed to get the total size of the
start_info region.
- Replace the mention of HVMlite in a comment with PVH.
- Don't use 64bit integers in hvm_modlist_entry.
---
tools/libxc/xc_dom_x86.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++-
xen/include/public/xen.h | 17 ++++++++++++
2 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 85b8288..20a39b7 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -561,7 +561,70 @@ 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->device_model )
+ if ( !dom->device_model )
+ {
+ struct xc_dom_seg seg;
+ struct hvm_start_info *start_info;
+ char *cmdline;
+ struct hvm_modlist_entry *modlist;
+ void *start_page;
+ size_t cmdline_size = 0;
+ size_t start_info_size = sizeof(*start_info);
+
+ if ( dom->cmdline )
+ {
+ cmdline_size = ROUNDUP(strlen(dom->cmdline) + 1, 8);
+ start_info_size += cmdline_size;
+
+ }
+ if ( dom->ramdisk_blob )
+ start_info_size += sizeof(*modlist); /* Limited to one module. */
+
+ rc = xc_dom_alloc_segment(dom, &seg, "HVMlite start info", 0,
+ start_info_size);
+ if ( rc != 0 )
+ {
+ DOMPRINTF("Unable to reserve memory for the start info");
+ goto out;
+ }
+
+ start_page = xc_map_foreign_range(xch, domid, start_info_size,
+ PROT_READ | PROT_WRITE,
+ seg.pfn);
+ if ( start_page == NULL )
+ {
+ DOMPRINTF("Unable to map HVM start info page");
+ goto error_out;
+ }
+
+ start_info = start_page;
+ cmdline = start_page + sizeof(*start_info);
+ modlist = start_page + sizeof(*start_info) + cmdline_size;
+
+ if ( dom->cmdline )
+ {
+ strncpy(cmdline, dom->cmdline, MAX_GUEST_CMDLINE);
+ cmdline[MAX_GUEST_CMDLINE - 1] = '\0';
+ start_info->cmdline_paddr = (seg.pfn << PAGE_SHIFT) +
+ ((uintptr_t)cmdline - (uintptr_t)start_info);
+ }
+
+ if ( dom->ramdisk_blob )
+ {
+ modlist[0].paddr = dom->ramdisk_seg.vstart - dom->parms.virt_base;
+ modlist[0].size = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
+ start_info->modlist_paddr = (seg.pfn << PAGE_SHIFT) +
+ ((uintptr_t)modlist - (uintptr_t)start_info);
+ start_info->nr_modules = 1;
+ }
+
+ start_info->magic = HVM_START_MAGIC_VALUE;
+
+ munmap(start_page, start_info_size);
+
+ dom->start_info_pfn = seg.pfn;
+ }
+ else
{
/*
* Allocate and clear additional ioreq server pages. The default
@@ -915,6 +978,9 @@ static int vcpu_hvm(struct xc_dom_image *dom)
/* Set the IP. */
bsp_ctx.cpu.rip = dom->parms.phys_entry;
+ if ( dom->start_info_pfn )
+ bsp_ctx.cpu.rbx = dom->start_info_pfn << PAGE_SHIFT;
+
/* Set the end descriptor. */
bsp_ctx.end_d.typecode = HVM_SAVE_CODE(END);
bsp_ctx.end_d.instance = 0;
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index ff5547e..709e12c 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -784,6 +784,23 @@ struct start_info {
};
typedef struct start_info start_info_t;
+/* Start of day structure passed to PVH guests in %ebx. */
+struct hvm_start_info {
+#define HVM_START_MAGIC_VALUE 0x336ec578
+ uint32_t magic; /* Contains the magic value 0x336ec578 */
+ /* ("xEn3" with the 0x80 bit of the "E" set).*/
+ uint32_t flags; /* SIF_xxx flags. */
+ uint32_t cmdline_paddr; /* Physical address of the command line. */
+ uint32_t nr_modules; /* Number of modules passed to the kernel. */
+ uint32_t modlist_paddr; /* Physical address of an array of */
+ /* hvm_modlist_entry. */
+};
+
+struct hvm_modlist_entry {
+ uint32_t paddr; /* Physical address of the module. */
+ uint32_t size; /* Size of the module in bytes. */
+};
+
/* New console union for dom0 introduced in 0x00030203. */
#if __XEN_INTERFACE_VERSION__ < 0x00030203
#define console_mfn console.domU.mfn
--
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] 105+ messages in thread
* Re: [PATCH v7 29/32] libxc/xen: introduce a start info structure for HVMlite guests
2015-10-02 15:49 ` [PATCH v7 29/32] libxc/xen: introduce a start info structure for HVMlite guests Roger Pau Monne
@ 2015-10-05 10:36 ` Andrew Cooper
2015-10-05 16:47 ` Roger Pau Monné
2015-10-06 9:26 ` Wei Liu
1 sibling, 1 reply; 105+ messages in thread
From: Andrew Cooper @ 2015-10-05 10:36 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel
Cc: Wei Liu, Ian Jackson, Ian Campbell, Jan Beulich,
Stefano Stabellini
On 02/10/15 16:49, Roger Pau Monne wrote:
> This structure contains the physical address of the command line, as well as
> the physical address of the list of loaded modules. The physical address of
> this structure is passed to the guest at boot time in the %ebx register.
>
> 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 v6:
> - Add a check to make sure the start info data is placed below 4GB.
> - Make sure byte addresses are treated as uintptr_t.
> - Fix single-line comment.
>
> Changes since v5:
> - Change some of the calculations performed to get the total size of the
> start_info region.
> - Replace the mention of HVMlite in a comment with PVH.
> - Don't use 64bit integers in hvm_modlist_entry.
> ---
> tools/libxc/xc_dom_x86.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++-
> xen/include/public/xen.h | 17 ++++++++++++
> 2 files changed, 84 insertions(+), 1 deletion(-)
>
> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> index 85b8288..20a39b7 100644
> --- a/tools/libxc/xc_dom_x86.c
> +++ b/tools/libxc/xc_dom_x86.c
> @@ -561,7 +561,70 @@ 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->device_model )
> + if ( !dom->device_model )
> + {
> + struct xc_dom_seg seg;
> + struct hvm_start_info *start_info;
> + char *cmdline;
> + struct hvm_modlist_entry *modlist;
> + void *start_page;
> + size_t cmdline_size = 0;
> + size_t start_info_size = sizeof(*start_info);
> +
> + if ( dom->cmdline )
> + {
> + cmdline_size = ROUNDUP(strlen(dom->cmdline) + 1, 8);
> + start_info_size += cmdline_size;
> +
> + }
> + if ( dom->ramdisk_blob )
> + start_info_size += sizeof(*modlist); /* Limited to one module. */
> +
> + rc = xc_dom_alloc_segment(dom, &seg, "HVMlite start info", 0,
> + start_info_size);
> + if ( rc != 0 )
> + {
> + DOMPRINTF("Unable to reserve memory for the start info");
> + goto out;
> + }
> +
> + start_page = xc_map_foreign_range(xch, domid, start_info_size,
> + PROT_READ | PROT_WRITE,
> + seg.pfn);
> + if ( start_page == NULL )
> + {
> + DOMPRINTF("Unable to map HVM start info page");
> + goto error_out;
> + }
> +
> + start_info = start_page;
You should clear start_info here for sanity sake. There is nothing
which requires the mapped memory to be clear.
> + cmdline = start_page + sizeof(*start_info);
> + modlist = start_page + sizeof(*start_info) + cmdline_size;
> +
> + if ( dom->cmdline )
> + {
> + strncpy(cmdline, dom->cmdline, MAX_GUEST_CMDLINE);
> + cmdline[MAX_GUEST_CMDLINE - 1] = '\0';
> + start_info->cmdline_paddr = (seg.pfn << PAGE_SHIFT) +
> + ((uintptr_t)cmdline - (uintptr_t)start_info);
> + }
> +
> + if ( dom->ramdisk_blob )
> + {
> + modlist[0].paddr = dom->ramdisk_seg.vstart - dom->parms.virt_base;
> + modlist[0].size = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
> + start_info->modlist_paddr = (seg.pfn << PAGE_SHIFT) +
> + ((uintptr_t)modlist - (uintptr_t)start_info);
> + start_info->nr_modules = 1;
> + }
> +
> + start_info->magic = HVM_START_MAGIC_VALUE;
> +
> + munmap(start_page, start_info_size);
> +
> + dom->start_info_pfn = seg.pfn;
> + }
> + else
> {
> /*
> * Allocate and clear additional ioreq server pages. The default
> @@ -915,6 +978,9 @@ static int vcpu_hvm(struct xc_dom_image *dom)
> /* Set the IP. */
> bsp_ctx.cpu.rip = dom->parms.phys_entry;
>
> + if ( dom->start_info_pfn )
> + bsp_ctx.cpu.rbx = dom->start_info_pfn << PAGE_SHIFT;
> +
> /* Set the end descriptor. */
> bsp_ctx.end_d.typecode = HVM_SAVE_CODE(END);
> bsp_ctx.end_d.instance = 0;
> diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
> index ff5547e..709e12c 100644
> --- a/xen/include/public/xen.h
> +++ b/xen/include/public/xen.h
> @@ -784,6 +784,23 @@ struct start_info {
> };
> typedef struct start_info start_info_t;
>
> +/* Start of day structure passed to PVH guests in %ebx. */
> +struct hvm_start_info {
> +#define HVM_START_MAGIC_VALUE 0x336ec578
> + uint32_t magic; /* Contains the magic value 0x336ec578 */
> + /* ("xEn3" with the 0x80 bit of the "E" set).*/
> + uint32_t flags; /* SIF_xxx flags. */
> + uint32_t cmdline_paddr; /* Physical address of the command line. */
> + uint32_t nr_modules; /* Number of modules passed to the kernel. */
> + uint32_t modlist_paddr; /* Physical address of an array of */
> + /* hvm_modlist_entry. */
We should state that nothing will be loaded at 0, so a paddr of 0 means
"not present".
Otherwise,
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] 105+ messages in thread
* Re: [PATCH v7 29/32] libxc/xen: introduce a start info structure for HVMlite guests
2015-10-05 10:36 ` Andrew Cooper
@ 2015-10-05 16:47 ` Roger Pau Monné
0 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-05 16:47 UTC (permalink / raw)
To: Andrew Cooper, xen-devel
Cc: Wei Liu, Ian Jackson, Ian Campbell, Jan Beulich,
Stefano Stabellini
El 05/10/15 a les 12.36, Andrew Cooper ha escrit:
> On 02/10/15 16:49, Roger Pau Monne wrote:
>> This structure contains the physical address of the command line, as well as
>> the physical address of the list of loaded modules. The physical address of
>> this structure is passed to the guest at boot time in the %ebx register.
>>
>> 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 v6:
>> - Add a check to make sure the start info data is placed below 4GB.
>> - Make sure byte addresses are treated as uintptr_t.
>> - Fix single-line comment.
>>
>> Changes since v5:
>> - Change some of the calculations performed to get the total size of the
>> start_info region.
>> - Replace the mention of HVMlite in a comment with PVH.
>> - Don't use 64bit integers in hvm_modlist_entry.
>> ---
>> tools/libxc/xc_dom_x86.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++-
>> xen/include/public/xen.h | 17 ++++++++++++
>> 2 files changed, 84 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
>> index 85b8288..20a39b7 100644
>> --- a/tools/libxc/xc_dom_x86.c
>> +++ b/tools/libxc/xc_dom_x86.c
>> @@ -561,7 +561,70 @@ 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->device_model )
>> + if ( !dom->device_model )
>> + {
>> + struct xc_dom_seg seg;
>> + struct hvm_start_info *start_info;
>> + char *cmdline;
>> + struct hvm_modlist_entry *modlist;
>> + void *start_page;
>> + size_t cmdline_size = 0;
>> + size_t start_info_size = sizeof(*start_info);
>> +
>> + if ( dom->cmdline )
>> + {
>> + cmdline_size = ROUNDUP(strlen(dom->cmdline) + 1, 8);
>> + start_info_size += cmdline_size;
>> +
>> + }
>> + if ( dom->ramdisk_blob )
>> + start_info_size += sizeof(*modlist); /* Limited to one module. */
>> +
>> + rc = xc_dom_alloc_segment(dom, &seg, "HVMlite start info", 0,
>> + start_info_size);
>> + if ( rc != 0 )
>> + {
>> + DOMPRINTF("Unable to reserve memory for the start info");
>> + goto out;
>> + }
>> +
>> + start_page = xc_map_foreign_range(xch, domid, start_info_size,
>> + PROT_READ | PROT_WRITE,
>> + seg.pfn);
>> + if ( start_page == NULL )
>> + {
>> + DOMPRINTF("Unable to map HVM start info page");
>> + goto error_out;
>> + }
>> +
>> + start_info = start_page;
>
> You should clear start_info here for sanity sake. There is nothing
> which requires the mapped memory to be clear.
AFAICT xc_dom_alloc_segment already clears the allocated memory.
>
>> + cmdline = start_page + sizeof(*start_info);
>> + modlist = start_page + sizeof(*start_info) + cmdline_size;
>> +
>> + if ( dom->cmdline )
>> + {
>> + strncpy(cmdline, dom->cmdline, MAX_GUEST_CMDLINE);
>> + cmdline[MAX_GUEST_CMDLINE - 1] = '\0';
>> + start_info->cmdline_paddr = (seg.pfn << PAGE_SHIFT) +
>> + ((uintptr_t)cmdline - (uintptr_t)start_info);
>> + }
>> +
>> + if ( dom->ramdisk_blob )
>> + {
>> + modlist[0].paddr = dom->ramdisk_seg.vstart - dom->parms.virt_base;
>> + modlist[0].size = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
>> + start_info->modlist_paddr = (seg.pfn << PAGE_SHIFT) +
>> + ((uintptr_t)modlist - (uintptr_t)start_info);
>> + start_info->nr_modules = 1;
>> + }
>> +
>> + start_info->magic = HVM_START_MAGIC_VALUE;
>> +
>> + munmap(start_page, start_info_size);
>> +
>> + dom->start_info_pfn = seg.pfn;
>> + }
>> + else
>> {
>> /*
>> * Allocate and clear additional ioreq server pages. The default
>> @@ -915,6 +978,9 @@ static int vcpu_hvm(struct xc_dom_image *dom)
>> /* Set the IP. */
>> bsp_ctx.cpu.rip = dom->parms.phys_entry;
>>
>> + if ( dom->start_info_pfn )
>> + bsp_ctx.cpu.rbx = dom->start_info_pfn << PAGE_SHIFT;
>> +
>> /* Set the end descriptor. */
>> bsp_ctx.end_d.typecode = HVM_SAVE_CODE(END);
>> bsp_ctx.end_d.instance = 0;
>> diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
>> index ff5547e..709e12c 100644
>> --- a/xen/include/public/xen.h
>> +++ b/xen/include/public/xen.h
>> @@ -784,6 +784,23 @@ struct start_info {
>> };
>> typedef struct start_info start_info_t;
>>
>> +/* Start of day structure passed to PVH guests in %ebx. */
>> +struct hvm_start_info {
>> +#define HVM_START_MAGIC_VALUE 0x336ec578
>> + uint32_t magic; /* Contains the magic value 0x336ec578 */
>> + /* ("xEn3" with the 0x80 bit of the "E" set).*/
>> + uint32_t flags; /* SIF_xxx flags. */
>> + uint32_t cmdline_paddr; /* Physical address of the command line. */
>> + uint32_t nr_modules; /* Number of modules passed to the kernel. */
>> + uint32_t modlist_paddr; /* Physical address of an array of */
>> + /* hvm_modlist_entry. */
>
> We should state that nothing will be loaded at 0, so a paddr of 0 means
> "not present".
Will add it to the next version, thanks for the review.
> Otherwise,
>
> 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] 105+ messages in thread
* Re: [PATCH v7 29/32] libxc/xen: introduce a start info structure for HVMlite guests
2015-10-02 15:49 ` [PATCH v7 29/32] libxc/xen: introduce a start info structure for HVMlite guests Roger Pau Monne
2015-10-05 10:36 ` Andrew Cooper
@ 2015-10-06 9:26 ` Wei Liu
1 sibling, 0 replies; 105+ messages in thread
From: Wei Liu @ 2015-10-06 9:26 UTC (permalink / raw)
To: Roger Pau Monne
Cc: Wei Liu, Ian Campbell, Stefano Stabellini, Andrew Cooper,
Ian Jackson, Jan Beulich, xen-devel
On Fri, Oct 02, 2015 at 05:49:00PM +0200, Roger Pau Monne wrote:
> This structure contains the physical address of the command line, as well as
> the physical address of the list of loaded modules. The physical address of
> this structure is passed to the guest at boot time in the %ebx register.
>
> 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>
Since this patch is more about ABI and it has been reviewed by HV
maintainer.
Acked-by: Wei Liu <wei.liu2@citrix.com>
I didn't do a line by line review.
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 30/32] libxc: switch xc_dom_elfloader to be used with HVMlite domains
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (28 preceding siblings ...)
2015-10-02 15:49 ` [PATCH v7 29/32] libxc/xen: introduce a start info structure for HVMlite guests Roger Pau Monne
@ 2015-10-02 15:49 ` Roger Pau Monne
2015-10-02 15:49 ` [PATCH v7 31/32] libxl: allow the creation of HVM domains without a device model Roger Pau Monne
` (2 subsequent siblings)
32 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:49 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>
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>
---
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.
---
Changes since v5:
- Add Wei Liu Ack.
Changes since v4:
- Add Andrew Cooper Reviewed-by.
---
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 82524c9..8ba45ef 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] 105+ messages in thread
* [PATCH v7 31/32] libxl: allow the creation of HVM domains without a device model.
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (29 preceding siblings ...)
2015-10-02 15:49 ` [PATCH v7 30/32] libxc: switch xc_dom_elfloader to be used with HVMlite domains Roger Pau Monne
@ 2015-10-02 15:49 ` Roger Pau Monne
2015-10-08 14:36 ` Ian Campbell
2015-10-02 15:49 ` [PATCH v7 32/32] libxl: add support for migrating HVM guests " Roger Pau Monne
2015-10-08 11:46 ` [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Ian Campbell
32 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:49 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>
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 v5:
- Add Wei Liu Acked-by.
Changes since v4:
- Set dom->mmio_size to match the size of the special pages if there's no
device model for the guest. This implies moving NR_SPECIAL_PAGES and
X86_HVM_END_SPECIAL_REGION to a public header so they can be known by
libxl when creating the memory map.
- Reword the xl.cfg man page description of the "none" device model option.
- Use libxl__device_model_version_running instead of creating a new
function.
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/include/xc_dom.h | 2 ++
tools/libxc/xc_dom_x86.c | 15 ++++-----
tools/libxl/libxl.c | 44 ++++++++++++++++++--------
tools/libxl/libxl_create.c | 16 +++++++++-
tools/libxl/libxl_dm.c | 3 +-
tools/libxl/libxl_dom.c | 74 ++++++++++++++++++++++++++++++--------------
tools/libxl/libxl_internal.h | 9 +++++-
tools/libxl/libxl_types.idl | 1 +
tools/libxl/libxl_x86.c | 15 ++++++---
tools/libxl/xl_cmdimpl.c | 2 ++
11 files changed, 136 insertions(+), 50 deletions(-)
diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index f8fa48f..f627ac6 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -1781,6 +1781,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
+without emulated devices.
+
=back
It is recommended to accept the default value for new guests. If
diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 720b218..4939f76 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -17,6 +17,8 @@
#include <xenguest.h>
#define INVALID_P2M_ENTRY ((xen_pfn_t)-1)
+#define X86_HVM_NR_SPECIAL_PAGES 8
+#define X86_HVM_END_SPECIAL_REGION 0xff000u
/* --- typedefs and structs ---------------------------------------- */
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 20a39b7..c3bb7a3 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -57,8 +57,8 @@
#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 special_pfn(x) \
+ (X86_HVM_END_SPECIAL_REGION - X86_HVM_NR_SPECIAL_PAGES + (x))
#define NR_IOREQ_SERVER_PAGES 8
#define ioreq_server_pfn(x) (special_pfn(0) - NR_IOREQ_SERVER_PAGES + (x))
@@ -517,7 +517,7 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
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 special_array[X86_HVM_NR_SPECIAL_PAGES];
xen_pfn_t ioreq_server_array[NR_IOREQ_SERVER_PAGES];
xc_interface *xch = dom->xch;
@@ -532,18 +532,19 @@ static int alloc_magic_pages_hvm(struct xc_dom_image *dom)
}
/* Allocate and clear special pages. */
- for ( i = 0; i < NR_SPECIAL_PAGES; i++ )
+ for ( i = 0; i < X86_HVM_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);
+ rc = xc_domain_populate_physmap_exact(xch, domid, X86_HVM_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) )
+ if ( xc_clear_domain_pages(xch, domid, special_pfn(0),
+ X86_HVM_NR_SPECIAL_PAGES) )
goto error_out;
xc_hvm_param_set(xch, domid, HVM_PARAM_STORE_PFN,
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index e4ea476..0948b9d 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -1044,11 +1044,14 @@ 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__device_model_version_running(gc, domid) !=
+ LIBXL_DEVICE_MODEL_VERSION_NONE) {
+ 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);
@@ -1597,11 +1600,11 @@ 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);
@@ -3230,7 +3233,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;
@@ -3267,8 +3270,23 @@ 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) {
+ /* Path taken at creation time. */
+ if (info->device_model_version ==
+ LIBXL_DEVICE_MODEL_VERSION_NONE)
+ nic->nictype = LIBXL_NIC_TYPE_VIF;
+ else
+ nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
+ } else {
+ /* Path taken when hot-adding a nic. */
+ if (libxl__device_model_version_running(gc, domid) ==
+ LIBXL_DEVICE_MODEL_VERSION_NONE)
+ nic->nictype = LIBXL_NIC_TYPE_VIF;
+ else
+ nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
+ }
+ }
break;
case LIBXL_DOMAIN_TYPE_PV:
if (nic->nictype == LIBXL_NIC_TYPE_VIF_IOEMU) {
@@ -3317,7 +3335,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 bf2099b..675eb4f 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) {
@@ -924,7 +931,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;
@@ -1266,6 +1274,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 8e337de..601a30c 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1544,7 +1544,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;
}
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index b3ac44e..7e8ae14 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -782,21 +782,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);
@@ -862,7 +864,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;
@@ -877,18 +879,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;
}
@@ -899,6 +917,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);
@@ -916,6 +935,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);
@@ -928,6 +948,7 @@ static int libxl__domain_firmware(libxl__gc *gc,
return 0;
out:
+ assert(rc != 0);
return rc;
}
@@ -940,10 +961,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 device_model =
+ 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");
rc = ERROR_NOMEM;
@@ -976,8 +1000,12 @@ 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 && device_model)
dom->mmio_size = HVM_BELOW_4G_MMIO_LENGTH;
+ else if (dom->mmio_size == 0 && !device_model)
+ dom->mmio_size = GB(4) -
+ ((X86_HVM_END_SPECIAL_REGION - X86_HVM_NR_SPECIAL_PAGES)
+ << XC_PAGE_SHIFT);
lowmem_end = mem_size;
highmem_end = 0;
mmio_start = (1ull << 32) - dom->mmio_size;
@@ -989,8 +1017,8 @@ 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->vga_hole_size = LIBXL_VGA_HOLE_SIZE;
- dom->device_model = true;
+ dom->vga_hole_size = device_model ? LIBXL_VGA_HOLE_SIZE : 0;
+ dom->device_model = device_model;
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 25ace27..f6018a9 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -114,6 +114,12 @@
#define DOMID_XS_PATH "domid"
#define INVALID_DOMID ~0
+/* Size macros. */
+#define __AC(X,Y) (X##Y)
+#define _AC(X,Y) __AC(X,Y)
+#define MB(_mb) (_AC(_mb, ULL) << 20)
+#define GB(_gb) (_AC(_gb, ULL) << 30)
+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define ROUNDUP(_val, _order) \
@@ -1186,7 +1192,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);
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index d6ef9a2..082fed8 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 e71f80e..fb38e70 100644
--- a/tools/libxl/libxl_x86.c
+++ b/tools/libxl/libxl_x86.c
@@ -7,10 +7,16 @@ 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) {
+ /* HVM domains with a device model. */
xc_config->emulation_flags = XEN_X86_EMU_ALL;
- else
+ } else {
+ /* PV or HVM domains without a device model. */
xc_config->emulation_flags = 0;
+ }
return 0;
}
@@ -487,6 +493,7 @@ int libxl__arch_domain_construct_memmap(libxl__gc *gc,
struct e820entry *e820 = NULL;
uint64_t highmem_size =
dom->highmem_end ? dom->highmem_end - (1ull << 32) : 0;
+ uint32_t lowmem_start = dom->device_model ? GUEST_LOW_MEM_START_DEFAULT : 0;
/* Add all rdm entries. */
for (i = 0; i < d_config->num_rdms; i++)
@@ -507,8 +514,8 @@ int libxl__arch_domain_construct_memmap(libxl__gc *gc,
e820 = libxl__malloc(gc, sizeof(struct e820entry) * e820_entries);
/* Low memory */
- e820[nr].addr = GUEST_LOW_MEM_START_DEFAULT;
- e820[nr].size = dom->lowmem_end - GUEST_LOW_MEM_START_DEFAULT;
+ e820[nr].addr = lowmem_start;
+ e820[nr].size = dom->lowmem_end - lowmem_start;
e820[nr].type = E820_RAM;
nr++;
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 365798b..840d73f 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -2186,6 +2186,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] 105+ messages in thread
* Re: [PATCH v7 31/32] libxl: allow the creation of HVM domains without a device model.
2015-10-02 15:49 ` [PATCH v7 31/32] libxl: allow the creation of HVM domains without a device model Roger Pau Monne
@ 2015-10-08 14:36 ` Ian Campbell
2015-10-08 16:27 ` Roger Pau Monné
0 siblings, 1 reply; 105+ messages in thread
From: Ian Campbell @ 2015-10-08 14:36 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel; +Cc: Wei Liu, Ian Jackson, Stefano Stabellini
On Fri, 2015-10-02 at 17:49 +0200, Roger Pau Monne wrote:
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index d6ef9a2..082fed8 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
Is there a #define LIBXL_HAVE_<foo> somewhere in this series somewhere?
(Not in this patch I think)
Ian.
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 31/32] libxl: allow the creation of HVM domains without a device model.
2015-10-08 14:36 ` Ian Campbell
@ 2015-10-08 16:27 ` Roger Pau Monné
2015-10-08 16:39 ` Ian Campbell
0 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-08 16:27 UTC (permalink / raw)
To: Ian Campbell, xen-devel; +Cc: Wei Liu, Ian Jackson, Stefano Stabellini
El 08/10/15 a les 16.36, Ian Campbell ha escrit:
> On Fri, 2015-10-02 at 17:49 +0200, Roger Pau Monne wrote:
>> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
>> index d6ef9a2..082fed8 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
>
> Is there a #define LIBXL_HAVE_<foo> somewhere in this series somewhere?
> (Not in this patch I think)
No, but I'm afraid there should be one indeed. Does:
#define LIBXL_HAVE_HVM_WITHOUT_DM 1
Look reasonable?
Roger.
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 31/32] libxl: allow the creation of HVM domains without a device model.
2015-10-08 16:27 ` Roger Pau Monné
@ 2015-10-08 16:39 ` Ian Campbell
0 siblings, 0 replies; 105+ messages in thread
From: Ian Campbell @ 2015-10-08 16:39 UTC (permalink / raw)
To: Roger Pau Monné, xen-devel; +Cc: Wei Liu, Ian Jackson, Stefano Stabellini
On Thu, 2015-10-08 at 18:27 +0200, Roger Pau Monné wrote:
> El 08/10/15 a les 16.36, Ian Campbell ha escrit:
> > On Fri, 2015-10-02 at 17:49 +0200, Roger Pau Monne wrote:
> > > diff --git a/tools/libxl/libxl_types.idl
> > > b/tools/libxl/libxl_types.idl
> > > index d6ef9a2..082fed8 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
> >
> > Is there a #define LIBXL_HAVE_<foo> somewhere in this series somewhere?
> > (Not in this patch I think)
>
> No, but I'm afraid there should be one indeed. Does:
>
> #define LIBXL_HAVE_HVM_WITHOUT_DM 1
Usually we would name them after the type or value I think.
So LIBXL_HAVE_DEVICE_MODEL_VERSION_NONE here I think.
>
> Look reasonable?
>
> Roger.
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* [PATCH v7 32/32] libxl: add support for migrating HVM guests without a device model
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (30 preceding siblings ...)
2015-10-02 15:49 ` [PATCH v7 31/32] libxl: allow the creation of HVM domains without a device model Roger Pau Monne
@ 2015-10-02 15:49 ` Roger Pau Monne
2015-10-02 18:56 ` Andrew Cooper
2015-10-08 11:46 ` [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Ian Campbell
32 siblings, 1 reply; 105+ messages in thread
From: Roger Pau Monne @ 2015-10-02 15:49 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, Ian Jackson, Ian Campbell, Roger Pau Monne
Only some minor libxl changes are needed in order to be able to migrate HVM
guests without a device model, no hypervisor changes are needed.
This change prevents sending the emulator context if the device model
version is set to none.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl_dom.c | 3 +++
tools/libxl/libxl_dom_suspend.c | 2 ++
tools/libxl/libxl_stream_write.c | 8 +++++++-
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 7e8ae14..b40d744 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -1310,6 +1310,9 @@ void libxl__domain_suspend_common_switch_qemu_logdirty
case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
domain_suspend_switch_qemu_xen_logdirty(domid, enable, shs);
break;
+ case LIBXL_DEVICE_MODEL_VERSION_NONE:
+ libxl__xc_domain_saverestore_async_callback_done(egc, shs, 0);
+ break;
default:
LOG(ERROR,"logdirty switch failed"
", no valid device model version found, abandoning suspend");
diff --git a/tools/libxl/libxl_dom_suspend.c b/tools/libxl/libxl_dom_suspend.c
index 4cc01ad..3313ad1 100644
--- a/tools/libxl/libxl_dom_suspend.c
+++ b/tools/libxl/libxl_dom_suspend.c
@@ -43,6 +43,8 @@ int libxl__domain_suspend_device_model(libxl__gc *gc,
if (ret)
unlink(filename);
break;
+ case LIBXL_DEVICE_MODEL_VERSION_NONE:
+ break;
default:
return ERROR_INVAL;
}
diff --git a/tools/libxl/libxl_stream_write.c b/tools/libxl/libxl_stream_write.c
index 52a60d7..5551560 100644
--- a/tools/libxl/libxl_stream_write.c
+++ b/tools/libxl/libxl_stream_write.c
@@ -232,6 +232,9 @@ void libxl__stream_write_start(libxl__egc *egc,
stream->emu_sub_hdr.id = EMULATOR_QEMU_UPSTREAM;
break;
+ case LIBXL_DEVICE_MODEL_VERSION_NONE:
+ break;
+
default:
rc = ERROR_FAIL;
LOG(ERROR, "Unknown emulator for HVM domain");
@@ -387,8 +390,11 @@ static void emulator_xenstore_record_done(libxl__egc *egc,
libxl__stream_write_state *stream)
{
libxl__domain_suspend_state *dss = stream->dss;
+ STATE_AO_GC(stream->ao);
- if (dss->type == LIBXL_DOMAIN_TYPE_HVM)
+ if (dss->type == LIBXL_DOMAIN_TYPE_HVM &&
+ libxl__device_model_version_running(gc, dss->domid) !=
+ LIBXL_DEVICE_MODEL_VERSION_NONE)
write_emulator_context_record(egc, stream);
else {
if (stream->in_checkpoint)
--
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] 105+ messages in thread
* Re: [PATCH v7 32/32] libxl: add support for migrating HVM guests without a device model
2015-10-02 15:49 ` [PATCH v7 32/32] libxl: add support for migrating HVM guests " Roger Pau Monne
@ 2015-10-02 18:56 ` Andrew Cooper
2015-10-08 16:10 ` Roger Pau Monné
0 siblings, 1 reply; 105+ messages in thread
From: Andrew Cooper @ 2015-10-02 18:56 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel; +Cc: Ian Jackson, Wei Liu, Ian Campbell
On 02/10/15 16:49, Roger Pau Monne wrote:
> Only some minor libxl changes are needed in order to be able to migrate HVM
> guests without a device model, no hypervisor changes are needed.
>
> This change prevents sending the emulator context if the device model
> version is set to none.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> ---
> tools/libxl/libxl_dom.c | 3 +++
> tools/libxl/libxl_dom_suspend.c | 2 ++
> tools/libxl/libxl_stream_write.c | 8 +++++++-
> 3 files changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> index 7e8ae14..b40d744 100644
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -1310,6 +1310,9 @@ void libxl__domain_suspend_common_switch_qemu_logdirty
> case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
> domain_suspend_switch_qemu_xen_logdirty(domid, enable, shs);
> break;
> + case LIBXL_DEVICE_MODEL_VERSION_NONE:
> + libxl__xc_domain_saverestore_async_callback_done(egc, shs, 0);
> + break;
> default:
> LOG(ERROR,"logdirty switch failed"
> ", no valid device model version found, abandoning suspend");
> diff --git a/tools/libxl/libxl_dom_suspend.c b/tools/libxl/libxl_dom_suspend.c
> index 4cc01ad..3313ad1 100644
> --- a/tools/libxl/libxl_dom_suspend.c
> +++ b/tools/libxl/libxl_dom_suspend.c
> @@ -43,6 +43,8 @@ int libxl__domain_suspend_device_model(libxl__gc *gc,
> if (ret)
> unlink(filename);
> break;
> + case LIBXL_DEVICE_MODEL_VERSION_NONE:
> + break;
> default:
> return ERROR_INVAL;
> }
> diff --git a/tools/libxl/libxl_stream_write.c b/tools/libxl/libxl_stream_write.c
> index 52a60d7..5551560 100644
> --- a/tools/libxl/libxl_stream_write.c
> +++ b/tools/libxl/libxl_stream_write.c
> @@ -232,6 +232,9 @@ void libxl__stream_write_start(libxl__egc *egc,
> stream->emu_sub_hdr.id = EMULATOR_QEMU_UPSTREAM;
> break;
>
> + case LIBXL_DEVICE_MODEL_VERSION_NONE:
> + break;
> +
> default:
> rc = ERROR_FAIL;
> LOG(ERROR, "Unknown emulator for HVM domain");
> @@ -387,8 +390,11 @@ static void emulator_xenstore_record_done(libxl__egc *egc,
> libxl__stream_write_state *stream)
> {
> libxl__domain_suspend_state *dss = stream->dss;
> + STATE_AO_GC(stream->ao);
>
> - if (dss->type == LIBXL_DOMAIN_TYPE_HVM)
> + if (dss->type == LIBXL_DOMAIN_TYPE_HVM &&
> + libxl__device_model_version_running(gc, dss->domid) !=
> + LIBXL_DEVICE_MODEL_VERSION_NONE)
> write_emulator_context_record(egc, stream);
> else {
> if (stream->in_checkpoint)
I think a few more changes are needed to make this robust.
write_emulator_xenstore_record() needs an early check for
LIBXL_DEVICE_MODEL_VERSION_NONE and omit the call to
libxl__save_emulator_xenstore_data() (which is only needed because
qemu-upstream has a layering violation in its save format)
Instead of patching emulator_xenstore_record_done(), in the hunk above,
I would suggest having another early check and continue in
write_emulator_context_record()
Also, you need to patch the EMULATOR_* cases in
libxl_stream_read.c:process_record() to bail with a hard error if
records received for a domain configured to have no emulators.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 32/32] libxl: add support for migrating HVM guests without a device model
2015-10-02 18:56 ` Andrew Cooper
@ 2015-10-08 16:10 ` Roger Pau Monné
0 siblings, 0 replies; 105+ messages in thread
From: Roger Pau Monné @ 2015-10-08 16:10 UTC (permalink / raw)
To: Andrew Cooper, xen-devel; +Cc: Ian Jackson, Wei Liu, Ian Campbell
El 02/10/15 a les 20.56, Andrew Cooper ha escrit:
> On 02/10/15 16:49, Roger Pau Monne wrote:
>> Only some minor libxl changes are needed in order to be able to migrate HVM
>> guests without a device model, no hypervisor changes are needed.
>>
>> This change prevents sending the emulator context if the device model
>> version is set to none.
>>
>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Ian Campbell <ian.campbell@citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>> ---
>> tools/libxl/libxl_dom.c | 3 +++
>> tools/libxl/libxl_dom_suspend.c | 2 ++
>> tools/libxl/libxl_stream_write.c | 8 +++++++-
>> 3 files changed, 12 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
>> index 7e8ae14..b40d744 100644
>> --- a/tools/libxl/libxl_dom.c
>> +++ b/tools/libxl/libxl_dom.c
>> @@ -1310,6 +1310,9 @@ void libxl__domain_suspend_common_switch_qemu_logdirty
>> case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
>> domain_suspend_switch_qemu_xen_logdirty(domid, enable, shs);
>> break;
>> + case LIBXL_DEVICE_MODEL_VERSION_NONE:
>> + libxl__xc_domain_saverestore_async_callback_done(egc, shs, 0);
>> + break;
>> default:
>> LOG(ERROR,"logdirty switch failed"
>> ", no valid device model version found, abandoning suspend");
>> diff --git a/tools/libxl/libxl_dom_suspend.c b/tools/libxl/libxl_dom_suspend.c
>> index 4cc01ad..3313ad1 100644
>> --- a/tools/libxl/libxl_dom_suspend.c
>> +++ b/tools/libxl/libxl_dom_suspend.c
>> @@ -43,6 +43,8 @@ int libxl__domain_suspend_device_model(libxl__gc *gc,
>> if (ret)
>> unlink(filename);
>> break;
>> + case LIBXL_DEVICE_MODEL_VERSION_NONE:
>> + break;
>> default:
>> return ERROR_INVAL;
>> }
>> diff --git a/tools/libxl/libxl_stream_write.c b/tools/libxl/libxl_stream_write.c
>> index 52a60d7..5551560 100644
>> --- a/tools/libxl/libxl_stream_write.c
>> +++ b/tools/libxl/libxl_stream_write.c
>> @@ -232,6 +232,9 @@ void libxl__stream_write_start(libxl__egc *egc,
>> stream->emu_sub_hdr.id = EMULATOR_QEMU_UPSTREAM;
>> break;
>>
>> + case LIBXL_DEVICE_MODEL_VERSION_NONE:
>> + break;
>> +
>> default:
>> rc = ERROR_FAIL;
>> LOG(ERROR, "Unknown emulator for HVM domain");
>> @@ -387,8 +390,11 @@ static void emulator_xenstore_record_done(libxl__egc *egc,
>> libxl__stream_write_state *stream)
>> {
>> libxl__domain_suspend_state *dss = stream->dss;
>> + STATE_AO_GC(stream->ao);
>>
>> - if (dss->type == LIBXL_DOMAIN_TYPE_HVM)
>> + if (dss->type == LIBXL_DOMAIN_TYPE_HVM &&
>> + libxl__device_model_version_running(gc, dss->domid) !=
>> + LIBXL_DEVICE_MODEL_VERSION_NONE)
>> write_emulator_context_record(egc, stream);
>> else {
>> if (stream->in_checkpoint)
>
> I think a few more changes are needed to make this robust.
>
> write_emulator_xenstore_record() needs an early check for
> LIBXL_DEVICE_MODEL_VERSION_NONE and omit the call to
> libxl__save_emulator_xenstore_data() (which is only needed because
> qemu-upstream has a layering violation in its save format)
>
> Instead of patching emulator_xenstore_record_done(), in the hunk above,
> I would suggest having another early check and continue in
> write_emulator_context_record()
I've done so and bailed early on both functions, without touching
emulator_xenstore_record_done.
> Also, you need to patch the EMULATOR_* cases in
> libxl_stream_read.c:process_record() to bail with a hard error if
> records received for a domain configured to have no emulators.
Ack, I've added checks in both REC_TYPE_EMULATOR_XENSTORE_DATA and
REC_TYPE_EMULATOR_CONTEXT. Will send a new version.
Thanks, Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 105+ messages in thread
* Re: [PATCH v7 00/32] Introduce HVM without dm and new boot ABI
2015-10-02 15:48 [PATCH v7 00/32] Introduce HVM without dm and new boot ABI Roger Pau Monne
` (31 preceding siblings ...)
2015-10-02 15:49 ` [PATCH v7 32/32] libxl: add support for migrating HVM guests " Roger Pau Monne
@ 2015-10-08 11:46 ` Ian Campbell
32 siblings, 0 replies; 105+ messages in thread
From: Ian Campbell @ 2015-10-08 11:46 UTC (permalink / raw)
To: Roger Pau Monne, xen-devel
On Fri, 2015-10-02 at 17:48 +0200, Roger Pau Monne wrote:
> This series is split in the following order:
>
> - 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.
Applied this chunk, including the v8 of #5.
> - Patches from 25 to 32 introduce the creation of HVM guests without a
> device model and without the devices emulated inside of Xen.
>From this I applied "xenconsole: try to attach to PV console if HVM fails".
Ian.
^ permalink raw reply [flat|nested] 105+ messages in thread