[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [RFC PATCH 3/5] ioreq-server: on-demand creation of ioreq server
On 30/01/14 14:19, Paul Durrant wrote: > This patch only creates the ioreq server when the legacy HVM parameters > are touched by an emulator. It also lays some groundwork for supporting > multiple IOREQ servers. For instance, it introduces ioreq server reference > counting which is not strictly necessary at this stage but will become so > when ioreq servers can be destroyed prior the domain dying. > > There is a significant change in the layout of the special pages reserved > in xc_hvm_build_x86.c. This is so that we can 'grow' them downwards without > moving pages such as the xenstore page when building a domain that can > support more than one emulator. > > Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > --- > tools/libxc/xc_hvm_build_x86.c | 41 ++-- > xen/arch/x86/hvm/hvm.c | 409 > ++++++++++++++++++++++++++------------ > xen/include/asm-x86/hvm/domain.h | 3 +- > 3 files changed, 314 insertions(+), 139 deletions(-) > > diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c > index 77bd365..f24f2a1 100644 > --- a/tools/libxc/xc_hvm_build_x86.c > +++ b/tools/libxc/xc_hvm_build_x86.c > @@ -41,13 +41,12 @@ > #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 SPECIALPAGE_XENSTORE 3 > +#define SPECIALPAGE_IDENT_PT 4 > +#define SPECIALPAGE_CONSOLE 5 > +#define SPECIALPAGE_IOREQ 6 > +#define NR_SPECIAL_PAGES SPECIALPAGE_IOREQ + 2 /* ioreq server needs 2 > pages */ > +#define special_pfn(x) (0xff000u - (x)) > > static int modules_init(struct xc_hvm_build_args *args, > uint64_t vend, struct elf_binary *elf, > @@ -112,7 +111,7 @@ static void build_hvm_info(void *hvm_info_page, uint64_t > mem_size, > /* Memory parameters. */ > hvm_info->low_mem_pgend = lowmem_end >> PAGE_SHIFT; > hvm_info->high_mem_pgend = highmem_end >> PAGE_SHIFT; > - hvm_info->reserved_mem_pgstart = special_pfn(0); > + hvm_info->reserved_mem_pgstart = special_pfn(0) - NR_SPECIAL_PAGES; > > /* Finish with the checksum. */ > for ( i = 0, sum = 0; i < hvm_info->length; i++ ) > @@ -463,6 +462,24 @@ static int setup_guest(xc_interface *xch, > munmap(hvm_info_page, PAGE_SIZE); > > /* Allocate and clear special pages. */ > + > + DPRINTF("%d SPECIAL PAGES:\n" > + " PAGING: %"PRI_xen_pfn"\n" > + " ACCESS: %"PRI_xen_pfn"\n" > + " SHARING: %"PRI_xen_pfn"\n" > + " STORE: %"PRI_xen_pfn"\n" > + " IDENT_PT: %"PRI_xen_pfn"\n" > + " CONSOLE: %"PRI_xen_pfn"\n" > + " IOREQ: %"PRI_xen_pfn"\n", > + NR_SPECIAL_PAGES, > + (xen_pfn_t)special_pfn(SPECIALPAGE_PAGING), > + (xen_pfn_t)special_pfn(SPECIALPAGE_ACCESS), > + (xen_pfn_t)special_pfn(SPECIALPAGE_SHARING), > + (xen_pfn_t)special_pfn(SPECIALPAGE_XENSTORE), > + (xen_pfn_t)special_pfn(SPECIALPAGE_IDENT_PT), > + (xen_pfn_t)special_pfn(SPECIALPAGE_CONSOLE), > + (xen_pfn_t)special_pfn(SPECIALPAGE_IOREQ)); > + I realise I am being quite picky here, but from a daemon point of view trying to log to facilities like syslog, multi-line single debugging messages are a pain. Would it be possible to do this as 8 DPRINTF()s? > for ( i = 0; i < NR_SPECIAL_PAGES; i++ ) > { > xen_pfn_t pfn = special_pfn(i); > @@ -478,10 +495,6 @@ static int setup_guest(xc_interface *xch, > > xc_set_hvm_param(xch, dom, HVM_PARAM_STORE_PFN, > special_pfn(SPECIALPAGE_XENSTORE)); > - xc_set_hvm_param(xch, dom, HVM_PARAM_BUFIOREQ_PFN, > - special_pfn(SPECIALPAGE_BUFIOREQ)); > - xc_set_hvm_param(xch, dom, HVM_PARAM_IOREQ_PFN, > - special_pfn(SPECIALPAGE_IOREQ)); > xc_set_hvm_param(xch, dom, HVM_PARAM_CONSOLE_PFN, > special_pfn(SPECIALPAGE_CONSOLE)); > xc_set_hvm_param(xch, dom, HVM_PARAM_PAGING_RING_PFN, > @@ -490,6 +503,10 @@ static int setup_guest(xc_interface *xch, > special_pfn(SPECIALPAGE_ACCESS)); > xc_set_hvm_param(xch, dom, HVM_PARAM_SHARING_RING_PFN, > special_pfn(SPECIALPAGE_SHARING)); > + xc_set_hvm_param(xch, dom, HVM_PARAM_IOREQ_PFN, > + special_pfn(SPECIALPAGE_IOREQ)); > + xc_set_hvm_param(xch, dom, HVM_PARAM_BUFIOREQ_PFN, > + special_pfn(SPECIALPAGE_IOREQ) - 1); > > /* > * Identity-map page table is required for running with CR0.PG=0 when > diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c > index a0eaadb..d9874fb 100644 > --- a/xen/arch/x86/hvm/hvm.c > +++ b/xen/arch/x86/hvm/hvm.c > @@ -352,24 +352,9 @@ static ioreq_t *get_ioreq(struct hvm_ioreq_server *s, > int id) > return &p->vcpu_ioreq[id]; > } > > -void hvm_do_resume(struct vcpu *v) > +static void hvm_wait_on_io(struct domain *d, ioreq_t *p) > { > - struct hvm_ioreq_server *s; > - ioreq_t *p; > - > - check_wakeup_from_wait(); > - > - if ( is_hvm_vcpu(v) ) > - pt_restore_timer(v); > - > - s = v->arch.hvm_vcpu.ioreq_server; > - v->arch.hvm_vcpu.ioreq_server = NULL; > - > - if ( !s ) > - goto check_inject_trap; > - > /* NB. Optimised for common case (p->state == STATE_IOREQ_NONE). */ > - p = get_ioreq(s, v->vcpu_id); > while ( p->state != STATE_IOREQ_NONE ) > { > switch ( p->state ) > @@ -385,12 +370,32 @@ void hvm_do_resume(struct vcpu *v) > break; > default: > gdprintk(XENLOG_ERR, "Weird HVM iorequest state %d.\n", > p->state); > - domain_crash(v->domain); > + domain_crash(d); > return; /* bail */ > } > } > +} > + > +void hvm_do_resume(struct vcpu *v) > +{ > + struct domain *d = v->domain; > + struct hvm_ioreq_server *s; > + > + check_wakeup_from_wait(); > + > + if ( is_hvm_vcpu(v) ) > + pt_restore_timer(v); > + > + s = v->arch.hvm_vcpu.ioreq_server; > + v->arch.hvm_vcpu.ioreq_server = NULL; > + > + if ( s ) > + { > + ioreq_t *p = get_ioreq(s, v->vcpu_id); > + > + hvm_wait_on_io(d, p); > + } > > - check_inject_trap: > /* Inject pending hw/sw trap */ > if ( v->arch.hvm_vcpu.inject_trap.vector != -1 ) > { > @@ -399,11 +404,13 @@ void hvm_do_resume(struct vcpu *v) > } > } > > -static void hvm_init_ioreq_page( > - struct domain *d, struct hvm_ioreq_page *iorp) > +static void hvm_init_ioreq_page(struct hvm_ioreq_server *s, int buf) > { > + struct hvm_ioreq_page *iorp; > + > + iorp = ( buf ) ? &s->buf_ioreq : &s->ioreq; > + Brackets are redundant. > spin_lock_init(&iorp->lock); > - domain_pause(d); > } > > void destroy_ring_for_helper( > @@ -419,16 +426,13 @@ void destroy_ring_for_helper( > } > } > > -static void hvm_destroy_ioreq_page( > - struct domain *d, struct hvm_ioreq_page *iorp) > +static void hvm_destroy_ioreq_page(struct hvm_ioreq_server *s, int buf) > { > - spin_lock(&iorp->lock); > + struct hvm_ioreq_page *iorp; > > - ASSERT(d->is_dying); > + iorp = ( buf ) ? &s->buf_ioreq : &s->ioreq; > > destroy_ring_for_helper(&iorp->va, iorp->page); > - > - spin_unlock(&iorp->lock); > } > > int prepare_ring_for_helper( > @@ -476,8 +480,10 @@ int prepare_ring_for_helper( > } > > static int hvm_set_ioreq_page( > - struct domain *d, struct hvm_ioreq_page *iorp, unsigned long gmfn) > + struct hvm_ioreq_server *s, int buf, unsigned long gmfn) > { > + struct domain *d = s->domain; > + struct hvm_ioreq_page *iorp; > struct page_info *page; > void *va; > int rc; > @@ -485,22 +491,17 @@ static int hvm_set_ioreq_page( > if ( (rc = prepare_ring_for_helper(d, gmfn, &page, &va)) ) > return rc; > > - spin_lock(&iorp->lock); > + iorp = ( buf ) ? &s->buf_ioreq : &s->ioreq; > > if ( (iorp->va != NULL) || d->is_dying ) > { > - destroy_ring_for_helper(&iorp->va, iorp->page); > - spin_unlock(&iorp->lock); > + destroy_ring_for_helper(&va, page); > return -EINVAL; > } > > iorp->va = va; > iorp->page = page; > > - spin_unlock(&iorp->lock); > - > - domain_unpause(d); > - > return 0; > } > > @@ -544,38 +545,6 @@ static int handle_pvh_io( > return X86EMUL_OKAY; > } > > -static int hvm_init_ioreq_server(struct domain *d) > -{ > - struct hvm_ioreq_server *s; > - int i; > - > - s = xzalloc(struct hvm_ioreq_server); > - if ( !s ) > - return -ENOMEM; > - > - s->domain = d; > - > - for ( i = 0; i < MAX_HVM_VCPUS; i++ ) > - s->ioreq_evtchn[i] = -1; > - s->buf_ioreq_evtchn = -1; > - > - hvm_init_ioreq_page(d, &s->ioreq); > - hvm_init_ioreq_page(d, &s->buf_ioreq); > - > - d->arch.hvm_domain.ioreq_server = s; > - return 0; > -} > - > -static void hvm_deinit_ioreq_server(struct domain *d) > -{ > - struct hvm_ioreq_server *s = d->arch.hvm_domain.ioreq_server; > - > - hvm_destroy_ioreq_page(d, &s->ioreq); > - hvm_destroy_ioreq_page(d, &s->buf_ioreq); > - > - xfree(s); > -} > - > static void hvm_update_ioreq_server_evtchn(struct hvm_ioreq_server *s) > { > struct domain *d = s->domain; > @@ -637,6 +606,152 @@ static void hvm_ioreq_server_remove_vcpu(struct > hvm_ioreq_server *s, struct vcpu > } > } > > +static int hvm_create_ioreq_server(struct domain *d, domid_t domid) > +{ > + struct hvm_ioreq_server *s; > + int i; > + unsigned long pfn; > + struct vcpu *v; > + int rc; i and rc can be declared together. > + > + spin_lock(&d->arch.hvm_domain.ioreq_server_lock); > + > + rc = -EEXIST; > + if ( d->arch.hvm_domain.ioreq_server != NULL ) > + goto fail_exist; > + > + gdprintk(XENLOG_INFO, "%s: %d\n", __func__, d->domain_id); > + > + rc = -ENOMEM; > + s = xzalloc(struct hvm_ioreq_server); > + if ( !s ) > + goto fail_alloc; > + > + s->domain = d; > + s->domid = domid; > + > + for ( i = 0; i < MAX_HVM_VCPUS; i++ ) > + s->ioreq_evtchn[i] = -1; > + s->buf_ioreq_evtchn = -1; > + > + /* Initialize shared pages */ > + pfn = d->arch.hvm_domain.params[HVM_PARAM_IOREQ_PFN]; > + > + hvm_init_ioreq_page(s, 0); > + if ( (rc = hvm_set_ioreq_page(s, 0, pfn)) < 0 ) > + goto fail_set_ioreq; > + > + pfn = d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN]; > + > + hvm_init_ioreq_page(s, 1); > + if ( (rc = hvm_set_ioreq_page(s, 1, pfn)) < 0 ) > + goto fail_set_buf_ioreq; > + > + for_each_vcpu ( d, v ) > + { > + if ( (rc = hvm_ioreq_server_add_vcpu(s, v)) < 0 ) > + goto fail_add_vcpu; > + } > + > + d->arch.hvm_domain.ioreq_server = s; > + > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); > + > + return 0; > + > +fail_add_vcpu: > + for_each_vcpu ( d, v ) > + hvm_ioreq_server_remove_vcpu(s, v); > + hvm_destroy_ioreq_page(s, 1); > +fail_set_buf_ioreq: > + hvm_destroy_ioreq_page(s, 0); > +fail_set_ioreq: > + xfree(s); > +fail_alloc: > +fail_exist: > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); > + return rc; > +} > + > +static void hvm_destroy_ioreq_server(struct domain *d) > +{ > + struct hvm_ioreq_server *s; > + struct vcpu *v; > + > + spin_lock(&d->arch.hvm_domain.ioreq_server_lock); > + > + gdprintk(XENLOG_INFO, "%s: %d\n", __func__, d->domain_id); > + > + s = d->arch.hvm_domain.ioreq_server; > + if ( !s ) > + goto done; > + > + domain_pause(d); > + > + d->arch.hvm_domain.ioreq_server = NULL; > + > + for_each_vcpu ( d, v ) > + hvm_ioreq_server_remove_vcpu(s, v); > + > + hvm_destroy_ioreq_page(s, 1); > + hvm_destroy_ioreq_page(s, 0); > + > + xfree(s); > + > + domain_unpause(d); > + > +done: > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); > +} > + > +static int hvm_get_ioreq_server_buf_port(struct domain *d, evtchn_port_t > *port) > +{ > + struct hvm_ioreq_server *s; > + int rc; > + > + spin_lock(&d->arch.hvm_domain.ioreq_server_lock); > + > + s = d->arch.hvm_domain.ioreq_server; > + > + rc = -ENOENT; > + if ( !s ) > + goto done; > + > + *port = s->buf_ioreq_evtchn; > + rc = 0; > + > +done: > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); > + > + return rc; > +} > + > +static int hvm_get_ioreq_server_pfn(struct domain *d, int buf, xen_pfn_t > *pfn) > +{ > + struct hvm_ioreq_server *s; > + int rc; > + > + spin_lock(&d->arch.hvm_domain.ioreq_server_lock); > + > + s = d->arch.hvm_domain.ioreq_server; > + > + rc = -ENOENT; > + if ( !s ) > + goto done; > + > + if ( buf ) > + *pfn = d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN]; > + else > + *pfn = d->arch.hvm_domain.params[HVM_PARAM_IOREQ_PFN]; This can be reduced and use "params[buf ? HVM_PARAM_BUFIOREQ_PFN : HVM_PARAM_IOREQ_PFN]", although that is perhaps not as clear. > + > + rc = 0; > + > +done: > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); > + > + return rc; > +} > + > static int hvm_replace_event_channel(struct vcpu *v, domid_t remote_domid, > int *p_port) > { > @@ -652,13 +767,24 @@ static int hvm_replace_event_channel(struct vcpu *v, > domid_t remote_domid, > return 0; > } > > -static int hvm_set_ioreq_server_domid(struct hvm_ioreq_server *s, domid_t > domid) > +static int hvm_set_ioreq_server_domid(struct domain *d, domid_t domid) > { > - struct domain *d = s->domain; > + struct hvm_ioreq_server *s; > struct vcpu *v; > int rc = 0; > > domain_pause(d); > + spin_lock(&d->arch.hvm_domain.ioreq_server_lock); > + > + s = d->arch.hvm_domain.ioreq_server; > + > + rc = -ENOENT; > + if ( !s ) > + goto done; > + > + rc = 0; > + if ( s->domid == domid ) > + goto done; > > if ( d->vcpu[0] ) > { > @@ -680,31 +806,11 @@ static int hvm_set_ioreq_server_domid(struct > hvm_ioreq_server *s, domid_t domid) > > done: > domain_unpause(d); > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); Mismatched order of pause/unpause and lock/unlock pairs. The unlock should ideally be before the unpause. > > return rc; > } > > -static int hvm_set_ioreq_server_pfn(struct hvm_ioreq_server *s, unsigned > long pfn) > -{ > - struct domain *d = s->domain; > - int rc; > - > - rc = hvm_set_ioreq_page(d, &s->ioreq, pfn); > - if ( rc < 0 ) > - return rc; > - > - hvm_update_ioreq_server_evtchn(s); > - > - return 0; > -} > - > -static int hvm_set_ioreq_server_buf_pfn(struct hvm_ioreq_server *s, unsigned > long pfn) > -{ > - struct domain *d = s->domain; > - > - return hvm_set_ioreq_page(d, &s->buf_ioreq, pfn); > -} > - > int hvm_domain_initialise(struct domain *d) > { > int rc; > @@ -732,6 +838,7 @@ int hvm_domain_initialise(struct domain *d) > > } > > + spin_lock_init(&d->arch.hvm_domain.ioreq_server_lock); > spin_lock_init(&d->arch.hvm_domain.irq_lock); > spin_lock_init(&d->arch.hvm_domain.uc_lock); > > @@ -772,20 +879,14 @@ int hvm_domain_initialise(struct domain *d) > > rtc_init(d); > > - rc = hvm_init_ioreq_server(d); > - if ( rc != 0 ) > - goto fail2; > - > register_portio_handler(d, 0xe9, 1, hvm_print_line); > > rc = hvm_funcs.domain_initialise(d); > if ( rc != 0 ) > - goto fail3; > + goto fail2; > > return 0; > > - fail3: > - hvm_deinit_ioreq_server(d); > fail2: > rtc_deinit(d); > stdvga_deinit(d); > @@ -809,7 +910,7 @@ void hvm_domain_relinquish_resources(struct domain *d) > if ( hvm_funcs.nhvm_domain_relinquish_resources ) > hvm_funcs.nhvm_domain_relinquish_resources(d); > > - hvm_deinit_ioreq_server(d); > + hvm_destroy_ioreq_server(d); > > msixtbl_pt_cleanup(d); > > @@ -1364,11 +1465,16 @@ int hvm_vcpu_initialise(struct vcpu *v) > && (rc = nestedhvm_vcpu_initialise(v)) < 0 ) /* teardown: > nestedhvm_vcpu_destroy */ > goto fail5; > > + spin_lock(&d->arch.hvm_domain.ioreq_server_lock); > s = d->arch.hvm_domain.ioreq_server; > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); > > - rc = hvm_ioreq_server_add_vcpu(s, v); > - if ( rc < 0 ) > - goto fail6; > + if ( s ) > + { > + rc = hvm_ioreq_server_add_vcpu(s, v); > + if ( rc < 0 ) > + goto fail6; > + } > > if ( v->vcpu_id == 0 ) > { > @@ -1404,9 +1510,14 @@ int hvm_vcpu_initialise(struct vcpu *v) > void hvm_vcpu_destroy(struct vcpu *v) > { > struct domain *d = v->domain; > - struct hvm_ioreq_server *s = d->arch.hvm_domain.ioreq_server; > + struct hvm_ioreq_server *s; > + > + spin_lock(&d->arch.hvm_domain.ioreq_server_lock); > + s = d->arch.hvm_domain.ioreq_server; > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); > > - hvm_ioreq_server_remove_vcpu(s, v); > + if ( s ) > + hvm_ioreq_server_remove_vcpu(s, v); > > nestedhvm_vcpu_destroy(v); > > @@ -1459,7 +1570,10 @@ int hvm_buffered_io_send(ioreq_t *p) > /* Ensure buffered_iopage fits in a page */ > BUILD_BUG_ON(sizeof(buffered_iopage_t) > PAGE_SIZE); > > + spin_lock(&d->arch.hvm_domain.ioreq_server_lock); > s = d->arch.hvm_domain.ioreq_server; > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); > + > if ( !s ) > return 0; > > @@ -1532,20 +1646,12 @@ int hvm_buffered_io_send(ioreq_t *p) > return 1; > } > > -bool_t hvm_send_assist_req(struct vcpu *v, ioreq_t *proto_p) > +static bool_t hvm_send_assist_req_to_server(struct hvm_ioreq_server *s, > + struct vcpu *v, > + ioreq_t *proto_p) > { > struct domain *d = v->domain; > - struct hvm_ioreq_server *s; > - ioreq_t *p; > - > - if ( unlikely(!vcpu_start_shutdown_deferral(v)) ) > - return 0; /* implicitly bins the i/o operation */ > - > - s = d->arch.hvm_domain.ioreq_server; > - if ( !s ) > - return 0; > - > - p = get_ioreq(s, v->vcpu_id); > + ioreq_t *p = get_ioreq(s, v->vcpu_id); > > if ( unlikely(p->state != STATE_IOREQ_NONE) ) > { > @@ -1578,6 +1684,26 @@ bool_t hvm_send_assist_req(struct vcpu *v, ioreq_t > *proto_p) > return 1; > } > > +bool_t hvm_send_assist_req(struct vcpu *v, ioreq_t *p) > +{ > + struct domain *d = v->domain; > + struct hvm_ioreq_server *s; > + > + ASSERT(v->arch.hvm_vcpu.ioreq_server == NULL); > + > + if ( unlikely(!vcpu_start_shutdown_deferral(v)) ) > + return 0; > + > + spin_lock(&d->arch.hvm_domain.ioreq_server_lock); > + s = d->arch.hvm_domain.ioreq_server; > + spin_unlock(&d->arch.hvm_domain.ioreq_server_lock); What is the purpose of talking the server lock just to read the ioreq_server pointer? > + > + if ( !s ) > + return 0; > + > + return hvm_send_assist_req_to_server(s, v, p); > +} > + > void hvm_hlt(unsigned long rflags) > { > struct vcpu *curr = current; > @@ -4172,7 +4298,6 @@ long do_hvm_op(unsigned long op, > XEN_GUEST_HANDLE_PARAM(void) arg) > case HVMOP_get_param: > { > struct xen_hvm_param a; > - struct hvm_ioreq_server *s; > struct domain *d; > struct vcpu *v; > > @@ -4198,20 +4323,12 @@ long do_hvm_op(unsigned long op, > XEN_GUEST_HANDLE_PARAM(void) arg) > if ( rc ) > goto param_fail; > > - s = d->arch.hvm_domain.ioreq_server; > - > if ( op == HVMOP_set_param ) > { > rc = 0; > > switch ( a.index ) > { > - case HVM_PARAM_IOREQ_PFN: > - rc = hvm_set_ioreq_server_pfn(s, a.value); > - break; > - case HVM_PARAM_BUFIOREQ_PFN: > - rc = hvm_set_ioreq_server_buf_pfn(s, a.value); > - break; > case HVM_PARAM_CALLBACK_IRQ: > hvm_set_callback_via(d, a.value); > hvm_latch_shinfo_size(d); > @@ -4265,7 +4382,9 @@ long do_hvm_op(unsigned long op, > XEN_GUEST_HANDLE_PARAM(void) arg) > if ( a.value == DOMID_SELF ) > a.value = curr_d->domain_id; > > - rc = hvm_set_ioreq_server_domid(s, a.value); > + rc = hvm_create_ioreq_server(d, a.value); > + if ( rc == -EEXIST ) > + rc = hvm_set_ioreq_server_domid(d, a.value); > break; > case HVM_PARAM_ACPI_S_STATE: > /* Not reflexive, as we must domain_pause(). */ > @@ -4360,8 +4479,46 @@ long do_hvm_op(unsigned long op, > XEN_GUEST_HANDLE_PARAM(void) arg) > { > switch ( a.index ) > { > + case HVM_PARAM_IOREQ_PFN: > + case HVM_PARAM_BUFIOREQ_PFN: > case HVM_PARAM_BUFIOREQ_EVTCHN: > - a.value = s->buf_ioreq_evtchn; > + /* May need to create server */ > + rc = hvm_create_ioreq_server(d, curr_d->domain_id); > + if ( rc != 0 && rc != -EEXIST ) > + goto param_fail; > + > + switch ( a.index ) > + { > + case HVM_PARAM_IOREQ_PFN: { > + xen_pfn_t pfn; > + > + if ( (rc = hvm_get_ioreq_server_pfn(d, 0, &pfn)) < 0 ) > + goto param_fail; > + > + a.value = pfn; > + break; > + } > + case HVM_PARAM_BUFIOREQ_PFN: { > + xen_pfn_t pfn; > + > + if ( (rc = hvm_get_ioreq_server_pfn(d, 1, &pfn)) < 0 ) > + goto param_fail; > + > + a.value = pfn; > + break; > + } > + case HVM_PARAM_BUFIOREQ_EVTCHN: { > + evtchn_port_t port; > + > + if ( (rc = hvm_get_ioreq_server_buf_port(d, &port)) < 0 ) > + goto param_fail; > + > + a.value = port; > + break; > + } > + default: > + BUG(); > + } > break; > case HVM_PARAM_ACPI_S_STATE: > a.value = d->arch.hvm_domain.is_s3_suspended ? 3 : 0; > diff --git a/xen/include/asm-x86/hvm/domain.h > b/xen/include/asm-x86/hvm/domain.h > index 4c039f8..e750ef0 100644 > --- a/xen/include/asm-x86/hvm/domain.h > +++ b/xen/include/asm-x86/hvm/domain.h > @@ -52,6 +52,8 @@ struct hvm_ioreq_server { > > struct hvm_domain { > struct hvm_ioreq_server *ioreq_server; > + spinlock_t ioreq_server_lock; > + > struct pl_time pl_time; > > struct hvm_io_handler *io_handler; > @@ -106,4 +108,3 @@ struct hvm_domain { > #define hap_enabled(d) ((d)->arch.hvm_domain.hap_enabled) > > #endif /* __ASM_X86_HVM_DOMAIN_H__ */ > - Spurious whitespace change ~Andrew _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |