Skip to content

Commit

Permalink
hw/cxl/device: read from register values in mdev_reg_read()
Browse files Browse the repository at this point in the history
In the current mdev_reg_read() implementation, it consistently returns
that the Media Status is Ready (01b). This was fine until commit
25a5295 ("hw/cxl: Add support for device sanitation") because the
media was presumed to be ready.

However, as per the CXL 3.0 spec "8.2.9.8.5.1 Sanitize (Opcode 4400h)",
during sanitation, the Media State should be set to Disabled (11b). The
mentioned commit correctly sets it to Disabled, but mdev_reg_read()
still returns Media Status as Ready.

To address this, update mdev_reg_read() to read register values instead
of returning dummy values.

Note that __toggle_media() managed to not only write something
that no one read, it did it to the wrong register storage and
so changed the reported mailbox size which was definitely not
the intent. That gets fixed as a side effect of allocating
separate state storage for this register.

Fixes: commit 25a5295 ("hw/cxl: Add support for device sanitation")
Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Reviewed-by: Fan Ni <fan.ni@samsung.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20240126120132.24248-7-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit f7509f4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
  • Loading branch information
hygoni authored and Michael Tokarev committed Feb 14, 2024
1 parent 9d8a2a8 commit bdd3159
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
17 changes: 11 additions & 6 deletions hw/cxl/cxl-device-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,9 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,

static uint64_t mdev_reg_read(void *opaque, hwaddr offset, unsigned size)
{
uint64_t retval = 0;

retval = FIELD_DP64(retval, CXL_MEM_DEV_STS, MEDIA_STATUS, 1);
retval = FIELD_DP64(retval, CXL_MEM_DEV_STS, MBOX_READY, 1);
CXLDeviceState *cxl_dstate = opaque;

return retval;
return cxl_dstate->memdev_status;
}

static void ro_reg_write(void *opaque, hwaddr offset, uint64_t value,
Expand Down Expand Up @@ -371,7 +368,15 @@ static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
cxl_dstate->mbox_msi_n = msi_n;
}

static void memdev_reg_init_common(CXLDeviceState *cxl_dstate) { }
static void memdev_reg_init_common(CXLDeviceState *cxl_dstate)
{
uint64_t memdev_status_reg;

memdev_status_reg = FIELD_DP64(0, CXL_MEM_DEV_STS, MEDIA_STATUS, 1);
memdev_status_reg = FIELD_DP64(memdev_status_reg, CXL_MEM_DEV_STS,
MBOX_READY, 1);
cxl_dstate->memdev_status = memdev_status_reg;
}

void cxl_device_register_init_t3(CXLType3Dev *ct3d)
{
Expand Down
9 changes: 7 additions & 2 deletions include/hw/cxl/cxl_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ typedef struct cxl_device_state {
};
};

/* Stash the memory device status value */
uint64_t memdev_status;

struct {
bool set;
uint64_t last_set;
Expand Down Expand Up @@ -353,8 +356,10 @@ static inline void __toggle_media(CXLDeviceState *cxl_dstate, int val)
{
uint64_t dev_status_reg;

dev_status_reg = FIELD_DP64(0, CXL_MEM_DEV_STS, MEDIA_STATUS, val);
cxl_dstate->mbox_reg_state64[R_CXL_MEM_DEV_STS] = dev_status_reg;
dev_status_reg = cxl_dstate->memdev_status;
dev_status_reg = FIELD_DP64(dev_status_reg, CXL_MEM_DEV_STS, MEDIA_STATUS,
val);
cxl_dstate->memdev_status = dev_status_reg;
}
#define cxl_dev_disable_media(cxlds) \
do { __toggle_media((cxlds), 0x3); } while (0)
Expand Down

0 comments on commit bdd3159

Please sign in to comment.