From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
To: Vinayak Holikatti <vinayak.kh@samsung.com>
Cc: <qemu-devel@nongnu.org>, <gost.dev@samsung.com>,
<linux-cxl@vger.kernel.org>, <nifan.cxl@gmail.com>,
<dave@stgolabs.net>, <vishak.g@samsung.com>,
<krish.reddy@samsung.com>, <a.manzanares@samsung.com>,
<alok.rathore@samsung.com>
Subject: Re: [PATCH v3 3/3] hw/cxl/cxl-mailbox-utils: Add support for Media operations Sanitize and Write Zeros commands cxl r3.2(8.2.10.9.5.3)
Date: Thu, 20 Feb 2025 15:10:09 +0000 [thread overview]
Message-ID: <20250220151009.000009e7@huawei.com> (raw)
In-Reply-To: <20250220052724.1256642-4-vinayak.kh@samsung.com>
On Thu, 20 Feb 2025 10:57:24 +0530
Vinayak Holikatti <vinayak.kh@samsung.com> wrote:
> CXL spec 3.2 section 8.2.10.9.5.3 describes media operations commands.
> CXL devices supports media operations Sanitize and Write zero command.
>
> Signed-off-by: Vinayak Holikatti <vinayak.kh@samsung.com>
Another one where I made some minor tweaks whilst applying. Let me know if I
messed up! Comments on why folow.
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 4aa695cfa9..a48a551bfc 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -1796,7 +1796,7 @@ static int sanitize_range(CXLType3Dev *ct3d, uint64_t dpa_addr, size_t length,
uint64_t vmr_size, pmr_size;
AddressSpace *as = NULL;
- MemTxAttrs mem_attrs = {0};
+ MemTxAttrs mem_attrs = {};
vmr_size = get_vmr_size(ct3d, NULL);
pmr_size = get_pmr_size(ct3d, NULL);
@@ -1820,7 +1820,8 @@ static void __do_sanitize(CXLType3Dev *ct3d)
{
struct CXLSanitizeInfo *san_info = ct3d->media_op_sanitize;
int dpa_range_count = san_info->dpa_range_count;
- int rc = 0, i;
+ int rc = 0;
+ int i;
for (i = 0; i < dpa_range_count; i++) {
rc = sanitize_range(ct3d, san_info->dpa_range_list[i].starting_dpa,
@@ -1933,21 +1934,19 @@ static CXLRetCode media_operations_sanitize(CXLType3Dev *ct3d,
uint8_t media_operation_subclass;
uint8_t rsvd[2];
uint32_t dpa_range_count;
- struct {
- uint64_t starting_dpa;
- uint64_t length;
- } dpa_range_list[];
+ struct dpa_range_list_entry dpa_range_list[];
} QEMU_PACKED *media_op_in_sanitize_pl = (void *)payload_in;
uint32_t dpa_range_count = media_op_in_sanitize_pl->dpa_range_count;
uint64_t total_mem = 0;
+ size_t dpa_range_list_size;
int secs = 0, i;
if (dpa_range_count == 0) {
return CXL_MBOX_SUCCESS;
}
- if (len_in < (sizeof(*media_op_in_sanitize_pl) +
- (dpa_range_count * sizeof(struct dpa_range_list_entry)))) {
+ dpa_range_list_size = dpa_range_count * sizeof(struct dpa_range_list_entry);
+ if (len_in < (sizeof(*media_op_in_sanitize_pl) + dpa_range_list_size)) {
return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
}
@@ -1955,24 +1954,21 @@ static CXLRetCode media_operations_sanitize(CXLType3Dev *ct3d,
uint64_t start_dpa =
media_op_in_sanitize_pl->dpa_range_list[i].starting_dpa;
uint64_t length = media_op_in_sanitize_pl->dpa_range_list[i].length;
+
if (validate_dpa_addr(ct3d, start_dpa, length)) {
return CXL_MBOX_INVALID_INPUT;
}
- total_mem += media_op_in_sanitize_pl->dpa_range_list[i].length;
+ total_mem += length;
}
ct3d->media_op_sanitize = g_malloc0(sizeof(struct CXLSanitizeInfo) +
- (dpa_range_count *
- sizeof(struct dpa_range_list_entry)));
-
- if (ct3d->media_op_sanitize) {
- ct3d->media_op_sanitize->dpa_range_count = dpa_range_count;
- ct3d->media_op_sanitize->fill_value = fill_value;
- memcpy(ct3d->media_op_sanitize->dpa_range_list,
- media_op_in_sanitize_pl->dpa_range_list,
- (dpa_range_count *
- sizeof(struct dpa_range_list_entry)));
- secs = get_sanitize_duration(total_mem >> 20);
- }
+ dpa_range_list_size);
+
+ ct3d->media_op_sanitize->dpa_range_count = dpa_range_count;
+ ct3d->media_op_sanitize->fill_value = fill_value;
+ memcpy(ct3d->media_op_sanitize->dpa_range_list,
+ media_op_in_sanitize_pl->dpa_range_list,
+ dpa_range_list_size);
+ secs = get_sanitize_duration(total_mem >> 20);
/* EBUSY other bg cmds as of now */
cci->bg.runtime = secs * 1000UL;
> ---
> hw/cxl/cxl-mailbox-utils.c | 210 +++++++++++++++++++++++++++++++++++-
> include/hw/cxl/cxl_device.h | 4 +
> 2 files changed, 213 insertions(+), 1 deletion(-)
>
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index 2428d85fef..7b4e4daeb2 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -1731,6 +1731,130 @@ static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd,
> return CXL_MBOX_BG_STARTED;
> }
>
> +struct dpa_range_list_entry {
> + uint64_t starting_dpa;
> + uint64_t length;
> +} QEMU_PACKED;
> +
> +struct CXLSanitizeInfo {
> + uint32_t dpa_range_count;
> + uint8_t fill_value;
> + struct dpa_range_list_entry dpa_range_list[];
> +} QEMU_PACKED;
> +
> +static uint64_t get_vmr_size(CXLType3Dev *ct3d, MemoryRegion **vmr)
> +{
> + MemoryRegion *mr;
> + if (ct3d->hostvmem) {
> + mr = host_memory_backend_get_memory(ct3d->hostvmem);
> + if (vmr) {
> + *vmr = mr;
> + }
> + return memory_region_size(mr);
> + }
> + return 0;
> +}
> +
> +static uint64_t get_pmr_size(CXLType3Dev *ct3d, MemoryRegion **pmr)
> +{
> + MemoryRegion *mr;
> + if (ct3d->hostpmem) {
> + mr = host_memory_backend_get_memory(ct3d->hostpmem);
> + if (pmr) {
> + *pmr = mr;
> + }
> + return memory_region_size(mr);
> + }
> + return 0;
> +}
> +
> +static uint64_t get_dc_size(CXLType3Dev *ct3d, MemoryRegion **dc_mr)
> +{
> + MemoryRegion *mr;
> + if (ct3d->dc.host_dc) {
> + mr = host_memory_backend_get_memory(ct3d->dc.host_dc);
> + if (dc_mr) {
> + *dc_mr = mr;
> + }
> + return memory_region_size(mr);
> + }
> + return 0;
> +}
> +
> +static int validate_dpa_addr(CXLType3Dev *ct3d, uint64_t dpa_addr,
> + size_t length)
> +{
> + uint64_t vmr_size, pmr_size, dc_size;
> +
> + if ((dpa_addr % CXL_CACHE_LINE_SIZE) ||
> + (length % CXL_CACHE_LINE_SIZE) ||
extra spce before the ||
> + (length <= 0)) {
> + return -EINVAL;
> + }
> +
> + vmr_size = get_vmr_size(ct3d, NULL);
> + pmr_size = get_pmr_size(ct3d, NULL);
> + dc_size = get_dc_size(ct3d, NULL);
> +
> + if (dpa_addr + length > vmr_size + pmr_size + dc_size) {
> + return -EINVAL;
> + }
> +
> + if (dpa_addr > vmr_size + pmr_size) {
> + if (!ct3_test_region_block_backed(ct3d, dpa_addr, length)) {
> + return -ENODEV;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int sanitize_range(CXLType3Dev *ct3d, uint64_t dpa_addr, size_t length,
> + uint8_t fill_value)
> +{
> +
> + uint64_t vmr_size, pmr_size;
> + AddressSpace *as = NULL;
> + MemTxAttrs mem_attrs = {0};
No need for the 0. {} is same thing.
> +
> + vmr_size = get_vmr_size(ct3d, NULL);
> + pmr_size = get_pmr_size(ct3d, NULL);
> +
> + if (dpa_addr < vmr_size) {
> + as = &ct3d->hostvmem_as;
> + } else if (dpa_addr < vmr_size + pmr_size) {
> + as = &ct3d->hostpmem_as;
> + } else {
> + if (!ct3_test_region_block_backed(ct3d, dpa_addr, length)) {
> + return -ENODEV;
> + }
> + as = &ct3d->dc.host_dc_as;
> + }
> +
> + return address_space_set(as, dpa_addr, fill_value, length, mem_attrs);
> +}
> +
> +/* Perform the actual device zeroing */
> +static void __do_sanitize(CXLType3Dev *ct3d)
> +{
> + struct CXLSanitizeInfo *san_info = ct3d->media_op_sanitize;
> + int dpa_range_count = san_info->dpa_range_count;
> + int rc = 0, i;
I'll spit this. Generally mixing assignment and non assignment declarations
can be a small readabilty issue.
> +
> + for (i = 0; i < dpa_range_count; i++) {
> + rc = sanitize_range(ct3d, san_info->dpa_range_list[i].starting_dpa,
> + san_info->dpa_range_list[i].length,
> + san_info->fill_value);
> + if (rc) {
> + goto exit;
> + }
> + }
> +exit:
> + g_free(ct3d->media_op_sanitize);
> + ct3d->media_op_sanitize = NULL;
> + return;
> +}
> +
> enum {
> MEDIA_OP_CLASS_GENERAL = 0x0,
> #define MEDIA_OP_GEN_SUBC_DISCOVERY 0x0
> @@ -1823,6 +1947,70 @@ static CXLRetCode media_operations_discovery(uint8_t *payload_in,
> return CXL_MBOX_SUCCESS;
> }
>
> +static CXLRetCode media_operations_sanitize(CXLType3Dev *ct3d,
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + uint8_t fill_value,
> + CXLCCI *cci)
> +{
> + struct media_operations_sanitize {
> + uint8_t media_operation_class;
> + uint8_t media_operation_subclass;
> + uint8_t rsvd[2];
> + uint32_t dpa_range_count;
> + struct {
> + uint64_t starting_dpa;
> + uint64_t length;
> + } dpa_range_list[];
struct dpa_range_list_entry dpa_range_list[] which makes the
> + } QEMU_PACKED *media_op_in_sanitize_pl = (void *)payload_in;
> + uint32_t dpa_range_count = media_op_in_sanitize_pl->dpa_range_count;
> + uint64_t total_mem = 0;
> + int secs = 0, i;
As above.
> +
> + if (dpa_range_count == 0) {
> + return CXL_MBOX_SUCCESS;
> + }
> +
> + if (len_in < (sizeof(*media_op_in_sanitize_pl) +
> + (dpa_range_count * sizeof(struct dpa_range_list_entry)))) {
Lots of use is made of this size of the dpa_range list.
Deserves a local variable.
> + return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
> + }
> +
> + for (i = 0; i < dpa_range_count; i++) {
> + uint64_t start_dpa =
> + media_op_in_sanitize_pl->dpa_range_list[i].starting_dpa;
> + uint64_t length = media_op_in_sanitize_pl->dpa_range_list[i].length;
> + if (validate_dpa_addr(ct3d, start_dpa, length)) {
> + return CXL_MBOX_INVALID_INPUT;
> + }
> + total_mem += media_op_in_sanitize_pl->dpa_range_list[i].length;
totalmem += length.
> + }
> + ct3d->media_op_sanitize = g_malloc0(sizeof(struct CXLSanitizeInfo) +
> + (dpa_range_count *
> + sizeof(struct dpa_range_list_entry)));
> +
> + if (ct3d->media_op_sanitize) {
This can't fail. g_malloc0 failing kills qemu anyway (makes memory
handling simple ;)
> + ct3d->media_op_sanitize->dpa_range_count = dpa_range_count;
> + ct3d->media_op_sanitize->fill_value = fill_value;
> + memcpy(ct3d->media_op_sanitize->dpa_range_list,
> + media_op_in_sanitize_pl->dpa_range_list,
Align after the (
> + (dpa_range_count *
> + sizeof(struct dpa_range_list_entry)));
> + secs = get_sanitize_duration(total_mem >> 20);
> + }
> +
> + /* EBUSY other bg cmds as of now */
> + cci->bg.runtime = secs * 1000UL;
> + *len_out = 0;
> + /*
> + * media op sanitize is targeted so no need to disable media or
> + * clear event logs
> + */
> + return CXL_MBOX_BG_STARTED;
> +}
> +
> static CXLRetCode cmd_media_operations(const struct cxl_cmd *cmd,
> uint8_t *payload_in,
> size_t len_in,
> @@ -1836,6 +2024,7 @@ static CXLRetCode cmd_media_operations(const struct cxl_cmd *cmd,
> uint8_t rsvd[2];
> uint32_t dpa_range_count;
> } QEMU_PACKED *media_op_in_common_pl = (void *)payload_in;
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> uint8_t media_op_cl = 0;
> uint8_t media_op_subclass = 0;
>
> @@ -1853,7 +2042,20 @@ static CXLRetCode cmd_media_operations(const struct cxl_cmd *cmd,
> }
>
> return media_operations_discovery(payload_in, len_in, payload_out,
> - len_out);
> + len_out);
> + case MEDIA_OP_CLASS_SANITIZE:
> + switch (media_op_subclass) {
> + case MEDIA_OP_SAN_SUBC_SANITIZE:
> + return media_operations_sanitize(ct3d, payload_in, len_in,
> + payload_out, len_out, 0xF,
> + cci);
> + case MEDIA_OP_SAN_SUBC_ZERO:
> + return media_operations_sanitize(ct3d, payload_in, len_in,
> + payload_out, len_out, 0,
> + cci);
> + default:
> + return CXL_MBOX_UNSUPPORTED;
> + }
> default:
> return CXL_MBOX_UNSUPPORTED;
> }
> @@ -3170,6 +3372,12 @@ static void bg_timercb(void *opaque)
> cxl_dev_enable_media(&ct3d->cxl_dstate);
> }
> break;
> + case 0x4402: /* Media Operations sanitize */
> + {
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> + __do_sanitize(ct3d);
> + }
> + break;
> case 0x4304: /* scan media */
> {
> CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index a64739be25..3c5711249b 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -581,6 +581,8 @@ typedef struct CXLSetFeatureInfo {
> size_t data_size;
> } CXLSetFeatureInfo;
>
> +struct CXLSanitizeInfo;
> +
> struct CXLType3Dev {
> /* Private */
> PCIDevice parent_obj;
> @@ -651,6 +653,8 @@ struct CXLType3Dev {
> uint8_t num_regions; /* 0-8 regions */
> CXLDCRegion regions[DCD_MAX_NUM_REGION];
> } dc;
> +
> + struct CXLSanitizeInfo *media_op_sanitize;
> };
>
> #define TYPE_CXL_TYPE3 "cxl-type3"
WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron via <qemu-devel@nongnu.org>
To: Vinayak Holikatti <vinayak.kh@samsung.com>
Cc: <qemu-devel@nongnu.org>, <gost.dev@samsung.com>,
<linux-cxl@vger.kernel.org>, <nifan.cxl@gmail.com>,
<dave@stgolabs.net>, <vishak.g@samsung.com>,
<krish.reddy@samsung.com>, <a.manzanares@samsung.com>,
<alok.rathore@samsung.com>
Subject: Re: [PATCH v3 3/3] hw/cxl/cxl-mailbox-utils: Add support for Media operations Sanitize and Write Zeros commands cxl r3.2(8.2.10.9.5.3)
Date: Thu, 20 Feb 2025 15:10:09 +0000 [thread overview]
Message-ID: <20250220151009.000009e7@huawei.com> (raw)
In-Reply-To: <20250220052724.1256642-4-vinayak.kh@samsung.com>
On Thu, 20 Feb 2025 10:57:24 +0530
Vinayak Holikatti <vinayak.kh@samsung.com> wrote:
> CXL spec 3.2 section 8.2.10.9.5.3 describes media operations commands.
> CXL devices supports media operations Sanitize and Write zero command.
>
> Signed-off-by: Vinayak Holikatti <vinayak.kh@samsung.com>
Another one where I made some minor tweaks whilst applying. Let me know if I
messed up! Comments on why folow.
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 4aa695cfa9..a48a551bfc 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -1796,7 +1796,7 @@ static int sanitize_range(CXLType3Dev *ct3d, uint64_t dpa_addr, size_t length,
uint64_t vmr_size, pmr_size;
AddressSpace *as = NULL;
- MemTxAttrs mem_attrs = {0};
+ MemTxAttrs mem_attrs = {};
vmr_size = get_vmr_size(ct3d, NULL);
pmr_size = get_pmr_size(ct3d, NULL);
@@ -1820,7 +1820,8 @@ static void __do_sanitize(CXLType3Dev *ct3d)
{
struct CXLSanitizeInfo *san_info = ct3d->media_op_sanitize;
int dpa_range_count = san_info->dpa_range_count;
- int rc = 0, i;
+ int rc = 0;
+ int i;
for (i = 0; i < dpa_range_count; i++) {
rc = sanitize_range(ct3d, san_info->dpa_range_list[i].starting_dpa,
@@ -1933,21 +1934,19 @@ static CXLRetCode media_operations_sanitize(CXLType3Dev *ct3d,
uint8_t media_operation_subclass;
uint8_t rsvd[2];
uint32_t dpa_range_count;
- struct {
- uint64_t starting_dpa;
- uint64_t length;
- } dpa_range_list[];
+ struct dpa_range_list_entry dpa_range_list[];
} QEMU_PACKED *media_op_in_sanitize_pl = (void *)payload_in;
uint32_t dpa_range_count = media_op_in_sanitize_pl->dpa_range_count;
uint64_t total_mem = 0;
+ size_t dpa_range_list_size;
int secs = 0, i;
if (dpa_range_count == 0) {
return CXL_MBOX_SUCCESS;
}
- if (len_in < (sizeof(*media_op_in_sanitize_pl) +
- (dpa_range_count * sizeof(struct dpa_range_list_entry)))) {
+ dpa_range_list_size = dpa_range_count * sizeof(struct dpa_range_list_entry);
+ if (len_in < (sizeof(*media_op_in_sanitize_pl) + dpa_range_list_size)) {
return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
}
@@ -1955,24 +1954,21 @@ static CXLRetCode media_operations_sanitize(CXLType3Dev *ct3d,
uint64_t start_dpa =
media_op_in_sanitize_pl->dpa_range_list[i].starting_dpa;
uint64_t length = media_op_in_sanitize_pl->dpa_range_list[i].length;
+
if (validate_dpa_addr(ct3d, start_dpa, length)) {
return CXL_MBOX_INVALID_INPUT;
}
- total_mem += media_op_in_sanitize_pl->dpa_range_list[i].length;
+ total_mem += length;
}
ct3d->media_op_sanitize = g_malloc0(sizeof(struct CXLSanitizeInfo) +
- (dpa_range_count *
- sizeof(struct dpa_range_list_entry)));
-
- if (ct3d->media_op_sanitize) {
- ct3d->media_op_sanitize->dpa_range_count = dpa_range_count;
- ct3d->media_op_sanitize->fill_value = fill_value;
- memcpy(ct3d->media_op_sanitize->dpa_range_list,
- media_op_in_sanitize_pl->dpa_range_list,
- (dpa_range_count *
- sizeof(struct dpa_range_list_entry)));
- secs = get_sanitize_duration(total_mem >> 20);
- }
+ dpa_range_list_size);
+
+ ct3d->media_op_sanitize->dpa_range_count = dpa_range_count;
+ ct3d->media_op_sanitize->fill_value = fill_value;
+ memcpy(ct3d->media_op_sanitize->dpa_range_list,
+ media_op_in_sanitize_pl->dpa_range_list,
+ dpa_range_list_size);
+ secs = get_sanitize_duration(total_mem >> 20);
/* EBUSY other bg cmds as of now */
cci->bg.runtime = secs * 1000UL;
> ---
> hw/cxl/cxl-mailbox-utils.c | 210 +++++++++++++++++++++++++++++++++++-
> include/hw/cxl/cxl_device.h | 4 +
> 2 files changed, 213 insertions(+), 1 deletion(-)
>
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index 2428d85fef..7b4e4daeb2 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -1731,6 +1731,130 @@ static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd,
> return CXL_MBOX_BG_STARTED;
> }
>
> +struct dpa_range_list_entry {
> + uint64_t starting_dpa;
> + uint64_t length;
> +} QEMU_PACKED;
> +
> +struct CXLSanitizeInfo {
> + uint32_t dpa_range_count;
> + uint8_t fill_value;
> + struct dpa_range_list_entry dpa_range_list[];
> +} QEMU_PACKED;
> +
> +static uint64_t get_vmr_size(CXLType3Dev *ct3d, MemoryRegion **vmr)
> +{
> + MemoryRegion *mr;
> + if (ct3d->hostvmem) {
> + mr = host_memory_backend_get_memory(ct3d->hostvmem);
> + if (vmr) {
> + *vmr = mr;
> + }
> + return memory_region_size(mr);
> + }
> + return 0;
> +}
> +
> +static uint64_t get_pmr_size(CXLType3Dev *ct3d, MemoryRegion **pmr)
> +{
> + MemoryRegion *mr;
> + if (ct3d->hostpmem) {
> + mr = host_memory_backend_get_memory(ct3d->hostpmem);
> + if (pmr) {
> + *pmr = mr;
> + }
> + return memory_region_size(mr);
> + }
> + return 0;
> +}
> +
> +static uint64_t get_dc_size(CXLType3Dev *ct3d, MemoryRegion **dc_mr)
> +{
> + MemoryRegion *mr;
> + if (ct3d->dc.host_dc) {
> + mr = host_memory_backend_get_memory(ct3d->dc.host_dc);
> + if (dc_mr) {
> + *dc_mr = mr;
> + }
> + return memory_region_size(mr);
> + }
> + return 0;
> +}
> +
> +static int validate_dpa_addr(CXLType3Dev *ct3d, uint64_t dpa_addr,
> + size_t length)
> +{
> + uint64_t vmr_size, pmr_size, dc_size;
> +
> + if ((dpa_addr % CXL_CACHE_LINE_SIZE) ||
> + (length % CXL_CACHE_LINE_SIZE) ||
extra spce before the ||
> + (length <= 0)) {
> + return -EINVAL;
> + }
> +
> + vmr_size = get_vmr_size(ct3d, NULL);
> + pmr_size = get_pmr_size(ct3d, NULL);
> + dc_size = get_dc_size(ct3d, NULL);
> +
> + if (dpa_addr + length > vmr_size + pmr_size + dc_size) {
> + return -EINVAL;
> + }
> +
> + if (dpa_addr > vmr_size + pmr_size) {
> + if (!ct3_test_region_block_backed(ct3d, dpa_addr, length)) {
> + return -ENODEV;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int sanitize_range(CXLType3Dev *ct3d, uint64_t dpa_addr, size_t length,
> + uint8_t fill_value)
> +{
> +
> + uint64_t vmr_size, pmr_size;
> + AddressSpace *as = NULL;
> + MemTxAttrs mem_attrs = {0};
No need for the 0. {} is same thing.
> +
> + vmr_size = get_vmr_size(ct3d, NULL);
> + pmr_size = get_pmr_size(ct3d, NULL);
> +
> + if (dpa_addr < vmr_size) {
> + as = &ct3d->hostvmem_as;
> + } else if (dpa_addr < vmr_size + pmr_size) {
> + as = &ct3d->hostpmem_as;
> + } else {
> + if (!ct3_test_region_block_backed(ct3d, dpa_addr, length)) {
> + return -ENODEV;
> + }
> + as = &ct3d->dc.host_dc_as;
> + }
> +
> + return address_space_set(as, dpa_addr, fill_value, length, mem_attrs);
> +}
> +
> +/* Perform the actual device zeroing */
> +static void __do_sanitize(CXLType3Dev *ct3d)
> +{
> + struct CXLSanitizeInfo *san_info = ct3d->media_op_sanitize;
> + int dpa_range_count = san_info->dpa_range_count;
> + int rc = 0, i;
I'll spit this. Generally mixing assignment and non assignment declarations
can be a small readabilty issue.
> +
> + for (i = 0; i < dpa_range_count; i++) {
> + rc = sanitize_range(ct3d, san_info->dpa_range_list[i].starting_dpa,
> + san_info->dpa_range_list[i].length,
> + san_info->fill_value);
> + if (rc) {
> + goto exit;
> + }
> + }
> +exit:
> + g_free(ct3d->media_op_sanitize);
> + ct3d->media_op_sanitize = NULL;
> + return;
> +}
> +
> enum {
> MEDIA_OP_CLASS_GENERAL = 0x0,
> #define MEDIA_OP_GEN_SUBC_DISCOVERY 0x0
> @@ -1823,6 +1947,70 @@ static CXLRetCode media_operations_discovery(uint8_t *payload_in,
> return CXL_MBOX_SUCCESS;
> }
>
> +static CXLRetCode media_operations_sanitize(CXLType3Dev *ct3d,
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + uint8_t fill_value,
> + CXLCCI *cci)
> +{
> + struct media_operations_sanitize {
> + uint8_t media_operation_class;
> + uint8_t media_operation_subclass;
> + uint8_t rsvd[2];
> + uint32_t dpa_range_count;
> + struct {
> + uint64_t starting_dpa;
> + uint64_t length;
> + } dpa_range_list[];
struct dpa_range_list_entry dpa_range_list[] which makes the
> + } QEMU_PACKED *media_op_in_sanitize_pl = (void *)payload_in;
> + uint32_t dpa_range_count = media_op_in_sanitize_pl->dpa_range_count;
> + uint64_t total_mem = 0;
> + int secs = 0, i;
As above.
> +
> + if (dpa_range_count == 0) {
> + return CXL_MBOX_SUCCESS;
> + }
> +
> + if (len_in < (sizeof(*media_op_in_sanitize_pl) +
> + (dpa_range_count * sizeof(struct dpa_range_list_entry)))) {
Lots of use is made of this size of the dpa_range list.
Deserves a local variable.
> + return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
> + }
> +
> + for (i = 0; i < dpa_range_count; i++) {
> + uint64_t start_dpa =
> + media_op_in_sanitize_pl->dpa_range_list[i].starting_dpa;
> + uint64_t length = media_op_in_sanitize_pl->dpa_range_list[i].length;
> + if (validate_dpa_addr(ct3d, start_dpa, length)) {
> + return CXL_MBOX_INVALID_INPUT;
> + }
> + total_mem += media_op_in_sanitize_pl->dpa_range_list[i].length;
totalmem += length.
> + }
> + ct3d->media_op_sanitize = g_malloc0(sizeof(struct CXLSanitizeInfo) +
> + (dpa_range_count *
> + sizeof(struct dpa_range_list_entry)));
> +
> + if (ct3d->media_op_sanitize) {
This can't fail. g_malloc0 failing kills qemu anyway (makes memory
handling simple ;)
> + ct3d->media_op_sanitize->dpa_range_count = dpa_range_count;
> + ct3d->media_op_sanitize->fill_value = fill_value;
> + memcpy(ct3d->media_op_sanitize->dpa_range_list,
> + media_op_in_sanitize_pl->dpa_range_list,
Align after the (
> + (dpa_range_count *
> + sizeof(struct dpa_range_list_entry)));
> + secs = get_sanitize_duration(total_mem >> 20);
> + }
> +
> + /* EBUSY other bg cmds as of now */
> + cci->bg.runtime = secs * 1000UL;
> + *len_out = 0;
> + /*
> + * media op sanitize is targeted so no need to disable media or
> + * clear event logs
> + */
> + return CXL_MBOX_BG_STARTED;
> +}
> +
> static CXLRetCode cmd_media_operations(const struct cxl_cmd *cmd,
> uint8_t *payload_in,
> size_t len_in,
> @@ -1836,6 +2024,7 @@ static CXLRetCode cmd_media_operations(const struct cxl_cmd *cmd,
> uint8_t rsvd[2];
> uint32_t dpa_range_count;
> } QEMU_PACKED *media_op_in_common_pl = (void *)payload_in;
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> uint8_t media_op_cl = 0;
> uint8_t media_op_subclass = 0;
>
> @@ -1853,7 +2042,20 @@ static CXLRetCode cmd_media_operations(const struct cxl_cmd *cmd,
> }
>
> return media_operations_discovery(payload_in, len_in, payload_out,
> - len_out);
> + len_out);
> + case MEDIA_OP_CLASS_SANITIZE:
> + switch (media_op_subclass) {
> + case MEDIA_OP_SAN_SUBC_SANITIZE:
> + return media_operations_sanitize(ct3d, payload_in, len_in,
> + payload_out, len_out, 0xF,
> + cci);
> + case MEDIA_OP_SAN_SUBC_ZERO:
> + return media_operations_sanitize(ct3d, payload_in, len_in,
> + payload_out, len_out, 0,
> + cci);
> + default:
> + return CXL_MBOX_UNSUPPORTED;
> + }
> default:
> return CXL_MBOX_UNSUPPORTED;
> }
> @@ -3170,6 +3372,12 @@ static void bg_timercb(void *opaque)
> cxl_dev_enable_media(&ct3d->cxl_dstate);
> }
> break;
> + case 0x4402: /* Media Operations sanitize */
> + {
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> + __do_sanitize(ct3d);
> + }
> + break;
> case 0x4304: /* scan media */
> {
> CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index a64739be25..3c5711249b 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -581,6 +581,8 @@ typedef struct CXLSetFeatureInfo {
> size_t data_size;
> } CXLSetFeatureInfo;
>
> +struct CXLSanitizeInfo;
> +
> struct CXLType3Dev {
> /* Private */
> PCIDevice parent_obj;
> @@ -651,6 +653,8 @@ struct CXLType3Dev {
> uint8_t num_regions; /* 0-8 regions */
> CXLDCRegion regions[DCD_MAX_NUM_REGION];
> } dc;
> +
> + struct CXLSanitizeInfo *media_op_sanitize;
> };
>
> #define TYPE_CXL_TYPE3 "cxl-type3"
next prev parent reply other threads:[~2025-02-20 15:10 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20250220052733epcas5p41f847e5d0233a62703693565ee37374c@epcas5p4.samsung.com>
2025-02-20 5:27 ` [PATCH v3 0/3] CXL CCI Media Operations Vinayak Holikatti
2025-02-20 5:27 ` [PATCH v3 1/3] hw/cxl/cxl-mailbox-utils: Add support for Media operations discovery commands cxl r3.2 (8.2.10.9.5.3) Vinayak Holikatti
2025-02-20 15:10 ` Jonathan Cameron
2025-02-20 15:10 ` Jonathan Cameron via
2025-02-20 5:27 ` [PATCH v3 2/3] hw/cxl: factor out calculation of sanitize duration from cmd_santize_overwrite Vinayak Holikatti
2025-03-05 8:49 ` Jonathan Cameron
2025-03-05 8:49 ` Jonathan Cameron via
2025-02-20 5:27 ` [PATCH v3 3/3] hw/cxl/cxl-mailbox-utils: Add support for Media operations Sanitize and Write Zeros commands cxl r3.2(8.2.10.9.5.3) Vinayak Holikatti
2025-02-20 15:10 ` Jonathan Cameron [this message]
2025-02-20 15:10 ` 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=20250220151009.000009e7@huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=a.manzanares@samsung.com \
--cc=alok.rathore@samsung.com \
--cc=dave@stgolabs.net \
--cc=gost.dev@samsung.com \
--cc=krish.reddy@samsung.com \
--cc=linux-cxl@vger.kernel.org \
--cc=nifan.cxl@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=vinayak.kh@samsung.com \
--cc=vishak.g@samsung.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.