[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 19/30] xen/dcpi: add a dpci passthrough handler for hardware domain



> -----Original Message-----
> From: Roger Pau Monne [mailto:roger.pau@xxxxxxxxxx]
> Sent: 27 September 2016 16:57
> To: xen-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: konrad.wilk@xxxxxxxxxx; boris.ostrovsky@xxxxxxxxxx; Roger Pau Monne
> <roger.pau@xxxxxxxxxx>; Paul Durrant <Paul.Durrant@xxxxxxxxxx>; Jan
> Beulich <jbeulich@xxxxxxxx>; Andrew Cooper
> <Andrew.Cooper3@xxxxxxxxxx>
> Subject: [PATCH v2 19/30] xen/dcpi: add a dpci passthrough handler for
> hardware domain
> 
> This is very similar to the PCI trap used for the traditional PV(H) Dom0.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
> ---
> Cc: Paul Durrant <paul.durrant@xxxxxxxxxx>
> Cc: Jan Beulich <jbeulich@xxxxxxxx>
> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> ---
>  xen/arch/x86/hvm/io.c         | 72
> ++++++++++++++++++++++++++++++++++++++++++-
>  xen/arch/x86/traps.c          | 39 -----------------------
>  xen/drivers/passthrough/pci.c | 39 +++++++++++++++++++++++
>  xen/include/xen/pci.h         |  2 ++
>  4 files changed, 112 insertions(+), 40 deletions(-)
> 
> diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c index
> 1e7a5f9..31d54dc 100644
> --- a/xen/arch/x86/hvm/io.c
> +++ b/xen/arch/x86/hvm/io.c
> @@ -247,12 +247,79 @@ static int dpci_portio_write(const struct
> hvm_io_handler *handler,
>      return X86EMUL_OKAY;
>  }
> 
> +static bool_t hw_dpci_portio_accept(const struct hvm_io_handler
> *handler,
> +                                    const ioreq_t *p) {
> +    if ( (p->addr == 0xcf8 && p->size == 4) || (p->addr & 0xfffc) == 0xcfc)
> +    {
> +        return 1;
> +    }
> +
> +    return 0;

Why not just return the value of the boolean expression?

> +}
> +
> +static int hw_dpci_portio_read(const struct hvm_io_handler *handler,
> +                            uint64_t addr,
> +                            uint32_t size,
> +                            uint64_t *data) {
> +    struct domain *currd = current->domain;
> +
> +    if ( addr == 0xcf8 )
> +    {
> +        ASSERT(size == 4);
> +        *data = currd->arch.pci_cf8;
> +        return X86EMUL_OKAY;
> +    }
> +
> +    ASSERT((addr & 0xfffc) == 0xcfc);

You could do 'addr &= 3' and simplify the expressions below.

> +    size = min(size, 4 - ((uint32_t)addr & 3));
> +    if ( size == 3 )
> +        size = 2;
> +    if ( pci_cfg_ok(currd, addr & 3, size, NULL) )

Is this the right place to do the check. Can this not be done in the accept op?

> +        *data = pci_conf_read(currd->arch.pci_cf8, addr & 3, size);
> +
> +    return X86EMUL_OKAY;
> +}
> +
> +static int hw_dpci_portio_write(const struct hvm_io_handler *handler,
> +                                uint64_t addr,
> +                                uint32_t size,
> +                                uint64_t data) {
> +    struct domain *currd = current->domain;
> +    uint32_t data32;
> +
> +    if ( addr == 0xcf8 )
> +    {
> +            ASSERT(size == 4);
> +            currd->arch.pci_cf8 = data;
> +            return X86EMUL_OKAY;
> +    }
> +
> +    ASSERT((addr & 0xfffc) == 0xcfc);

'addr &= 3' again here.

  Paul

> +    size = min(size, 4 - ((uint32_t)addr & 3));
> +    if ( size == 3 )
> +        size = 2;
> +    data32 = data;
> +    if ( pci_cfg_ok(currd, addr & 3, size, &data32) )
> +        pci_conf_write(currd->arch.pci_cf8, addr & 3, size, data);
> +
> +    return X86EMUL_OKAY;
> +}
> +
>  static const struct hvm_io_ops dpci_portio_ops = {
>      .accept = dpci_portio_accept,
>      .read = dpci_portio_read,
>      .write = dpci_portio_write
>  };
> 
> +static const struct hvm_io_ops hw_dpci_portio_ops = {
> +    .accept = hw_dpci_portio_accept,
> +    .read = hw_dpci_portio_read,
> +    .write = hw_dpci_portio_write
> +};
> +
>  void register_dpci_portio_handler(struct domain *d)  {
>      struct hvm_io_handler *handler = hvm_next_io_handler(d); @@ -261,7
> +328,10 @@ void register_dpci_portio_handler(struct domain *d)
>          return;
> 
>      handler->type = IOREQ_TYPE_PIO;
> -    handler->ops = &dpci_portio_ops;
> +    if ( is_hardware_domain(d) )
> +        handler->ops = &hw_dpci_portio_ops;
> +    else
> +        handler->ops = &dpci_portio_ops;
>  }
> 
>  /*
> diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index
> 24d173f..f3c5c9e 100644
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -2076,45 +2076,6 @@ static bool_t admin_io_okay(unsigned int port,
> unsigned int bytes,
>      return ioports_access_permitted(d, port, port + bytes - 1);  }
> 
> -static bool_t pci_cfg_ok(struct domain *currd, unsigned int start,
> -                         unsigned int size, uint32_t *write)
> -{
> -    uint32_t machine_bdf;
> -
> -    if ( !is_hardware_domain(currd) )
> -        return 0;
> -
> -    if ( !CF8_ENABLED(currd->arch.pci_cf8) )
> -        return 1;
> -
> -    machine_bdf = CF8_BDF(currd->arch.pci_cf8);
> -    if ( write )
> -    {
> -        const unsigned long *ro_map = pci_get_ro_map(0);
> -
> -        if ( ro_map && test_bit(machine_bdf, ro_map) )
> -            return 0;
> -    }
> -    start |= CF8_ADDR_LO(currd->arch.pci_cf8);
> -    /* AMD extended configuration space access? */
> -    if ( CF8_ADDR_HI(currd->arch.pci_cf8) &&
> -         boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
> -         boot_cpu_data.x86 >= 0x10 && boot_cpu_data.x86 <= 0x17 )
> -    {
> -        uint64_t msr_val;
> -
> -        if ( rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) )
> -            return 0;
> -        if ( msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT) )
> -            start |= CF8_ADDR_HI(currd->arch.pci_cf8);
> -    }
> -
> -    return !write ?
> -           xsm_pci_config_permission(XSM_HOOK, currd, machine_bdf,
> -                                     start, start + size - 1, 0) == 0 :
> -           pci_conf_write_intercept(0, machine_bdf, start, size, write) >= 0;
> -}
> -
>  uint32_t guest_io_read(unsigned int port, unsigned int bytes,
>                         struct domain *currd)  { diff --git 
> a/xen/drivers/passthrough/pci.c
> b/xen/drivers/passthrough/pci.c index dd291a2..a53b4c8 100644
> --- a/xen/drivers/passthrough/pci.c
> +++ b/xen/drivers/passthrough/pci.c
> @@ -966,6 +966,45 @@ void pci_check_disable_device(u16 seg, u8 bus, u8
> devfn)
>                       PCI_COMMAND, cword & ~PCI_COMMAND_MASTER);  }
> 
> +bool_t pci_cfg_ok(struct domain *currd, unsigned int start,
> +                         unsigned int size, uint32_t *write) {
> +    uint32_t machine_bdf;
> +
> +    if ( !is_hardware_domain(currd) )
> +        return 0;
> +
> +    if ( !CF8_ENABLED(currd->arch.pci_cf8) )
> +        return 1;
> +
> +    machine_bdf = CF8_BDF(currd->arch.pci_cf8);
> +    if ( write )
> +    {
> +        const unsigned long *ro_map = pci_get_ro_map(0);
> +
> +        if ( ro_map && test_bit(machine_bdf, ro_map) )
> +            return 0;
> +    }
> +    start |= CF8_ADDR_LO(currd->arch.pci_cf8);
> +    /* AMD extended configuration space access? */
> +    if ( CF8_ADDR_HI(currd->arch.pci_cf8) &&
> +         boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
> +         boot_cpu_data.x86 >= 0x10 && boot_cpu_data.x86 <= 0x17 )
> +    {
> +        uint64_t msr_val;
> +
> +        if ( rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) )
> +            return 0;
> +        if ( msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT) )
> +            start |= CF8_ADDR_HI(currd->arch.pci_cf8);
> +    }
> +
> +    return !write ?
> +           xsm_pci_config_permission(XSM_HOOK, currd, machine_bdf,
> +                                     start, start + size - 1, 0) == 0 :
> +           pci_conf_write_intercept(0, machine_bdf, start, size, write)
> +>= 0; }
> +
>  /*
>   * scan pci devices to add all existed PCI devices to alldevs_list,
>   * and setup pci hierarchy in array bus2bridge.
> diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index
> 0872401..f191773 100644
> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -162,6 +162,8 @@ const char *parse_pci(const char *, unsigned int *seg,
> unsigned int *bus,
> 
>  bool_t pcie_aer_get_firmware_first(const struct pci_dev *);
> 
> +bool_t pci_cfg_ok(struct domain *, unsigned int, unsigned int, uint32_t
> +*);
> +
>  struct pirq;
>  int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable);  
> void
> msixtbl_pt_unregister(struct domain *, struct pirq *);
> --
> 2.7.4 (Apple Git-66)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.