The 'vcpu' field changed from a fixed array to a pointer to an array.
The size of the array is stored in the (newly introduced) 'max_vcpus'
field. Modify xen_hyper_store_domain_context to account for this change.
Signed-off-by: Petr Tesarik <ptesarik(a)suse.cz>
---
xen_hyper.c | 37 +++++++++++++++++++++++++++++++++----
xen_hyper_defs.h | 1 +
2 files changed, 34 insertions(+), 4 deletions(-)
--- a/xen_hyper.c
+++ b/xen_hyper.c
@@ -220,6 +220,7 @@ xen_hyper_domain_init(void)
XEN_HYPER_MEMBER_OFFSET_INIT(domain_is_shut_down, "domain",
"is_shut_down");
XEN_HYPER_MEMBER_OFFSET_INIT(domain_vcpu, "domain", "vcpu");
XEN_HYPER_MEMBER_SIZE_INIT(domain_vcpu, "domain", "vcpu");
+ XEN_HYPER_MEMBER_OFFSET_INIT(domain_max_vcpus, "domain",
"max_vcpus");
XEN_HYPER_MEMBER_OFFSET_INIT(domain_arch, "domain", "arch");
XEN_HYPER_STRUCT_SIZE_INIT(arch_shared_info, "arch_shared_info");
@@ -1208,6 +1209,7 @@ struct xen_hyper_domain_context *
xen_hyper_store_domain_context(struct xen_hyper_domain_context *dc,
ulong domain, char *dp)
{
+ char *vcpup;
unsigned int max_vcpus;
unsigned int i;
@@ -1246,7 +1248,9 @@ xen_hyper_store_domain_context(struct xe
dc->domain_flags = XEN_HYPER_DOMF_ERROR;
}
dc->evtchn = ULONG(dp + XEN_HYPER_OFFSET(domain_evtchn));
- if (XEN_HYPER_VALID_SIZE(domain_vcpu)) {
+ if (XEN_HYPER_VALID_MEMBER(domain_max_vcpus)) {
+ max_vcpus = UINT(dp + XEN_HYPER_OFFSET(domain_max_vcpus));
+ } else if (XEN_HYPER_VALID_SIZE(domain_vcpu)) {
max_vcpus = XEN_HYPER_SIZE(domain_vcpu) / sizeof(void *);
} else {
max_vcpus = XEN_HYPER_MAX_VIRT_CPUS;
@@ -1255,9 +1259,34 @@ xen_hyper_store_domain_context(struct xe
error(FATAL, "cannot malloc vcpu array (%d VCPUs).",
max_vcpus);
}
- for (i = 0; i < max_vcpus; i++) {
- dc->vcpu[i] = ULONG(dp + XEN_HYPER_OFFSET(domain_vcpu) +
i*sizeof(void *));
- if (dc->vcpu[i]) XEN_HYPER_NR_VCPUS_IN_DOM(dc)++;
+ if (MEMBER_TYPE("domain", "vcpu") == TYPE_CODE_ARRAY)
+ vcpup = dp + XEN_HYPER_OFFSET(domain_vcpu);
+ else {
+ ulong vcpu_array = ULONG(dp + XEN_HYPER_OFFSET(domain_vcpu));
+ if (vcpu_array && max_vcpus) {
+ if (!(vcpup =
+ malloc(max_vcpus * sizeof(void *)))) {
+ error(FATAL, "cannot malloc VCPU array for domain %lx.",
+ domain);
+ }
+ if (!readmem(vcpu_array, KVADDR,
+ vcpup, max_vcpus * sizeof(void*),
+ "VCPU array", RETURN_ON_ERROR)) {
+ error(FATAL, "cannot read VCPU array for domain %lx.",
+ domain);
+ }
+ } else {
+ vcpup = NULL;
+ }
+ }
+ if (vcpup) {
+ for (i = 0; i < max_vcpus; i++) {
+ dc->vcpu[i] = ULONG(vcpup + i*sizeof(void *));
+ if (dc->vcpu[i]) XEN_HYPER_NR_VCPUS_IN_DOM(dc)++;
+ }
+ if (vcpup != dp + XEN_HYPER_OFFSET(domain_vcpu)) {
+ free(vcpup);
+ }
}
return dc;
--- a/xen_hyper_defs.h
+++ b/xen_hyper_defs.h
@@ -675,6 +675,7 @@ struct xen_hyper_offset_table {
long domain_is_shutting_down;
long domain_is_shut_down;
long domain_vcpu;
+ long domain_max_vcpus;
long domain_arch;
#ifdef IA64
/* mm_struct */