Message ID | 20240924162359.1390487-5-edgar.iglesias@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | xen/arm: Add Virtio-PCI for dom0less on ARM | expand |
On Tue, 24 Sep 2024, Edgar E. Iglesias wrote: > From: "Edgar E. Iglesias" <edgar.iglesias@amd.com> > > Add support for mmio background regions. These regions > can be overlayed by IOREQ handlers and thus act as > fallback handlers while IOREQ clients haven't registered. > > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> > --- > xen/arch/arm/include/asm/mmio.h | 11 ++++++++++- > xen/arch/arm/io.c | 18 ++++++++++++------ > 2 files changed, 22 insertions(+), 7 deletions(-) > > diff --git a/xen/arch/arm/include/asm/mmio.h b/xen/arch/arm/include/asm/mmio.h > index b22cfdac5b..7da542cd79 100644 > --- a/xen/arch/arm/include/asm/mmio.h > +++ b/xen/arch/arm/include/asm/mmio.h > @@ -70,6 +70,7 @@ struct mmio_handler_ops { > struct mmio_handler { > paddr_t addr; > paddr_t size; > + bool background; > const struct mmio_handler_ops *ops; > void *priv; > }; > @@ -83,9 +84,17 @@ struct vmmio { > > enum io_state try_handle_mmio(struct cpu_user_regs *regs, > mmio_info_t *info); > +void register_mmio_bg_handler(struct domain *d, > + bool background, > + const struct mmio_handler_ops *ops, > + paddr_t addr, paddr_t size, void *priv); > +static inline > void register_mmio_handler(struct domain *d, > const struct mmio_handler_ops *ops, > - paddr_t addr, paddr_t size, void *priv); > + paddr_t addr, paddr_t size, void *priv) > +{ > + register_mmio_bg_handler(d, false, ops, addr, size, priv); > +} > int domain_io_init(struct domain *d, unsigned int max_count); > void domain_io_free(struct domain *d); > > diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c > index 96c740d563..934a2ad2b9 100644 > --- a/xen/arch/arm/io.c > +++ b/xen/arch/arm/io.c > @@ -159,6 +159,7 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs, > { > struct vcpu *v = current; > const struct mmio_handler *handler = NULL; > + bool has_background; > int rc; > > ASSERT(info->dabt.ec == HSR_EC_DATA_ABORT_LOWER_EL); > @@ -170,13 +171,16 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs, > } > > handler = find_mmio_handler(v->domain, info->gpa); > - if ( !handler ) > + has_background = handler && handler->background; > + if ( !handler || has_background ) > { > rc = try_fwd_ioserv(regs, v, info); > if ( rc == IO_HANDLED ) > return handle_ioserv(regs, v); > - > - return rc; > + else if ( !(rc == IO_UNHANDLED && has_background) ) { > + /* Only return failure if there's no background handler. */ > + return rc; > + } > } > > /* > @@ -197,9 +201,10 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs, > return handle_read(handler, v, info); > } > > -void register_mmio_handler(struct domain *d, > - const struct mmio_handler_ops *ops, > - paddr_t addr, paddr_t size, void *priv) > +void register_mmio_bg_handler(struct domain *d, > + bool background, > + const struct mmio_handler_ops *ops, > + paddr_t addr, paddr_t size, void *priv) > { > struct vmmio *vmmio = &d->arch.vmmio; > struct mmio_handler *handler; > @@ -213,6 +218,7 @@ void register_mmio_handler(struct domain *d, > handler->ops = ops; > handler->addr = addr; > handler->size = size; > + handler->background = background; > handler->priv = priv; > > vmmio->num_entries++; > -- > 2.43.0 >
diff --git a/xen/arch/arm/include/asm/mmio.h b/xen/arch/arm/include/asm/mmio.h index b22cfdac5b..7da542cd79 100644 --- a/xen/arch/arm/include/asm/mmio.h +++ b/xen/arch/arm/include/asm/mmio.h @@ -70,6 +70,7 @@ struct mmio_handler_ops { struct mmio_handler { paddr_t addr; paddr_t size; + bool background; const struct mmio_handler_ops *ops; void *priv; }; @@ -83,9 +84,17 @@ struct vmmio { enum io_state try_handle_mmio(struct cpu_user_regs *regs, mmio_info_t *info); +void register_mmio_bg_handler(struct domain *d, + bool background, + const struct mmio_handler_ops *ops, + paddr_t addr, paddr_t size, void *priv); +static inline void register_mmio_handler(struct domain *d, const struct mmio_handler_ops *ops, - paddr_t addr, paddr_t size, void *priv); + paddr_t addr, paddr_t size, void *priv) +{ + register_mmio_bg_handler(d, false, ops, addr, size, priv); +} int domain_io_init(struct domain *d, unsigned int max_count); void domain_io_free(struct domain *d); diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c index 96c740d563..934a2ad2b9 100644 --- a/xen/arch/arm/io.c +++ b/xen/arch/arm/io.c @@ -159,6 +159,7 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs, { struct vcpu *v = current; const struct mmio_handler *handler = NULL; + bool has_background; int rc; ASSERT(info->dabt.ec == HSR_EC_DATA_ABORT_LOWER_EL); @@ -170,13 +171,16 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs, } handler = find_mmio_handler(v->domain, info->gpa); - if ( !handler ) + has_background = handler && handler->background; + if ( !handler || has_background ) { rc = try_fwd_ioserv(regs, v, info); if ( rc == IO_HANDLED ) return handle_ioserv(regs, v); - - return rc; + else if ( !(rc == IO_UNHANDLED && has_background) ) { + /* Only return failure if there's no background handler. */ + return rc; + } } /* @@ -197,9 +201,10 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs, return handle_read(handler, v, info); } -void register_mmio_handler(struct domain *d, - const struct mmio_handler_ops *ops, - paddr_t addr, paddr_t size, void *priv) +void register_mmio_bg_handler(struct domain *d, + bool background, + const struct mmio_handler_ops *ops, + paddr_t addr, paddr_t size, void *priv) { struct vmmio *vmmio = &d->arch.vmmio; struct mmio_handler *handler; @@ -213,6 +218,7 @@ void register_mmio_handler(struct domain *d, handler->ops = ops; handler->addr = addr; handler->size = size; + handler->background = background; handler->priv = priv; vmmio->num_entries++;