qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Fan Ni <fan.ni@samsung.com>
To: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: "qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	Michael Tsirkin <mst@redhat.com>,
	Ben Widawsky <bwidawsk@kernel.org>,
	"linux-cxl@vger.kernel.org" <linux-cxl@vger.kernel.org>,
	"linuxarm@huawei.com" <linuxarm@huawei.com>,
	Ira Weiny <ira.weiny@intel.com>,
	Dave Jiang <dave.jiang@intel.com>,
	"alison.schofield@intel.com" <alison.schofield@intel.com>
Subject: Re: [PATCH 2/2] hw/pxb-cxl: Support passthrough HDM Decoders unless overridden
Date: Thu, 26 Jan 2023 21:57:35 +0000	[thread overview]
Message-ID: <20230126215727.GA203951@bgt-140510-bm03> (raw)
In-Reply-To: <20230125152703.9928-3-Jonathan.Cameron@huawei.com>

On Wed, Jan 25, 2023 at 03:27:03PM +0000, Jonathan Cameron wrote:

> The CXL r3.0 specification allows for there to be no HDM decoders on CXL
> Host Bridges if they have only a single root port. Instead, all accesses
> directed to the host bridge (as specified in CXL Fixed Memory Windows)
> are assumed to be routed to the single root port.
> 
> Linux currently assumes this implementation choice. So to simplify testing,
> make QEMU emulation also default to no HDM decoders under these particular
> circumstances, but provide a hdm_for_passthrough boolean option to have
> HDM decoders as previously.
> 
> Technically this is breaking backwards compatibility, but given the only
> known software stack used with the QEMU emulation is the Linux kernel
> and this configuration did not work before this change, there are
> unlikely to be any complaints that it now works. The option is retained
> to allow testing of software that does allow for these HDM decoders to exist,
> once someone writes it.
> 
> Reported-by: Fan Ni <fan.ni@samsung.com>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
>  hw/cxl/cxl-host.c                   | 31 ++++++++++++--------
>  hw/pci-bridge/pci_expander_bridge.c | 44 +++++++++++++++++++++++++----
>  include/hw/cxl/cxl.h                |  1 +
>  include/hw/cxl/cxl_component.h      |  1 +
>  include/hw/pci/pci_bridge.h         |  1 +
>  5 files changed, 61 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
> index 3c1ec8732a..6e923ceeaf 100644
> --- a/hw/cxl/cxl-host.c
> +++ b/hw/cxl/cxl-host.c
> @@ -146,21 +146,28 @@ static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow *fw, hwaddr addr)
>          return NULL;
>      }
>  
> -    hb_cstate = cxl_get_hb_cstate(hb);
> -    if (!hb_cstate) {
> -        return NULL;
> -    }
> +    if (cxl_get_hb_passthrough(hb)) {
> +        rp = pcie_find_port_first(hb->bus);
> +        if (!rp) {
> +            return NULL;
> +        }
> +    } else {
> +        hb_cstate = cxl_get_hb_cstate(hb);
> +        if (!hb_cstate) {
> +            return NULL;
> +        }
>  
> -    cache_mem = hb_cstate->crb.cache_mem_registers;
> +        cache_mem = hb_cstate->crb.cache_mem_registers;
>  
> -    target_found = cxl_hdm_find_target(cache_mem, addr, &target);
> -    if (!target_found) {
> -        return NULL;
> -    }
> +        target_found = cxl_hdm_find_target(cache_mem, addr, &target);
> +        if (!target_found) {
> +            return NULL;
> +        }
>  
> -    rp = pcie_find_port_by_pn(hb->bus, target);
> -    if (!rp) {
> -        return NULL;
> +        rp = pcie_find_port_by_pn(hb->bus, target);
> +        if (!rp) {
> +            return NULL;
> +        }
>      }
>  
>      d = pci_bridge_get_sec_bus(PCI_BRIDGE(rp))->devices[0];
> diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
> index e752a21292..ead33f0c05 100644
> --- a/hw/pci-bridge/pci_expander_bridge.c
> +++ b/hw/pci-bridge/pci_expander_bridge.c
> @@ -15,6 +15,7 @@
>  #include "hw/pci/pci.h"
>  #include "hw/pci/pci_bus.h"
>  #include "hw/pci/pci_host.h"
> +#include "hw/pci/pcie_port.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/pci/pci_bridge.h"
>  #include "hw/pci-bridge/pci_expander_bridge.h"
> @@ -79,6 +80,13 @@ CXLComponentState *cxl_get_hb_cstate(PCIHostState *hb)
>      return &host->cxl_cstate;
>  }
>  
> +bool cxl_get_hb_passthrough(PCIHostState *hb)
> +{
> +    CXLHost *host = PXB_CXL_HOST(hb);
> +
> +    return host->passthrough;
> +}
> +
>  static int pxb_bus_num(PCIBus *bus)
>  {
>      PXBDev *pxb = convert_to_pxb(bus->parent_dev);
> @@ -289,15 +297,32 @@ static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
>      return pin - PCI_SLOT(pxb->devfn);
>  }
>  
> -static void pxb_dev_reset(DeviceState *dev)
> +static void pxb_cxl_dev_reset(DeviceState *dev)
>  {
>      CXLHost *cxl = PXB_CXL_DEV(dev)->cxl.cxl_host_bridge;
>      CXLComponentState *cxl_cstate = &cxl->cxl_cstate;
> +    PCIHostState *hb = PCI_HOST_BRIDGE(cxl);
>      uint32_t *reg_state = cxl_cstate->crb.cache_mem_registers;
>      uint32_t *write_msk = cxl_cstate->crb.cache_mem_regs_write_mask;
> +    int dsp_count = 0;
>  
>      cxl_component_register_init_common(reg_state, write_msk, CXL2_ROOT_PORT);
> -    ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, TARGET_COUNT, 8);
> +    /*
> +     * The CXL specification allows for host bridges with no HDM decoders
> +     * if they only have a single root port.
> +     */
> +    if (!PXB_DEV(dev)->hdm_for_passthrough) {
> +        dsp_count = pcie_count_ds_ports(hb->bus);
> +    }
> +    /* Initial reset will have 0 dsp so wait until > 0 */
> +    if (dsp_count == 1) {
> +        cxl->passthrough = true;
> +        /* Set Capability ID in header to NONE */
> +        ARRAY_FIELD_DP32(reg_state, CXL_HDM_CAPABILITY_HEADER, ID, 0);
> +    } else {
> +        ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, TARGET_COUNT,
> +                         8);
> +    }
>  }
>  
>  static gint pxb_compare(gconstpointer a, gconstpointer b)
> @@ -481,9 +506,18 @@ static void pxb_cxl_dev_realize(PCIDevice *dev, Error **errp)
>      }
>  
>      pxb_dev_realize_common(dev, CXL, errp);
> -    pxb_dev_reset(DEVICE(dev));
> +    pxb_cxl_dev_reset(DEVICE(dev));
>  }
>  
> +static Property pxb_cxl_dev_properties[] = {
> +    /* Note: 0 is not a legal PXB bus number. */
> +    DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0),
> +    DEFINE_PROP_UINT16("numa_node", PXBDev, numa_node, NUMA_NODE_UNASSIGNED),
> +    DEFINE_PROP_BOOL("bypass_iommu", PXBDev, bypass_iommu, false),
> +    DEFINE_PROP_BOOL("hdm_for_passthrough", PXBDev, hdm_for_passthrough, false),
when setting hdm_for_passthrough to true at the qemu command line, we
will see the segfault issue as before. I think this is expected as it
is the logic in cxl_cfmws_find_device. Wondering if there will be
following fixes to handle the case when hdm_for_passthrough is true.
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
>  static void pxb_cxl_dev_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc   = DEVICE_CLASS(klass);
> @@ -497,12 +531,12 @@ static void pxb_cxl_dev_class_init(ObjectClass *klass, void *data)
>       */
>  
>      dc->desc = "CXL Host Bridge";
> -    device_class_set_props(dc, pxb_dev_properties);
> +    device_class_set_props(dc, pxb_cxl_dev_properties);
>      set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
>  
>      /* Host bridges aren't hotpluggable. FIXME: spec reference */
>      dc->hotpluggable = false;
> -    dc->reset = pxb_dev_reset;
> +    dc->reset = pxb_cxl_dev_reset;
>  }
>  
>  static const TypeInfo pxb_cxl_dev_info = {
> diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h
> index b161be59b7..b2cffbb364 100644
> --- a/include/hw/cxl/cxl.h
> +++ b/include/hw/cxl/cxl.h
> @@ -49,6 +49,7 @@ struct CXLHost {
>      PCIHostState parent_obj;
>  
>      CXLComponentState cxl_cstate;
> +    bool passthrough;
>  };
>  
>  #define TYPE_PXB_CXL_HOST "pxb-cxl-host"
> diff --git a/include/hw/cxl/cxl_component.h b/include/hw/cxl/cxl_component.h
> index 8752171f70..b4104b78b5 100644
> --- a/include/hw/cxl/cxl_component.h
> +++ b/include/hw/cxl/cxl_component.h
> @@ -249,6 +249,7 @@ static inline hwaddr cxl_decode_ig(int ig)
>  }
>  
>  CXLComponentState *cxl_get_hb_cstate(PCIHostState *hb);
> +bool cxl_get_hb_passthrough(PCIHostState *hb);
>  
>  void cxl_doe_cdat_init(CXLComponentState *cxl_cstate, Error **errp);
>  void cxl_doe_cdat_release(CXLComponentState *cxl_cstate);
> diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h
> index 63a7521567..81a058bb2c 100644
> --- a/include/hw/pci/pci_bridge.h
> +++ b/include/hw/pci/pci_bridge.h
> @@ -92,6 +92,7 @@ struct PXBDev {
>      uint8_t bus_nr;
>      uint16_t numa_node;
>      bool bypass_iommu;
> +    bool hdm_for_passthrough;
>      struct cxl_dev {
>          CXLHost *cxl_host_bridge; /* Pointer to a CXLHost */
>      } cxl;
> -- 
> 2.37.2
> 
> 

  parent reply	other threads:[~2023-01-26 21:58 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-25 15:27 [PATCH 0/2] hw/cxl: Passthrough HDM decoder emulation Jonathan Cameron via
2023-01-25 15:27 ` [PATCH 1/2] hw/pci: Add pcie_count_ds_port() and pcie_find_port_first() helpers Jonathan Cameron via
2023-01-25 15:27 ` [PATCH 2/2] hw/pxb-cxl: Support passthrough HDM Decoders unless overridden Jonathan Cameron via
     [not found]   ` <CGME20230126215736uscas1p2166334bf8185239cf6ac70053dc386c5@uscas1p2.samsung.com>
2023-01-26 21:57     ` Fan Ni [this message]
2023-01-27 10:01       ` Jonathan Cameron via
2023-01-27 17:02         ` Fan Ni
2023-01-27 17:15           ` Jonathan Cameron via

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=20230126215727.GA203951@bgt-140510-bm03 \
    --to=fan.ni@samsung.com \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=alison.schofield@intel.com \
    --cc=bwidawsk@kernel.org \
    --cc=dave.jiang@intel.com \
    --cc=ira.weiny@intel.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linuxarm@huawei.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).