|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 09/11] vpci: register as an internal ioreq server
> -----Original Message-----
> From: Roger Pau Monne <roger.pau@xxxxxxxxxx>
> Sent: 03 September 2019 17:14
> To: xen-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Roger Pau Monne <roger.pau@xxxxxxxxxx>; Ian Jackson
> <Ian.Jackson@xxxxxxxxxx>; Wei Liu
> <wl@xxxxxxx>; Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>; George Dunlap
> <George.Dunlap@xxxxxxxxxx>; Jan
> Beulich <jbeulich@xxxxxxxx>; Julien Grall <julien.grall@xxxxxxx>; Konrad
> Rzeszutek Wilk
> <konrad.wilk@xxxxxxxxxx>; Stefano Stabellini <sstabellini@xxxxxxxxxx>; Tim
> (Xen.org) <tim@xxxxxxx>;
> Paul Durrant <Paul.Durrant@xxxxxxxxxx>
> Subject: [PATCH v2 09/11] vpci: register as an internal ioreq server
>
> Switch vPCI to become an internal ioreq server, and hence drop all the
> vPCI specific decoding and trapping to PCI IO ports and MMCFG regions.
>
> This allows to unify the vPCI code with the ioreq infrastructure,
> opening the door for domains having PCI accesses handled by vPCI and
> other ioreq servers at the same time.
>
> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
[snip]
> diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
> index f61f66df5f..bf2c64a0a9 100644
> --- a/xen/arch/x86/physdev.c
> +++ b/xen/arch/x86/physdev.c
> @@ -11,6 +11,7 @@
> #include <asm/current.h>
> #include <asm/io_apic.h>
> #include <asm/msi.h>
> +#include <asm/hvm/ioreq.h>
Why is this change necessary on its own?
> #include <asm/hvm/irq.h>
> #include <asm/hypercall.h>
> #include <public/xen.h>
> diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
> index cbd1bac7fc..5664020c2d 100644
> --- a/xen/drivers/vpci/vpci.c
> +++ b/xen/drivers/vpci/vpci.c
> @@ -20,6 +20,8 @@
> #include <xen/sched.h>
> #include <xen/vpci.h>
>
> +#include <asm/hvm/ioreq.h>
> +
> /* Internal struct to store the emulated PCI registers. */
> struct vpci_register {
> vpci_read_t *read;
> @@ -302,7 +304,7 @@ static uint32_t merge_result(uint32_t data, uint32_t new,
> unsigned int size,
> return (data & ~(mask << (offset * 8))) | ((new & mask) << (offset * 8));
> }
>
> -uint32_t vpci_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int size)
> +static uint32_t read(pci_sbdf_t sbdf, unsigned int reg, unsigned int size)
> {
> const struct domain *d = current->domain;
> const struct pci_dev *pdev;
> @@ -404,8 +406,8 @@ static void vpci_write_helper(const struct pci_dev *pdev,
> r->private);
> }
>
> -void vpci_write(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
> - uint32_t data)
> +static void write(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
> + uint32_t data)
> {
> const struct domain *d = current->domain;
> const struct pci_dev *pdev;
> @@ -478,6 +480,67 @@ void vpci_write(pci_sbdf_t sbdf, unsigned int reg,
> unsigned int size,
> spin_unlock(&pdev->vpci->lock);
> }
>
> +#ifdef __XEN__
> +static int ioreq_handler(struct vcpu *v, ioreq_t *req, void *data)
> +{
> + pci_sbdf_t sbdf;
> +
> + if ( req->type == IOREQ_TYPE_INVALIDATE )
> + /*
> + * Ignore invalidate requests, those can be received even without
> + * having any memory ranges registered, see send_invalidate_req.
> + */
> + return X86EMUL_OKAY;
In general, I wonder whether internal servers will ever need to deal with
invalidate? The code only exists to get QEMU to drop its map cache after a
decrease_reservation so that the page refs get dropped.
Paul
> +
> + if ( req->type != IOREQ_TYPE_PCI_CONFIG || req->data_is_ptr )
> + {
> + ASSERT_UNREACHABLE();
> + return X86EMUL_UNHANDLEABLE;
> + }
> +
> + sbdf.sbdf = req->addr >> 32;
> +
> + if ( req->dir )
> + req->data = read(sbdf, req->addr, req->size);
> + else
> + write(sbdf, req->addr, req->size, req->data);
> +
> + return X86EMUL_OKAY;
> +}
> +
> +int vpci_register_ioreq(struct domain *d)
> +{
> + ioservid_t id;
> + int rc;
> +
> + if ( !has_vpci(d) )
> + return 0;
> +
> + rc = hvm_create_ioreq_server(d, HVM_IOREQSRV_BUFIOREQ_OFF, &id, true);
> + if ( rc )
> + return rc;
> +
> + rc = hvm_add_ioreq_handler(d, id, ioreq_handler, NULL);
> + if ( rc )
> + return rc;
> +
> + if ( is_hardware_domain(d) )
> + {
> + /* Handle all devices in vpci. */
> + rc = hvm_map_io_range_to_ioreq_server(d, id, XEN_DMOP_IO_RANGE_PCI,
> + 0, ~(uint64_t)0);
> + if ( rc )
> + return rc;
> + }
> +
> + rc = hvm_set_ioreq_server_state(d, id, true);
> + if ( rc )
> + return rc;
> +
> + return rc;
> +}
> +#endif
> +
> /*
> * Local variables:
> * mode: C
> diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h
> index 4cf233c779..36f435ed5b 100644
> --- a/xen/include/xen/vpci.h
> +++ b/xen/include/xen/vpci.h
> @@ -23,6 +23,9 @@ typedef int vpci_register_init_t(struct pci_dev *dev);
> static vpci_register_init_t *const x##_entry \
> __used_section(".data.vpci." p) = x
>
> +/* Register vPCI handler with ioreq. */
> +int vpci_register_ioreq(struct domain *d);
> +
> /* Add vPCI handlers to device. */
> int __must_check vpci_add_handlers(struct pci_dev *dev);
>
> @@ -38,11 +41,6 @@ int __must_check vpci_add_register(struct vpci *vpci,
> int __must_check vpci_remove_register(struct vpci *vpci, unsigned int offset,
> unsigned int size);
>
> -/* Generic read/write handlers for the PCI config space. */
> -uint32_t vpci_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int size);
> -void vpci_write(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
> - uint32_t data);
> -
> /* Passthrough handlers. */
> uint32_t vpci_hw_read16(const struct pci_dev *pdev, unsigned int reg,
> void *data);
> @@ -221,20 +219,12 @@ static inline int vpci_add_handlers(struct pci_dev
> *pdev)
> return 0;
> }
>
> -static inline void vpci_dump_msi(void) { }
> -
> -static inline uint32_t vpci_read(pci_sbdf_t sbdf, unsigned int reg,
> - unsigned int size)
> +static inline int vpci_register_ioreq(struct domain *d)
> {
> - ASSERT_UNREACHABLE();
> - return ~(uint32_t)0;
> + return 0;
> }
>
> -static inline void vpci_write(pci_sbdf_t sbdf, unsigned int reg,
> - unsigned int size, uint32_t data)
> -{
> - ASSERT_UNREACHABLE();
> -}
> +static inline void vpci_dump_msi(void) { }
>
> static inline bool vpci_process_pending(struct vcpu *v)
> {
> --
> 2.22.0
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |