All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad@darnok.org>
To: Anthony PERARD <anthony.perard@citrix.com>
Cc: Guy Zana <guy@neocleus.com>,
	Xen Devel <xen-devel@lists.xensource.com>,
	Allen Kay <allen.m.kay@intel.com>,
	QEMU-devel <qemu-devel@nongnu.org>,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: Re: [Qemu-devel] [Xen-devel] [PATCH V11 5/8] Introduce Xen PCI Passthrough, qdevice (1/3)
Date: Wed, 16 May 2012 07:31:43 -0400	[thread overview]
Message-ID: <20120516113142.GC21609@andromeda.dapyr.net> (raw)
In-Reply-To: <1333467163-25795-6-git-send-email-anthony.perard@citrix.com>

> +void xen_pt_log(const PCIDevice *d, const char *f, ...)
> +{
> +    va_list ap;
> +
> +    va_start(ap, f);
> +    if (d) {
> +        fprintf(stderr, "[%02x:%02x.%x] ", pci_bus_num(d->bus),

%d at the end and in the other location pls fix it up..

> +                PCI_SLOT(d->devfn), PCI_FUNC(d->devfn));
> +    }
> +    vfprintf(stderr, f, ap);
> +    va_end(ap);
> +}
> +
> +/* Config Space */
> +

.. Is there a way to make this function (and the following one) squahed?

> +static uint32_t xen_pt_pci_read_config(PCIDevice *d, uint32_t addr, int len)
> +{
> +    XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d);
> +    uint32_t val = 0;
> +    XenPTRegGroup *reg_grp_entry = NULL;
> +    XenPTReg *reg_entry = NULL;
> +    int rc = 0;
> +    int emul_len = 0;
> +    uint32_t find_addr = addr;
> +
> +    if (xen_pt_pci_config_access_check(d, addr, len)) {
> +        goto exit;
> +    }
> +
> +    /* find register group entry */
> +    reg_grp_entry = xen_pt_find_reg_grp(s, addr);
> +    if (reg_grp_entry) {
> +        /* check 0-Hardwired register group */
> +        if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) {
> +            /* no need to emulate, just return 0 */
> +            val = 0;
> +            goto exit;
> +        }
> +    }
> +
> +    /* read I/O device register value */
> +    rc = xen_host_pci_get_block(&s->real_device, addr, (uint8_t *)&val, len);
> +    if (rc < 0) {
> +        XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
> +        memset(&val, 0xff, len);
> +    }
> +
> +    /* just return the I/O device register value for
> +     * passthrough type register group */
> +    if (reg_grp_entry == NULL) {
> +        goto exit;
> +    }
> +
> +    /* adjust the read value to appropriate CFC-CFF window */
> +    val <<= (addr & 3) << 3;
> +    emul_len = len;
> +
> +    /* loop around the guest requested size */
> +    while (emul_len > 0) {
> +        /* find register entry to be emulated */
> +        reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr);
> +        if (reg_entry) {
> +            XenPTRegInfo *reg = reg_entry->reg;
> +            uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
> +            uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
> +            uint8_t *ptr_val = NULL;
> +
> +            valid_mask <<= (find_addr - real_offset) << 3;
> +            ptr_val = (uint8_t *)&val + (real_offset & 3);
> +
> +            /* do emulation based on register size */
> +            switch (reg->size) {
> +            case 1:
> +                if (reg->u.b.read) {
> +                    rc = reg->u.b.read(s, reg_entry, ptr_val, valid_mask);
> +                }
> +                break;
> +            case 2:
> +                if (reg->u.w.read) {
> +                    rc = reg->u.w.read(s, reg_entry,
> +                                       (uint16_t *)ptr_val, valid_mask);
> +                }
> +                break;
> +            case 4:
> +                if (reg->u.dw.read) {
> +                    rc = reg->u.dw.read(s, reg_entry,
> +                                        (uint32_t *)ptr_val, valid_mask);
> +                }
> +                break;
> +            }
> +
> +            if (rc < 0) {
> +                xen_shutdown_fatal_error("Internal error: Invalid read "
> +                                         "emulation. (%s, rc: %d)\n",
> +                                         __func__, rc);
> +                return 0;
> +            }
> +
> +            /* calculate next address to find */
> +            emul_len -= reg->size;
> +            if (emul_len > 0) {
> +                find_addr = real_offset + reg->size;
> +            }
> +        } else {
> +            /* nothing to do with passthrough type register,
> +             * continue to find next byte */
> +            emul_len--;
> +            find_addr++;
> +        }
> +    }
> +
> +    /* need to shift back before returning them to pci bus emulator */
> +    val >>= ((addr & 3) << 3);
> +
> +exit:
> +    XEN_PT_LOG_CONFIG(d, addr, val, len);
> +    return val;
> +}
> +
> +static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
> +                                    uint32_t val, int len)
> +{
> +    XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d);
> +    int index = 0;
> +    XenPTRegGroup *reg_grp_entry = NULL;
> +    int rc = 0;
> +    uint32_t read_val = 0;
> +    int emul_len = 0;
> +    XenPTReg *reg_entry = NULL;
> +    uint32_t find_addr = addr;
> +    XenPTRegInfo *reg = NULL;
> +
> +    if (xen_pt_pci_config_access_check(d, addr, len)) {
> +        return;
> +    }
> +
> +    XEN_PT_LOG_CONFIG(d, addr, val, len);
> +
> +    /* check unused BAR register */
> +    index = xen_pt_bar_offset_to_index(addr);
> +    if ((index >= 0) && (val > 0 && val < XEN_PT_BAR_ALLF) &&
> +        (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED)) {
> +        XEN_PT_WARN(d, "Guest attempt to set address to unused Base Address "
> +                    "Register. (addr: 0x%02x, len: %d)\n", addr, len);
> +    }
> +
> +    /* find register group entry */
> +    reg_grp_entry = xen_pt_find_reg_grp(s, addr);
> +    if (reg_grp_entry) {
> +        /* check 0-Hardwired register group */
> +        if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) {
> +            /* ignore silently */
> +            XEN_PT_WARN(d, "Access to 0-Hardwired register. "
> +                        "(addr: 0x%02x, len: %d)\n", addr, len);
> +            return;
> +        }
> +    }
> +
> +    rc = xen_host_pci_get_block(&s->real_device, addr,
> +                                (uint8_t *)&read_val, len);
> +    if (rc < 0) {
> +        XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
> +        memset(&read_val, 0xff, len);
> +    }
> +
> +    /* pass directly to the real device for passthrough type register group */
> +    if (reg_grp_entry == NULL) {
> +        goto out;
> +    }
> +
> +    memory_region_transaction_begin();
> +    pci_default_write_config(d, addr, val, len);
> +
> +    /* adjust the read and write value to appropriate CFC-CFF window */
> +    read_val <<= (addr & 3) << 3;
> +    val <<= (addr & 3) << 3;
> +    emul_len = len;
> +
> +    /* loop around the guest requested size */
> +    while (emul_len > 0) {
> +        /* find register entry to be emulated */
> +        reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr);
> +        if (reg_entry) {
> +            reg = reg_entry->reg;
> +            uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
> +            uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
> +            uint8_t *ptr_val = NULL;
> +
> +            valid_mask <<= (find_addr - real_offset) << 3;
> +            ptr_val = (uint8_t *)&val + (real_offset & 3);
> +
> +            /* do emulation based on register size */
> +            switch (reg->size) {
> +            case 1:
> +                if (reg->u.b.write) {
> +                    rc = reg->u.b.write(s, reg_entry, ptr_val,
> +                                        read_val >> ((real_offset & 3) << 3),
> +                                        valid_mask);
> +                }
> +                break;
> +            case 2:
> +                if (reg->u.w.write) {
> +                    rc = reg->u.w.write(s, reg_entry, (uint16_t *)ptr_val,
> +                                        (read_val >> ((real_offset & 3) << 3)),
> +                                        valid_mask);
> +                }
> +                break;
> +            case 4:
> +                if (reg->u.dw.write) {
> +                    rc = reg->u.dw.write(s, reg_entry, (uint32_t *)ptr_val,
> +                                         (read_val >> ((real_offset & 3) << 3)),
> +                                         valid_mask);
> +                }
> +                break;
> +            }
> +
> +            if (rc < 0) {
> +                xen_shutdown_fatal_error("Internal error: Invalid write"
> +                                         " emulation. (%s, rc: %d)\n",
> +                                         __func__, rc);
> +                return;
> +            }
> +
> +            /* calculate next address to find */
> +            emul_len -= reg->size;
> +            if (emul_len > 0) {
> +                find_addr = real_offset + reg->size;
> +            }
> +        } else {
> +            /* nothing to do with passthrough type register,
> +             * continue to find next byte */
> +            emul_len--;
> +            find_addr++;
> +        }
> +    }
> +
> +    /* need to shift back before passing them to xen_host_pci_device */
> +    val >>= (addr & 3) << 3;
> +
> +    memory_region_transaction_commit();

WARNING: multiple messages have this Message-ID (diff)
From: Konrad Rzeszutek Wilk <konrad@darnok.org>
To: Anthony PERARD <anthony.perard@citrix.com>
Cc: Guy Zana <guy@neocleus.com>,
	Xen Devel <xen-devel@lists.xensource.com>,
	Allen Kay <allen.m.kay@intel.com>,
	QEMU-devel <qemu-devel@nongnu.org>,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: Re: [Xen-devel] [PATCH V11 5/8] Introduce Xen PCI Passthrough, qdevice (1/3)
Date: Wed, 16 May 2012 07:31:43 -0400	[thread overview]
Message-ID: <20120516113142.GC21609@andromeda.dapyr.net> (raw)
In-Reply-To: <1333467163-25795-6-git-send-email-anthony.perard@citrix.com>

> +void xen_pt_log(const PCIDevice *d, const char *f, ...)
> +{
> +    va_list ap;
> +
> +    va_start(ap, f);
> +    if (d) {
> +        fprintf(stderr, "[%02x:%02x.%x] ", pci_bus_num(d->bus),

%d at the end and in the other location pls fix it up..

> +                PCI_SLOT(d->devfn), PCI_FUNC(d->devfn));
> +    }
> +    vfprintf(stderr, f, ap);
> +    va_end(ap);
> +}
> +
> +/* Config Space */
> +

.. Is there a way to make this function (and the following one) squahed?

> +static uint32_t xen_pt_pci_read_config(PCIDevice *d, uint32_t addr, int len)
> +{
> +    XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d);
> +    uint32_t val = 0;
> +    XenPTRegGroup *reg_grp_entry = NULL;
> +    XenPTReg *reg_entry = NULL;
> +    int rc = 0;
> +    int emul_len = 0;
> +    uint32_t find_addr = addr;
> +
> +    if (xen_pt_pci_config_access_check(d, addr, len)) {
> +        goto exit;
> +    }
> +
> +    /* find register group entry */
> +    reg_grp_entry = xen_pt_find_reg_grp(s, addr);
> +    if (reg_grp_entry) {
> +        /* check 0-Hardwired register group */
> +        if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) {
> +            /* no need to emulate, just return 0 */
> +            val = 0;
> +            goto exit;
> +        }
> +    }
> +
> +    /* read I/O device register value */
> +    rc = xen_host_pci_get_block(&s->real_device, addr, (uint8_t *)&val, len);
> +    if (rc < 0) {
> +        XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
> +        memset(&val, 0xff, len);
> +    }
> +
> +    /* just return the I/O device register value for
> +     * passthrough type register group */
> +    if (reg_grp_entry == NULL) {
> +        goto exit;
> +    }
> +
> +    /* adjust the read value to appropriate CFC-CFF window */
> +    val <<= (addr & 3) << 3;
> +    emul_len = len;
> +
> +    /* loop around the guest requested size */
> +    while (emul_len > 0) {
> +        /* find register entry to be emulated */
> +        reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr);
> +        if (reg_entry) {
> +            XenPTRegInfo *reg = reg_entry->reg;
> +            uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
> +            uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
> +            uint8_t *ptr_val = NULL;
> +
> +            valid_mask <<= (find_addr - real_offset) << 3;
> +            ptr_val = (uint8_t *)&val + (real_offset & 3);
> +
> +            /* do emulation based on register size */
> +            switch (reg->size) {
> +            case 1:
> +                if (reg->u.b.read) {
> +                    rc = reg->u.b.read(s, reg_entry, ptr_val, valid_mask);
> +                }
> +                break;
> +            case 2:
> +                if (reg->u.w.read) {
> +                    rc = reg->u.w.read(s, reg_entry,
> +                                       (uint16_t *)ptr_val, valid_mask);
> +                }
> +                break;
> +            case 4:
> +                if (reg->u.dw.read) {
> +                    rc = reg->u.dw.read(s, reg_entry,
> +                                        (uint32_t *)ptr_val, valid_mask);
> +                }
> +                break;
> +            }
> +
> +            if (rc < 0) {
> +                xen_shutdown_fatal_error("Internal error: Invalid read "
> +                                         "emulation. (%s, rc: %d)\n",
> +                                         __func__, rc);
> +                return 0;
> +            }
> +
> +            /* calculate next address to find */
> +            emul_len -= reg->size;
> +            if (emul_len > 0) {
> +                find_addr = real_offset + reg->size;
> +            }
> +        } else {
> +            /* nothing to do with passthrough type register,
> +             * continue to find next byte */
> +            emul_len--;
> +            find_addr++;
> +        }
> +    }
> +
> +    /* need to shift back before returning them to pci bus emulator */
> +    val >>= ((addr & 3) << 3);
> +
> +exit:
> +    XEN_PT_LOG_CONFIG(d, addr, val, len);
> +    return val;
> +}
> +
> +static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
> +                                    uint32_t val, int len)
> +{
> +    XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d);
> +    int index = 0;
> +    XenPTRegGroup *reg_grp_entry = NULL;
> +    int rc = 0;
> +    uint32_t read_val = 0;
> +    int emul_len = 0;
> +    XenPTReg *reg_entry = NULL;
> +    uint32_t find_addr = addr;
> +    XenPTRegInfo *reg = NULL;
> +
> +    if (xen_pt_pci_config_access_check(d, addr, len)) {
> +        return;
> +    }
> +
> +    XEN_PT_LOG_CONFIG(d, addr, val, len);
> +
> +    /* check unused BAR register */
> +    index = xen_pt_bar_offset_to_index(addr);
> +    if ((index >= 0) && (val > 0 && val < XEN_PT_BAR_ALLF) &&
> +        (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED)) {
> +        XEN_PT_WARN(d, "Guest attempt to set address to unused Base Address "
> +                    "Register. (addr: 0x%02x, len: %d)\n", addr, len);
> +    }
> +
> +    /* find register group entry */
> +    reg_grp_entry = xen_pt_find_reg_grp(s, addr);
> +    if (reg_grp_entry) {
> +        /* check 0-Hardwired register group */
> +        if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) {
> +            /* ignore silently */
> +            XEN_PT_WARN(d, "Access to 0-Hardwired register. "
> +                        "(addr: 0x%02x, len: %d)\n", addr, len);
> +            return;
> +        }
> +    }
> +
> +    rc = xen_host_pci_get_block(&s->real_device, addr,
> +                                (uint8_t *)&read_val, len);
> +    if (rc < 0) {
> +        XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
> +        memset(&read_val, 0xff, len);
> +    }
> +
> +    /* pass directly to the real device for passthrough type register group */
> +    if (reg_grp_entry == NULL) {
> +        goto out;
> +    }
> +
> +    memory_region_transaction_begin();
> +    pci_default_write_config(d, addr, val, len);
> +
> +    /* adjust the read and write value to appropriate CFC-CFF window */
> +    read_val <<= (addr & 3) << 3;
> +    val <<= (addr & 3) << 3;
> +    emul_len = len;
> +
> +    /* loop around the guest requested size */
> +    while (emul_len > 0) {
> +        /* find register entry to be emulated */
> +        reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr);
> +        if (reg_entry) {
> +            reg = reg_entry->reg;
> +            uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
> +            uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
> +            uint8_t *ptr_val = NULL;
> +
> +            valid_mask <<= (find_addr - real_offset) << 3;
> +            ptr_val = (uint8_t *)&val + (real_offset & 3);
> +
> +            /* do emulation based on register size */
> +            switch (reg->size) {
> +            case 1:
> +                if (reg->u.b.write) {
> +                    rc = reg->u.b.write(s, reg_entry, ptr_val,
> +                                        read_val >> ((real_offset & 3) << 3),
> +                                        valid_mask);
> +                }
> +                break;
> +            case 2:
> +                if (reg->u.w.write) {
> +                    rc = reg->u.w.write(s, reg_entry, (uint16_t *)ptr_val,
> +                                        (read_val >> ((real_offset & 3) << 3)),
> +                                        valid_mask);
> +                }
> +                break;
> +            case 4:
> +                if (reg->u.dw.write) {
> +                    rc = reg->u.dw.write(s, reg_entry, (uint32_t *)ptr_val,
> +                                         (read_val >> ((real_offset & 3) << 3)),
> +                                         valid_mask);
> +                }
> +                break;
> +            }
> +
> +            if (rc < 0) {
> +                xen_shutdown_fatal_error("Internal error: Invalid write"
> +                                         " emulation. (%s, rc: %d)\n",
> +                                         __func__, rc);
> +                return;
> +            }
> +
> +            /* calculate next address to find */
> +            emul_len -= reg->size;
> +            if (emul_len > 0) {
> +                find_addr = real_offset + reg->size;
> +            }
> +        } else {
> +            /* nothing to do with passthrough type register,
> +             * continue to find next byte */
> +            emul_len--;
> +            find_addr++;
> +        }
> +    }
> +
> +    /* need to shift back before passing them to xen_host_pci_device */
> +    val >>= (addr & 3) << 3;
> +
> +    memory_region_transaction_commit();

  reply	other threads:[~2012-05-16 11:32 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-03 15:32 [Qemu-devel] [PATCH V11 0/8] Xen PCI Passthrough Anthony PERARD
2012-04-03 15:32 ` Anthony PERARD
2012-04-03 15:32 ` [Qemu-devel] [PATCH V11 1/8] pci_ids: Add INTEL_82599_SFP_VF id Anthony PERARD
2012-04-03 15:32   ` Anthony PERARD
2012-04-03 15:32 ` [Qemu-devel] [PATCH V11 2/8] configure: Introduce --enable-xen-pci-passthrough Anthony PERARD
2012-04-03 15:32   ` Anthony PERARD
2012-04-03 15:32 ` [Qemu-devel] [PATCH V11 3/8] Introduce XenHostPCIDevice to access a pci device on the host Anthony PERARD
2012-04-03 15:32   ` Anthony PERARD
2012-05-16 11:24   ` [Qemu-devel] [Xen-devel] " Konrad Rzeszutek Wilk
2012-05-16 11:24     ` Konrad Rzeszutek Wilk
2012-05-22 12:52     ` [Qemu-devel] " Anthony PERARD
2012-05-22 12:52       ` Anthony PERARD
2012-04-03 15:32 ` [Qemu-devel] [PATCH V11 4/8] pci.c: Add opaque argument to pci_for_each_device Anthony PERARD
2012-04-03 15:32   ` Anthony PERARD
2012-04-03 15:32 ` [Qemu-devel] [PATCH V11 5/8] Introduce Xen PCI Passthrough, qdevice (1/3) Anthony PERARD
2012-04-03 15:32   ` Anthony PERARD
2012-05-16 11:31   ` Konrad Rzeszutek Wilk [this message]
2012-05-16 11:31     ` [Xen-devel] " Konrad Rzeszutek Wilk
2012-04-03 15:32 ` [Qemu-devel] [PATCH V11 6/8] Introduce Xen PCI Passthrough, PCI config space helpers (2/3) Anthony PERARD
2012-04-03 15:32   ` Anthony PERARD
2012-04-03 15:32 ` [Qemu-devel] [PATCH V11 7/8] Introduce apic-msidef.h Anthony PERARD
2012-04-03 15:32   ` Anthony PERARD
2012-04-03 15:32 ` [Qemu-devel] [PATCH V11 8/8] Introduce Xen PCI Passthrough, MSI (3/3) Anthony PERARD
2012-04-03 15:32   ` Anthony PERARD

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120516113142.GC21609@andromeda.dapyr.net \
    --to=konrad@darnok.org \
    --cc=allen.m.kay@intel.com \
    --cc=anthony.perard@citrix.com \
    --cc=guy@neocleus.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.