|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v14 04/11] x86/hvm/ioreq: defer mapping gfns until they are actually requsted
On Tue, Nov 28, 2017 at 03:08:46PM +0000, Paul Durrant wrote:
>A subsequent patch will introduce a new scheme to allow an emulator to
>map ioreq server pages directly from Xen rather than the guest P2M.
>
>This patch lays the groundwork for that change by deferring mapping of
>gfns until their values are requested by an emulator. To that end, the
>pad field of the xen_dm_op_get_ioreq_server_info structure is re-purposed
>to a flags field and new flag, XEN_DMOP_no_gfns, defined which modifies the
>behaviour of XEN_DMOP_get_ioreq_server_info to allow the caller to avoid
>requesting the gfn values.
>
>Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
>Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
>Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx>
>Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
>---
>Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
>Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
>Cc: George Dunlap <George.Dunlap@xxxxxxxxxxxxx>
>Cc: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
>Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>
>Cc: Tim Deegan <tim@xxxxxxx>
>
>v8:
> - For safety make all of the pointers passed to
> hvm_get_ioreq_server_info() optional.
> - Shrink bufioreq_handling down to a uint8_t.
>
>v3:
> - Updated in response to review comments from Wei and Roger.
> - Added a HANDLE_BUFIOREQ macro to make the code neater.
> - This patch no longer introduces a security vulnerability since there
> is now an explicit limit on the number of ioreq servers that may be
> created for any one domain.
>---
> tools/libs/devicemodel/core.c | 8 +++++
> tools/libs/devicemodel/include/xendevicemodel.h | 6 ++--
> xen/arch/x86/hvm/dm.c | 9 +++--
> xen/arch/x86/hvm/ioreq.c | 47 ++++++++++++++-----------
> xen/include/asm-x86/hvm/domain.h | 2 +-
> xen/include/public/hvm/dm_op.h | 32 ++++++++++-------
> 6 files changed, 63 insertions(+), 41 deletions(-)
>
>diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c
>index b66d4f9294..e684e657b6 100644
>--- a/tools/libs/devicemodel/core.c
>+++ b/tools/libs/devicemodel/core.c
>@@ -204,6 +204,14 @@ int xendevicemodel_get_ioreq_server_info(
>
> data->id = id;
>
>+ /*
>+ * If the caller is not requesting gfn values then instruct the
>+ * hypercall not to retrieve them as this may cause them to be
>+ * mapped.
>+ */
>+ if (!ioreq_gfn && !bufioreq_gfn)
>+ data->flags |= XEN_DMOP_no_gfns;
>+
> rc = xendevicemodel_op(dmod, domid, 1, &op, sizeof(op));
> if (rc)
> return rc;
>diff --git a/tools/libs/devicemodel/include/xendevicemodel.h
>b/tools/libs/devicemodel/include/xendevicemodel.h
>index dda0bc7695..fffee3a4a0 100644
>--- a/tools/libs/devicemodel/include/xendevicemodel.h
>+++ b/tools/libs/devicemodel/include/xendevicemodel.h
>@@ -61,11 +61,11 @@ int xendevicemodel_create_ioreq_server(
> * @parm domid the domain id to be serviced
> * @parm id the IOREQ Server id.
> * @parm ioreq_gfn pointer to a xen_pfn_t to receive the synchronous ioreq
>- * gfn
>+ * gfn. (May be NULL if not required)
> * @parm bufioreq_gfn pointer to a xen_pfn_t to receive the buffered ioreq
>- * gfn
>+ * gfn. (May be NULL if not required)
> * @parm bufioreq_port pointer to a evtchn_port_t to receive the buffered
>- * ioreq event channel
>+ * ioreq event channel. (May be NULL if not required)
> * @return 0 on success, -1 on failure.
> */
> int xendevicemodel_get_ioreq_server_info(
>diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
>index a787f43737..3c617bd754 100644
>--- a/xen/arch/x86/hvm/dm.c
>+++ b/xen/arch/x86/hvm/dm.c
>@@ -416,16 +416,19 @@ static int dm_op(const struct dmop_args *op_args)
> {
> struct xen_dm_op_get_ioreq_server_info *data =
> &op.u.get_ioreq_server_info;
>+ const uint16_t valid_flags = XEN_DMOP_no_gfns;
>
> const_op = false;
>
> rc = -EINVAL;
>- if ( data->pad )
>+ if ( data->flags & ~valid_flags )
> break;
>
> rc = hvm_get_ioreq_server_info(d, data->id,
>- &data->ioreq_gfn,
>- &data->bufioreq_gfn,
>+ (data->flags & XEN_DMOP_no_gfns) ?
>+ NULL : &data->ioreq_gfn,
>+ (data->flags & XEN_DMOP_no_gfns) ?
>+ NULL : &data->bufioreq_gfn,
> &data->bufioreq_port);
> break;
> }
>diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
>index eec4e4771e..39de659ddf 100644
>--- a/xen/arch/x86/hvm/ioreq.c
>+++ b/xen/arch/x86/hvm/ioreq.c
>@@ -350,6 +350,9 @@ static void hvm_update_ioreq_evtchn(struct
>hvm_ioreq_server *s,
> }
> }
>
>+#define HANDLE_BUFIOREQ(s) \
>+ ((s)->bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF)
>+
> static int hvm_ioreq_server_add_vcpu(struct hvm_ioreq_server *s,
> struct vcpu *v)
> {
>@@ -371,7 +374,7 @@ static int hvm_ioreq_server_add_vcpu(struct
>hvm_ioreq_server *s,
>
> sv->ioreq_evtchn = rc;
>
>- if ( v->vcpu_id == 0 && s->bufioreq.va != NULL )
>+ if ( v->vcpu_id == 0 && HANDLE_BUFIOREQ(s) )
> {
> struct domain *d = s->domain;
>
>@@ -422,7 +425,7 @@ static void hvm_ioreq_server_remove_vcpu(struct
>hvm_ioreq_server *s,
>
> list_del(&sv->list_entry);
>
>- if ( v->vcpu_id == 0 && s->bufioreq.va != NULL )
>+ if ( v->vcpu_id == 0 && HANDLE_BUFIOREQ(s) )
> free_xen_event_channel(v->domain, s->bufioreq_evtchn);
>
> free_xen_event_channel(v->domain, sv->ioreq_evtchn);
>@@ -449,7 +452,7 @@ static void hvm_ioreq_server_remove_all_vcpus(struct
>hvm_ioreq_server *s)
>
> list_del(&sv->list_entry);
>
>- if ( v->vcpu_id == 0 && s->bufioreq.va != NULL )
>+ if ( v->vcpu_id == 0 && HANDLE_BUFIOREQ(s) )
> free_xen_event_channel(v->domain, s->bufioreq_evtchn);
>
> free_xen_event_channel(v->domain, sv->ioreq_evtchn);
>@@ -460,14 +463,13 @@ static void hvm_ioreq_server_remove_all_vcpus(struct
>hvm_ioreq_server *s)
> spin_unlock(&s->lock);
> }
>
>-static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
>- bool handle_bufioreq)
>+static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s)
> {
> int rc;
>
> rc = hvm_map_ioreq_gfn(s, false);
>
>- if ( !rc && handle_bufioreq )
>+ if ( !rc && HANDLE_BUFIOREQ(s) )
> rc = hvm_map_ioreq_gfn(s, true);
>
> if ( rc )
>@@ -597,13 +599,7 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server
>*s,
> if ( rc )
> return rc;
>
>- if ( bufioreq_handling == HVM_IOREQSRV_BUFIOREQ_ATOMIC )
>- s->bufioreq_atomic = true;
>-
>- rc = hvm_ioreq_server_map_pages(
>- s, bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF);
It seems that for default IO server, mapping gfns here is required. Old
qemu won't call hvm_get_ioreq_server_info() (and cannot because of the
assertion 'ASSERT(!IS_DEFAULT(s))') to set up the mapping.
Thanks
Chao
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |