diff mbox series

[v4,12/28] cxl/cdat: Gather DSMAS data for DCD regions

Message ID 20241007-dcd-type2-upstream-v4-12-c261ee6eeded@intel.com
State Superseded
Headers show
Series DCD: Add support for Dynamic Capacity Devices (DCD) | expand

Commit Message

Ira Weiny Oct. 7, 2024, 11:16 p.m. UTC
Additional DCD region (partition) information is contained in the DSMAS
CDAT tables, including performance, read only, and shareable attributes.

Match DCD partitions with DSMAS tables and store the meta data.

To: Robert Moore <robert.moore@intel.com>
To: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
To: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
Cc: acpica-devel@lists.linux.dev
Signed-off-by: Ira Weiny <ira.weiny@intel.com>

---
Changes:
[iweiny: new patch]
[iweiny: Gather shareable/read-only flags for later use]
---
 drivers/cxl/core/cdat.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/cxl/core/mbox.c |  2 ++
 drivers/cxl/cxlmem.h    |  3 +++
 include/acpi/actbl1.h   |  2 ++
 4 files changed, 45 insertions(+)

Comments

Rafael J. Wysocki Oct. 9, 2024, 2:42 p.m. UTC | #1
On Tue, Oct 8, 2024 at 1:17 AM Ira Weiny <ira.weiny@intel.com> wrote:
>
> Additional DCD region (partition) information is contained in the DSMAS
> CDAT tables, including performance, read only, and shareable attributes.
>
> Match DCD partitions with DSMAS tables and store the meta data.
>
> To: Robert Moore <robert.moore@intel.com>
> To: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> To: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> Cc: acpica-devel@lists.linux.dev
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
>
> ---
> Changes:
> [iweiny: new patch]
> [iweiny: Gather shareable/read-only flags for later use]
> ---
>  drivers/cxl/core/cdat.c | 38 ++++++++++++++++++++++++++++++++++++++
>  drivers/cxl/core/mbox.c |  2 ++
>  drivers/cxl/cxlmem.h    |  3 +++
>  include/acpi/actbl1.h   |  2 ++
>  4 files changed, 45 insertions(+)
>
> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
> index bd50bb655741..9b2f717a16e5 100644
> --- a/drivers/cxl/core/cdat.c
> +++ b/drivers/cxl/core/cdat.c
> @@ -17,6 +17,8 @@ struct dsmas_entry {
>         struct access_coordinate cdat_coord[ACCESS_COORDINATE_MAX];
>         int entries;
>         int qos_class;
> +       bool shareable;
> +       bool read_only;
>  };
>
>  static u32 cdat_normalize(u16 entry, u64 base, u8 type)
> @@ -74,6 +76,8 @@ static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg,
>                 return -ENOMEM;
>
>         dent->handle = dsmas->dsmad_handle;
> +       dent->shareable = dsmas->flags & ACPI_CDAT_DSMAS_SHAREABLE;
> +       dent->read_only = dsmas->flags & ACPI_CDAT_DSMAS_READ_ONLY;
>         dent->dpa_range.start = le64_to_cpu((__force __le64)dsmas->dpa_base_address);
>         dent->dpa_range.end = le64_to_cpu((__force __le64)dsmas->dpa_base_address) +
>                               le64_to_cpu((__force __le64)dsmas->dpa_length) - 1;
> @@ -255,6 +259,38 @@ static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
>                 dent->coord[ACCESS_COORDINATE_CPU].write_latency);
>  }
>
> +
> +static void update_dcd_perf(struct cxl_dev_state *cxlds,
> +                           struct dsmas_entry *dent)
> +{
> +       struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
> +       struct device *dev = cxlds->dev;
> +
> +       for (int i = 0; i < mds->nr_dc_region; i++) {
> +               /* CXL defines a u32 handle while cdat defines u8, ignore upper bits */
> +               u8 dc_handle = mds->dc_region[i].dsmad_handle & 0xff;
> +
> +               if (resource_size(&cxlds->dc_res[i])) {
> +                       struct range dc_range = {
> +                               .start = cxlds->dc_res[i].start,
> +                               .end = cxlds->dc_res[i].end,
> +                       };
> +
> +                       if (range_contains(&dent->dpa_range, &dc_range)) {
> +                               if (dent->handle != dc_handle)
> +                                       dev_warn(dev, "DC Region/DSMAS mis-matched handle/range; region %pra (%u); dsmas %pra (%u)\n"
> +                                                     "   setting DC region attributes regardless\n",
> +                                               &dent->dpa_range, dent->handle,
> +                                               &dc_range, dc_handle);
> +
> +                               mds->dc_region[i].shareable = dent->shareable;
> +                               mds->dc_region[i].read_only = dent->read_only;
> +                               update_perf_entry(dev, dent, &mds->dc_perf[i]);
> +                       }
> +               }
> +       }
> +}
> +
>  static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
>                                      struct xarray *dsmas_xa)
>  {
> @@ -278,6 +314,8 @@ static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
>                 else if (resource_size(&cxlds->pmem_res) &&
>                          range_contains(&pmem_range, &dent->dpa_range))
>                         update_perf_entry(dev, dent, &mds->pmem_perf);
> +               else if (cxl_dcd_supported(mds))
> +                       update_dcd_perf(cxlds, dent);
>                 else
>                         dev_dbg(dev, "no partition for dsmas dpa: %pra\n",
>                                 &dent->dpa_range);
> diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
> index 4b51ddd1ff94..3ba465823564 100644
> --- a/drivers/cxl/core/mbox.c
> +++ b/drivers/cxl/core/mbox.c
> @@ -1649,6 +1649,8 @@ struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
>         mds->cxlds.type = CXL_DEVTYPE_CLASSMEM;
>         mds->ram_perf.qos_class = CXL_QOS_CLASS_INVALID;
>         mds->pmem_perf.qos_class = CXL_QOS_CLASS_INVALID;
> +       for (int i = 0; i < CXL_MAX_DC_REGION; i++)
> +               mds->dc_perf[i].qos_class = CXL_QOS_CLASS_INVALID;
>
>         return mds;
>  }
> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
> index 0690b917b1e0..c3b889a586d8 100644
> --- a/drivers/cxl/cxlmem.h
> +++ b/drivers/cxl/cxlmem.h
> @@ -466,6 +466,8 @@ struct cxl_dc_region_info {
>         u64 blk_size;
>         u32 dsmad_handle;
>         u8 flags;
> +       bool shareable;
> +       bool read_only;
>         u8 name[CXL_DC_REGION_STRLEN];
>  };
>
> @@ -533,6 +535,7 @@ struct cxl_memdev_state {
>
>         u8 nr_dc_region;
>         struct cxl_dc_region_info dc_region[CXL_MAX_DC_REGION];
> +       struct cxl_dpa_perf dc_perf[CXL_MAX_DC_REGION];
>
>         struct cxl_event_state event;
>         struct cxl_poison_state poison;
> diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
> index 199afc2cd122..387fc821703a 100644
> --- a/include/acpi/actbl1.h
> +++ b/include/acpi/actbl1.h
> @@ -403,6 +403,8 @@ struct acpi_cdat_dsmas {
>  /* Flags for subtable above */
>
>  #define ACPI_CDAT_DSMAS_NON_VOLATILE        (1 << 2)
> +#define ACPI_CDAT_DSMAS_SHAREABLE           (1 << 3)
> +#define ACPI_CDAT_DSMAS_READ_ONLY           (1 << 6)
>
>  /* Subtable 1: Device scoped Latency and Bandwidth Information Structure (DSLBIS) */
>

Is there an upstream ACPICA commit for this?
Fan Ni Oct. 9, 2024, 6:16 p.m. UTC | #2
On Mon, Oct 07, 2024 at 06:16:18PM -0500, Ira Weiny wrote:
> Additional DCD region (partition) information is contained in the DSMAS
> CDAT tables, including performance, read only, and shareable attributes.
> 
> Match DCD partitions with DSMAS tables and store the meta data.
> 
> To: Robert Moore <robert.moore@intel.com>
> To: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> To: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> Cc: acpica-devel@lists.linux.dev
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> 

One minor comment inline.

> ---
> Changes:
> [iweiny: new patch]
> [iweiny: Gather shareable/read-only flags for later use]
> ---
>  drivers/cxl/core/cdat.c | 38 ++++++++++++++++++++++++++++++++++++++
>  drivers/cxl/core/mbox.c |  2 ++
>  drivers/cxl/cxlmem.h    |  3 +++
>  include/acpi/actbl1.h   |  2 ++
>  4 files changed, 45 insertions(+)
> 
> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
> index bd50bb655741..9b2f717a16e5 100644
> --- a/drivers/cxl/core/cdat.c
> +++ b/drivers/cxl/core/cdat.c
> @@ -17,6 +17,8 @@ struct dsmas_entry {
>  	struct access_coordinate cdat_coord[ACCESS_COORDINATE_MAX];
>  	int entries;
>  	int qos_class;
> +	bool shareable;
> +	bool read_only;
>  };
>  
>  static u32 cdat_normalize(u16 entry, u64 base, u8 type)
> @@ -74,6 +76,8 @@ static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg,
>  		return -ENOMEM;
>  
>  	dent->handle = dsmas->dsmad_handle;
> +	dent->shareable = dsmas->flags & ACPI_CDAT_DSMAS_SHAREABLE;
> +	dent->read_only = dsmas->flags & ACPI_CDAT_DSMAS_READ_ONLY;
>  	dent->dpa_range.start = le64_to_cpu((__force __le64)dsmas->dpa_base_address);
>  	dent->dpa_range.end = le64_to_cpu((__force __le64)dsmas->dpa_base_address) +
>  			      le64_to_cpu((__force __le64)dsmas->dpa_length) - 1;
> @@ -255,6 +259,38 @@ static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
>  		dent->coord[ACCESS_COORDINATE_CPU].write_latency);
>  }
>  
> +
Unwanted blank line.

Fan
> +static void update_dcd_perf(struct cxl_dev_state *cxlds,
> +			    struct dsmas_entry *dent)
> +{
> +	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
> +	struct device *dev = cxlds->dev;
> +
> +	for (int i = 0; i < mds->nr_dc_region; i++) {
> +		/* CXL defines a u32 handle while cdat defines u8, ignore upper bits */
> +		u8 dc_handle = mds->dc_region[i].dsmad_handle & 0xff;
> +
> +		if (resource_size(&cxlds->dc_res[i])) {
> +			struct range dc_range = {
> +				.start = cxlds->dc_res[i].start,
> +				.end = cxlds->dc_res[i].end,
> +			};
> +
> +			if (range_contains(&dent->dpa_range, &dc_range)) {
> +				if (dent->handle != dc_handle)
> +					dev_warn(dev, "DC Region/DSMAS mis-matched handle/range; region %pra (%u); dsmas %pra (%u)\n"
> +						      "   setting DC region attributes regardless\n",
> +						&dent->dpa_range, dent->handle,
> +						&dc_range, dc_handle);
> +
> +				mds->dc_region[i].shareable = dent->shareable;
> +				mds->dc_region[i].read_only = dent->read_only;
> +				update_perf_entry(dev, dent, &mds->dc_perf[i]);
> +			}
> +		}
> +	}
> +}
> +
>  static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
>  				     struct xarray *dsmas_xa)
>  {
> @@ -278,6 +314,8 @@ static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
>  		else if (resource_size(&cxlds->pmem_res) &&
>  			 range_contains(&pmem_range, &dent->dpa_range))
>  			update_perf_entry(dev, dent, &mds->pmem_perf);
> +		else if (cxl_dcd_supported(mds))
> +			update_dcd_perf(cxlds, dent);
>  		else
>  			dev_dbg(dev, "no partition for dsmas dpa: %pra\n",
>  				&dent->dpa_range);
> diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
> index 4b51ddd1ff94..3ba465823564 100644
> --- a/drivers/cxl/core/mbox.c
> +++ b/drivers/cxl/core/mbox.c
> @@ -1649,6 +1649,8 @@ struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
>  	mds->cxlds.type = CXL_DEVTYPE_CLASSMEM;
>  	mds->ram_perf.qos_class = CXL_QOS_CLASS_INVALID;
>  	mds->pmem_perf.qos_class = CXL_QOS_CLASS_INVALID;
> +	for (int i = 0; i < CXL_MAX_DC_REGION; i++)
> +		mds->dc_perf[i].qos_class = CXL_QOS_CLASS_INVALID;
>  
>  	return mds;
>  }
> diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
> index 0690b917b1e0..c3b889a586d8 100644
> --- a/drivers/cxl/cxlmem.h
> +++ b/drivers/cxl/cxlmem.h
> @@ -466,6 +466,8 @@ struct cxl_dc_region_info {
>  	u64 blk_size;
>  	u32 dsmad_handle;
>  	u8 flags;
> +	bool shareable;
> +	bool read_only;
>  	u8 name[CXL_DC_REGION_STRLEN];
>  };
>  
> @@ -533,6 +535,7 @@ struct cxl_memdev_state {
>  
>  	u8 nr_dc_region;
>  	struct cxl_dc_region_info dc_region[CXL_MAX_DC_REGION];
> +	struct cxl_dpa_perf dc_perf[CXL_MAX_DC_REGION];
>  
>  	struct cxl_event_state event;
>  	struct cxl_poison_state poison;
> diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
> index 199afc2cd122..387fc821703a 100644
> --- a/include/acpi/actbl1.h
> +++ b/include/acpi/actbl1.h
> @@ -403,6 +403,8 @@ struct acpi_cdat_dsmas {
>  /* Flags for subtable above */
>  
>  #define ACPI_CDAT_DSMAS_NON_VOLATILE        (1 << 2)
> +#define ACPI_CDAT_DSMAS_SHAREABLE           (1 << 3)
> +#define ACPI_CDAT_DSMAS_READ_ONLY           (1 << 6)
>  
>  /* Subtable 1: Device scoped Latency and Bandwidth Information Structure (DSLBIS) */
>  
> 
> -- 
> 2.46.0
>
Jonathan Cameron Oct. 10, 2024, 12:51 p.m. UTC | #3
On Mon, 07 Oct 2024 18:16:18 -0500
Ira Weiny <ira.weiny@intel.com> wrote:

> Additional DCD region (partition) information is contained in the DSMAS
> CDAT tables, including performance, read only, and shareable attributes.
> 
> Match DCD partitions with DSMAS tables and store the meta data.
> 
> To: Robert Moore <robert.moore@intel.com>
> To: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> To: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> Cc: acpica-devel@lists.linux.dev
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
One trivial comment from me.
As Rafael has raised, the ACPICA dependency in here is
going to be the blocker :(

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

> +static void update_dcd_perf(struct cxl_dev_state *cxlds,
> +			    struct dsmas_entry *dent)
> +{
> +	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
> +	struct device *dev = cxlds->dev;
> +
> +	for (int i = 0; i < mds->nr_dc_region; i++) {
> +		/* CXL defines a u32 handle while cdat defines u8, ignore upper bits */

CDAT

> +		u8 dc_handle = mds->dc_region[i].dsmad_handle & 0xff;
> +
> +		if (resource_size(&cxlds->dc_res[i])) {
> +			struct range dc_range = {
> +				.start = cxlds->dc_res[i].start,
> +				.end = cxlds->dc_res[i].end,
> +			};
> +
> +			if (range_contains(&dent->dpa_range, &dc_range)) {
> +				if (dent->handle != dc_handle)
> +					dev_warn(dev, "DC Region/DSMAS mis-matched handle/range; region %pra (%u); dsmas %pra (%u)\n"
> +						      "   setting DC region attributes regardless\n",
> +						&dent->dpa_range, dent->handle,
> +						&dc_range, dc_handle);
> +
> +				mds->dc_region[i].shareable = dent->shareable;
> +				mds->dc_region[i].read_only = dent->read_only;
> +				update_perf_entry(dev, dent, &mds->dc_perf[i]);
> +			}
> +		}
> +	}
> +}
Ira Weiny Oct. 11, 2024, 8:38 p.m. UTC | #4
Rafael J. Wysocki wrote:
> On Tue, Oct 8, 2024 at 1:17 AM Ira Weiny <ira.weiny@intel.com> wrote:
> >

[snip]

> > diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
> > index 199afc2cd122..387fc821703a 100644
> > --- a/include/acpi/actbl1.h
> > +++ b/include/acpi/actbl1.h
> > @@ -403,6 +403,8 @@ struct acpi_cdat_dsmas {
> >  /* Flags for subtable above */
> >
> >  #define ACPI_CDAT_DSMAS_NON_VOLATILE        (1 << 2)
> > +#define ACPI_CDAT_DSMAS_SHAREABLE           (1 << 3)
> > +#define ACPI_CDAT_DSMAS_READ_ONLY           (1 << 6)
> >
> >  /* Subtable 1: Device scoped Latency and Bandwidth Information Structure (DSLBIS) */
> >
> 
> Is there an upstream ACPICA commit for this?

There is a PR for it now.

	https://github.com/acpica/acpica/pull/976

Do I need to reference that in this patch?  Or wait for it to be merged
and drop this hunk?

Ira
Ira Weiny Oct. 14, 2024, 1:16 a.m. UTC | #5
Fan Ni wrote:
> On Mon, Oct 07, 2024 at 06:16:18PM -0500, Ira Weiny wrote:
> > Additional DCD region (partition) information is contained in the DSMAS
> > CDAT tables, including performance, read only, and shareable attributes.
> > 
> > Match DCD partitions with DSMAS tables and store the meta data.
> > 
> > To: Robert Moore <robert.moore@intel.com>
> > To: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > To: Len Brown <lenb@kernel.org>
> > Cc: linux-acpi@vger.kernel.org
> > Cc: acpica-devel@lists.linux.dev
> > Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> > 
> 
> One minor comment inline.
> 
> > ---
> > Changes:
> > [iweiny: new patch]
> > [iweiny: Gather shareable/read-only flags for later use]
> > ---
> >  drivers/cxl/core/cdat.c | 38 ++++++++++++++++++++++++++++++++++++++
> >  drivers/cxl/core/mbox.c |  2 ++
> >  drivers/cxl/cxlmem.h    |  3 +++
> >  include/acpi/actbl1.h   |  2 ++
> >  4 files changed, 45 insertions(+)
> > 
> > diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
> > index bd50bb655741..9b2f717a16e5 100644
> > --- a/drivers/cxl/core/cdat.c
> > +++ b/drivers/cxl/core/cdat.c
> > @@ -17,6 +17,8 @@ struct dsmas_entry {
> >  	struct access_coordinate cdat_coord[ACCESS_COORDINATE_MAX];
> >  	int entries;
> >  	int qos_class;
> > +	bool shareable;
> > +	bool read_only;
> >  };
> >  
> >  static u32 cdat_normalize(u16 entry, u64 base, u8 type)
> > @@ -74,6 +76,8 @@ static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg,
> >  		return -ENOMEM;
> >  
> >  	dent->handle = dsmas->dsmad_handle;
> > +	dent->shareable = dsmas->flags & ACPI_CDAT_DSMAS_SHAREABLE;
> > +	dent->read_only = dsmas->flags & ACPI_CDAT_DSMAS_READ_ONLY;
> >  	dent->dpa_range.start = le64_to_cpu((__force __le64)dsmas->dpa_base_address);
> >  	dent->dpa_range.end = le64_to_cpu((__force __le64)dsmas->dpa_base_address) +
> >  			      le64_to_cpu((__force __le64)dsmas->dpa_length) - 1;
> > @@ -255,6 +259,38 @@ static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
> >  		dent->coord[ACCESS_COORDINATE_CPU].write_latency);
> >  }
> >  
> > +
> Unwanted blank line.

Fixed. Thanks.
Ira
Wysocki, Rafael J Oct. 14, 2024, 8:52 p.m. UTC | #6
On 10/11/2024 10:38 PM, Ira Weiny wrote:
> Rafael J. Wysocki wrote:
>> On Tue, Oct 8, 2024 at 1:17 AM Ira Weiny <ira.weiny@intel.com> wrote:
> [snip]
>
>>> diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
>>> index 199afc2cd122..387fc821703a 100644
>>> --- a/include/acpi/actbl1.h
>>> +++ b/include/acpi/actbl1.h
>>> @@ -403,6 +403,8 @@ struct acpi_cdat_dsmas {
>>>   /* Flags for subtable above */
>>>
>>>   #define ACPI_CDAT_DSMAS_NON_VOLATILE        (1 << 2)
>>> +#define ACPI_CDAT_DSMAS_SHAREABLE           (1 << 3)
>>> +#define ACPI_CDAT_DSMAS_READ_ONLY           (1 << 6)
>>>
>>>   /* Subtable 1: Device scoped Latency and Bandwidth Information Structure (DSLBIS) */
>>>
>> Is there an upstream ACPICA commit for this?
> There is a PR for it now.
>
> 	https://github.com/acpica/acpica/pull/976
>
> Do I need to reference that in this patch?  Or wait for it to be merged
> and drop this hunk?

Wait for it to be merged first.  Then either drop this hunk and wait for 
an ACPICA release (that may not happen soon, though), or send a Linux 
patch corresponding to it with a Link tag pointing to the above.

Thanks!
diff mbox series

Patch

diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
index bd50bb655741..9b2f717a16e5 100644
--- a/drivers/cxl/core/cdat.c
+++ b/drivers/cxl/core/cdat.c
@@ -17,6 +17,8 @@  struct dsmas_entry {
 	struct access_coordinate cdat_coord[ACCESS_COORDINATE_MAX];
 	int entries;
 	int qos_class;
+	bool shareable;
+	bool read_only;
 };
 
 static u32 cdat_normalize(u16 entry, u64 base, u8 type)
@@ -74,6 +76,8 @@  static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg,
 		return -ENOMEM;
 
 	dent->handle = dsmas->dsmad_handle;
+	dent->shareable = dsmas->flags & ACPI_CDAT_DSMAS_SHAREABLE;
+	dent->read_only = dsmas->flags & ACPI_CDAT_DSMAS_READ_ONLY;
 	dent->dpa_range.start = le64_to_cpu((__force __le64)dsmas->dpa_base_address);
 	dent->dpa_range.end = le64_to_cpu((__force __le64)dsmas->dpa_base_address) +
 			      le64_to_cpu((__force __le64)dsmas->dpa_length) - 1;
@@ -255,6 +259,38 @@  static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
 		dent->coord[ACCESS_COORDINATE_CPU].write_latency);
 }
 
+
+static void update_dcd_perf(struct cxl_dev_state *cxlds,
+			    struct dsmas_entry *dent)
+{
+	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
+	struct device *dev = cxlds->dev;
+
+	for (int i = 0; i < mds->nr_dc_region; i++) {
+		/* CXL defines a u32 handle while cdat defines u8, ignore upper bits */
+		u8 dc_handle = mds->dc_region[i].dsmad_handle & 0xff;
+
+		if (resource_size(&cxlds->dc_res[i])) {
+			struct range dc_range = {
+				.start = cxlds->dc_res[i].start,
+				.end = cxlds->dc_res[i].end,
+			};
+
+			if (range_contains(&dent->dpa_range, &dc_range)) {
+				if (dent->handle != dc_handle)
+					dev_warn(dev, "DC Region/DSMAS mis-matched handle/range; region %pra (%u); dsmas %pra (%u)\n"
+						      "   setting DC region attributes regardless\n",
+						&dent->dpa_range, dent->handle,
+						&dc_range, dc_handle);
+
+				mds->dc_region[i].shareable = dent->shareable;
+				mds->dc_region[i].read_only = dent->read_only;
+				update_perf_entry(dev, dent, &mds->dc_perf[i]);
+			}
+		}
+	}
+}
+
 static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
 				     struct xarray *dsmas_xa)
 {
@@ -278,6 +314,8 @@  static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
 		else if (resource_size(&cxlds->pmem_res) &&
 			 range_contains(&pmem_range, &dent->dpa_range))
 			update_perf_entry(dev, dent, &mds->pmem_perf);
+		else if (cxl_dcd_supported(mds))
+			update_dcd_perf(cxlds, dent);
 		else
 			dev_dbg(dev, "no partition for dsmas dpa: %pra\n",
 				&dent->dpa_range);
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 4b51ddd1ff94..3ba465823564 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -1649,6 +1649,8 @@  struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
 	mds->cxlds.type = CXL_DEVTYPE_CLASSMEM;
 	mds->ram_perf.qos_class = CXL_QOS_CLASS_INVALID;
 	mds->pmem_perf.qos_class = CXL_QOS_CLASS_INVALID;
+	for (int i = 0; i < CXL_MAX_DC_REGION; i++)
+		mds->dc_perf[i].qos_class = CXL_QOS_CLASS_INVALID;
 
 	return mds;
 }
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index 0690b917b1e0..c3b889a586d8 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -466,6 +466,8 @@  struct cxl_dc_region_info {
 	u64 blk_size;
 	u32 dsmad_handle;
 	u8 flags;
+	bool shareable;
+	bool read_only;
 	u8 name[CXL_DC_REGION_STRLEN];
 };
 
@@ -533,6 +535,7 @@  struct cxl_memdev_state {
 
 	u8 nr_dc_region;
 	struct cxl_dc_region_info dc_region[CXL_MAX_DC_REGION];
+	struct cxl_dpa_perf dc_perf[CXL_MAX_DC_REGION];
 
 	struct cxl_event_state event;
 	struct cxl_poison_state poison;
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 199afc2cd122..387fc821703a 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -403,6 +403,8 @@  struct acpi_cdat_dsmas {
 /* Flags for subtable above */
 
 #define ACPI_CDAT_DSMAS_NON_VOLATILE        (1 << 2)
+#define ACPI_CDAT_DSMAS_SHAREABLE           (1 << 3)
+#define ACPI_CDAT_DSMAS_READ_ONLY           (1 << 6)
 
 /* Subtable 1: Device scoped Latency and Bandwidth Information Structure (DSLBIS) */