|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 1/4] x86/msi: passthrough all MSI-X vector ctrl writes to device model
On 06.04.2023 05:57, Marek Marczykowski-Górecki wrote:
> --- a/xen/arch/x86/hvm/vmsi.c
> +++ b/xen/arch/x86/hvm/vmsi.c
> @@ -272,6 +272,15 @@ out:
> return r;
> }
>
> +/*
> + * This function returns X86EMUL_UNHANDLEABLE even if write is properly
> + * handled, to propagate it to the device model (so it can keep its internal
> + * state in sync).
> + * len==0 means really len==4, but as a write completion that will return
> + * X86EMUL_OKAY on successful processing. Use WRITE_LEN4_COMPLETION to make
> it
> + * less confusing.
> + */
> +#define WRITE_LEN4_COMPLETION 0
> static int msixtbl_write(struct vcpu *v, unsigned long address,
> unsigned int len, unsigned long val)
> {
> @@ -283,8 +292,9 @@ static int msixtbl_write(struct vcpu *v, unsigned long
> address,
> unsigned long flags;
> struct irq_desc *desc;
>
> - if ( (len != 4 && len != 8) || (address & (len - 1)) )
> - return r;
> + if ( (len != 4 && len != 8 && len != WRITE_LEN4_COMPLETION) ||
> + (len && (address & (len - 1))) )
> + return X86EMUL_UNHANDLEABLE;
>
> rcu_read_lock(&msixtbl_rcu_lock);
>
> @@ -345,7 +355,7 @@ static int msixtbl_write(struct vcpu *v, unsigned long
> address,
>
> unlock:
> spin_unlock_irqrestore(&desc->lock, flags);
> - if ( len == 4 )
> + if ( len == WRITE_LEN4_COMPLETION )
> r = X86EMUL_OKAY;
>
> out:
> @@ -635,7 +645,7 @@ void msix_write_completion(struct vcpu *v)
> return;
>
> v->arch.hvm.hvm_io.msix_unmask_address = 0;
> - if ( msixtbl_write(v, ctrl_address, 4, 0) != X86EMUL_OKAY )
> + if ( msixtbl_write(v, ctrl_address, WRITE_LEN4_COMPLETION, 0) !=
> X86EMUL_OKAY )
> gdprintk(XENLOG_WARNING, "MSI-X write completion failure\n");
> }
>
This part is okay with me, but ...
> --- a/xen/common/ioreq.c
> +++ b/xen/common/ioreq.c
> @@ -743,7 +743,8 @@ static int ioreq_server_destroy(struct domain *d,
> ioservid_t id)
> static int ioreq_server_get_info(struct domain *d, ioservid_t id,
> unsigned long *ioreq_gfn,
> unsigned long *bufioreq_gfn,
> - evtchn_port_t *bufioreq_port)
> + evtchn_port_t *bufioreq_port,
> + uint16_t *flags)
> {
> struct ioreq_server *s;
> int rc;
> @@ -779,6 +780,9 @@ static int ioreq_server_get_info(struct domain *d,
> ioservid_t id,
> *bufioreq_port = s->bufioreq_evtchn;
> }
>
> + /* Advertise supported features/behaviors. */
> + *flags = XEN_DMOP_all_msix_writes;
> +
> rc = 0;
>
> out:
> @@ -1374,7 +1378,8 @@ int ioreq_server_dm_op(struct xen_dm_op *op, struct
> domain *d, bool *const_op)
> NULL : (unsigned long *)&data->ioreq_gfn,
> (data->flags & XEN_DMOP_no_gfns) ?
> NULL : (unsigned long
> *)&data->bufioreq_gfn,
> - &data->bufioreq_port);
> + &data->bufioreq_port, &data->flags);
> +
> break;
> }
>
> diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h
> index acdf91693d0b..490b151c5dd7 100644
> --- a/xen/include/public/hvm/dm_op.h
> +++ b/xen/include/public/hvm/dm_op.h
> @@ -70,7 +70,9 @@ typedef struct xen_dm_op_create_ioreq_server
> xen_dm_op_create_ioreq_server_t;
> * not contain XEN_DMOP_no_gfns then these pages will be made available and
> * the frame numbers passed back in gfns <ioreq_gfn> and <bufioreq_gfn>
> * respectively. (If the IOREQ Server is not handling buffered emulation
> - * only <ioreq_gfn> will be valid).
> + * only <ioreq_gfn> will be valid). When Xen returns XEN_DMOP_all_msix_writes
> + * flag set, it will notify the IOREQ server about all writes to MSI-X table
> + * (if it's handled by this IOREQ server), not only those clearing a mask
> bit.
> *
> * NOTE: To access the synchronous ioreq structures and buffered ioreq
> * ring, it is preferable to use the XENMEM_acquire_resource memory
> @@ -81,11 +83,13 @@ typedef struct xen_dm_op_create_ioreq_server
> xen_dm_op_create_ioreq_server_t;
> struct xen_dm_op_get_ioreq_server_info {
> /* IN - server id */
> ioservid_t id;
> - /* IN - flags */
> + /* IN/OUT - flags */
> uint16_t flags;
>
> -#define _XEN_DMOP_no_gfns 0
> -#define XEN_DMOP_no_gfns (1u << _XEN_DMOP_no_gfns)
> +#define _XEN_DMOP_no_gfns 0 /* IN */
> +#define _XEN_DMOP_all_msix_writes 1 /* OUT */
> +#define XEN_DMOP_no_gfns (1u << _XEN_DMOP_no_gfns)
> +#define XEN_DMOP_all_msix_writes (1u << _XEN_DMOP_all_msix_writes)
>
> /* OUT - buffered ioreq port */
> evtchn_port_t bufioreq_port;
... this isn't: What is obtained through this hypercall is information
pertaining to a particular ioreq server. I don't think Xen behavior
should be reported there. To me this information much rather fits in
what public/features.h has / offers. And XENVER_get_features isn't
constrained in any way, so any dm ought to be able to retrieve the
information that way.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |