|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 10/11] ioreq: split the code to detect PCI config space accesses
> -----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>; Paul Durrant
> <Paul.Durrant@xxxxxxxxxx>; Jan Beulich
> <jbeulich@xxxxxxxx>; Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>; Wei Liu
> <wl@xxxxxxx>
> Subject: [PATCH v2 10/11] ioreq: split the code to detect PCI config space
> accesses
>
> Place the code that converts a PIO/COPY ioreq into a PCI_CONFIG one
> into a separate function, and adjust the code to make use of this
> newly introduced function.
>
> No functional change intended.
>
> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
> ---
> Changes since v1:
> - New in this version.
> ---
> xen/arch/x86/hvm/ioreq.c | 111 +++++++++++++++++++++++----------------
> 1 file changed, 67 insertions(+), 44 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
> index fecdc2786f..33c56b880c 100644
> --- a/xen/arch/x86/hvm/ioreq.c
> +++ b/xen/arch/x86/hvm/ioreq.c
> @@ -183,6 +183,54 @@ static bool hvm_wait_for_io(struct hvm_ioreq_vcpu *sv,
> ioreq_t *p)
> return true;
> }
>
> +static void convert_pci_ioreq(struct domain *d, ioreq_t *p)
> +{
> + const struct hvm_mmcfg *mmcfg;
> + uint32_t cf8 = d->arch.hvm.pci_cf8;
> +
> + if ( p->type != IOREQ_TYPE_PIO && p->type != IOREQ_TYPE_COPY )
> + {
> + ASSERT_UNREACHABLE();
> + return;
> + }
> +
> + read_lock(&d->arch.hvm.mmcfg_lock);
Actually, looking at this... can you not restrict holding the mmcfg_lock...
> + if ( (p->type == IOREQ_TYPE_PIO &&
> + (p->addr & ~3) == 0xcfc &&
> + CF8_ENABLED(cf8)) ||
> + (p->type == IOREQ_TYPE_COPY &&
> + (mmcfg = hvm_mmcfg_find(d, p->addr)) != NULL) )
> + {
> + uint32_t x86_fam;
> + pci_sbdf_t sbdf;
> + unsigned int reg;
> +
> + reg = p->type == IOREQ_TYPE_PIO ? hvm_pci_decode_addr(cf8, p->addr,
> + &sbdf)
> + : hvm_mmcfg_decode_addr(mmcfg,
> p->addr,
> + &sbdf);
... to within hvm_mmcfg_decode_addr()?
Paul
> +
> + /* PCI config data cycle */
> + p->addr = ((uint64_t)sbdf.sbdf << 32) | reg;
> + /* AMD extended configuration space access? */
> + if ( p->type == IOREQ_TYPE_PIO && CF8_ADDR_HI(cf8) &&
> + d->arch.cpuid->x86_vendor == X86_VENDOR_AMD &&
> + (x86_fam = get_cpu_family(
> + d->arch.cpuid->basic.raw_fms, NULL, NULL)) > 0x10 &&
> + x86_fam < 0x17 )
> + {
> + uint64_t msr_val;
> +
> + if ( !rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) &&
> + (msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT)) )
> + p->addr |= CF8_ADDR_HI(cf8);
> + }
> + p->type = IOREQ_TYPE_PCI_CONFIG;
> +
> + }
> + read_unlock(&d->arch.hvm.mmcfg_lock);
> +}
> +
> bool handle_hvm_io_completion(struct vcpu *v)
> {
> struct domain *d = v->domain;
> @@ -1350,57 +1398,36 @@ void hvm_destroy_all_ioreq_servers(struct domain *d)
> ioservid_t hvm_select_ioreq_server(struct domain *d, ioreq_t *p)
> {
> struct hvm_ioreq_server *s;
> - uint32_t cf8;
> uint8_t type;
> - uint64_t addr;
> unsigned int id;
> - const struct hvm_mmcfg *mmcfg;
>
> if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO )
> return XEN_INVALID_IOSERVID;
>
> - cf8 = d->arch.hvm.pci_cf8;
> + /*
> + * Check and convert the PIO/MMIO ioreq to a PCI config space
> + * access.
> + */
> + convert_pci_ioreq(d, p);
>
> - read_lock(&d->arch.hvm.mmcfg_lock);
> - if ( (p->type == IOREQ_TYPE_PIO &&
> - (p->addr & ~3) == 0xcfc &&
> - CF8_ENABLED(cf8)) ||
> - (p->type == IOREQ_TYPE_COPY &&
> - (mmcfg = hvm_mmcfg_find(d, p->addr)) != NULL) )
> + switch ( p->type )
> {
> - uint32_t x86_fam;
> - pci_sbdf_t sbdf;
> - unsigned int reg;
> + case IOREQ_TYPE_PIO:
> + type = XEN_DMOP_IO_RANGE_PORT;
> + break;
>
> - reg = p->type == IOREQ_TYPE_PIO ? hvm_pci_decode_addr(cf8, p->addr,
> - &sbdf)
> - : hvm_mmcfg_decode_addr(mmcfg,
> p->addr,
> - &sbdf);
> + case IOREQ_TYPE_COPY:
> + type = XEN_DMOP_IO_RANGE_MEMORY;
> + break;
>
> - /* PCI config data cycle */
> + case IOREQ_TYPE_PCI_CONFIG:
> type = XEN_DMOP_IO_RANGE_PCI;
> - addr = ((uint64_t)sbdf.sbdf << 32) | reg;
> - /* AMD extended configuration space access? */
> - if ( p->type == IOREQ_TYPE_PIO && CF8_ADDR_HI(cf8) &&
> - d->arch.cpuid->x86_vendor == X86_VENDOR_AMD &&
> - (x86_fam = get_cpu_family(
> - d->arch.cpuid->basic.raw_fms, NULL, NULL)) > 0x10 &&
> - x86_fam < 0x17 )
> - {
> - uint64_t msr_val;
> + break;
>
> - if ( !rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) &&
> - (msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT)) )
> - addr |= CF8_ADDR_HI(cf8);
> - }
> - }
> - else
> - {
> - type = (p->type == IOREQ_TYPE_PIO) ?
> - XEN_DMOP_IO_RANGE_PORT : XEN_DMOP_IO_RANGE_MEMORY;
> - addr = p->addr;
> + default:
> + ASSERT_UNREACHABLE();
> + return XEN_INVALID_IOSERVID;
> }
> - read_unlock(&d->arch.hvm.mmcfg_lock);
>
> FOR_EACH_IOREQ_SERVER(d, id, s)
> {
> @@ -1416,7 +1443,7 @@ ioservid_t hvm_select_ioreq_server(struct domain *d,
> ioreq_t *p)
> unsigned long start, end;
>
> case XEN_DMOP_IO_RANGE_PORT:
> - start = addr;
> + start = p->addr;
> end = start + p->size - 1;
> if ( rangeset_contains_range(r, start, end) )
> return id;
> @@ -1433,12 +1460,8 @@ ioservid_t hvm_select_ioreq_server(struct domain *d,
> ioreq_t *p)
> break;
>
> case XEN_DMOP_IO_RANGE_PCI:
> - if ( rangeset_contains_singleton(r, addr >> 32) )
> - {
> - p->type = IOREQ_TYPE_PCI_CONFIG;
> - p->addr = addr;
> + if ( rangeset_contains_singleton(r, p->addr >> 32) )
> return id;
> - }
>
> break;
> }
> --
> 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 |