[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 |