[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH-for-8.0 06/10] hw/virtio: Cache access_is_big_endian valu
From: |
Philippe Mathieu-Daudé |
Subject: |
Re: [RFC PATCH-for-8.0 06/10] hw/virtio: Cache access_is_big_endian value in VirtIODevice state |
Date: |
Tue, 13 Dec 2022 09:32:51 +0100 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.5.1 |
On 13/12/22 09:03, Thomas Huth wrote:
On 13/12/2022 08.30, Philippe Mathieu-Daudé wrote:
On 13/12/22 01:14, Richard Henderson wrote:
On 12/12/22 17:05, Philippe Mathieu-Daudé wrote:
The device endianness doesn't change during runtime.
What are you talking about? Of course it does.
The host CPU certainly does, but the virtio device doesn't... Does it?
This check only consider the device, not the CPU:
bool virtio_access_is_big_endian(VirtIODevice *vdev)
{
#if defined(LEGACY_VIRTIO_IS_BIENDIAN)
return virtio_is_big_endian(vdev);
#elif TARGET_BIG_ENDIAN
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
/*Devices conforming to VIRTIO 1.0 or later are always LE.*/
return false;
}
return true;
Well, this part here means that the endianness can indeed change on the
device side during runtime. Depending on whether VIRTIO_F_VERSION_1 is
negotiated or not, the device is little or big endian. Happens on s390x
for example - for legacy virtio, big endian is used, and for modern
virtio, little endian is used instead.
virtio_is_big_endian() depends on vdev->device_endian which is set in:
1) virtio_init()
void virtio_init(VirtIODevice *vdev, uint16_t device_id,
size_t config_size)
{
....
vdev->device_endian = virtio_default_endian();
2) virtio_load()
int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
{
int i, ret;
int32_t config_len;
uint32_t num;
uint32_t features;
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
/*
* We poison the endianness to ensure it does not get
* used before subsections have been loaded.
*/
vdev->device_endian = VIRTIO_DEVICE_ENDIAN_UNKNOWN;
....
if (vdev->device_endian == VIRTIO_DEVICE_ENDIAN_UNKNOWN) {
vdev->device_endian = virtio_default_endian();
}
3) virtio_reset()
void virtio_reset(void *opaque)
{
VirtIODevice *vdev = opaque;
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
int i;
virtio_set_status(vdev, 0);
if (current_cpu) {
/* Guest initiated reset */
vdev->device_endian = virtio_current_cpu_endian();
} else {
/* System reset */
vdev->device_endian = virtio_default_endian();
}
So the current patch is not complete and should be:
-- >8 --
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 09b1a0e3d9..b02b9058f9 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2124,6 +2124,7 @@ void virtio_reset(void *opaque)
/* System reset */
vdev->device_endian = virtio_default_endian();
}
+ vdev->access_is_big_endian = virtio_access_is_big_endian(vdev);
if (k->reset) {
k->reset(vdev);
@@ -3018,6 +3019,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f,
int version_id)
if (vdev->device_endian == VIRTIO_DEVICE_ENDIAN_UNKNOWN) {
vdev->device_endian = virtio_default_endian();
+ vdev->access_is_big_endian = virtio_access_is_big_endian(vdev);
}
if (virtio_64bit_features_needed(vdev)) {
@@ -3193,6 +3195,7 @@ void virtio_init(VirtIODevice *vdev, uint16_t
device_id, size_t config_size)
vdev->vmstate = qdev_add_vm_change_state_handler(DEVICE(vdev),
virtio_vmstate_change, vdev);
vdev->device_endian = virtio_default_endian();
+ vdev->access_is_big_endian = virtio_access_is_big_endian(vdev);
vdev->use_guest_notifier_mask = true;
}
---
Still, the result of virtio_access_is_big_endian() doesn't depend on
the CPU endianness in my analysis... What am I missing?
Thanks,
Phil.
- [PATCH-for-8.0 02/10] hw/virtio: Rename virtio_ss[] -> specific_virtio_ss[], (continued)
- [PATCH-for-8.0 02/10] hw/virtio: Rename virtio_ss[] -> specific_virtio_ss[], Philippe Mathieu-Daudé, 2022/12/12
- [PATCH-for-8.0 03/10] hw/virtio: Constify qmp_virtio_feature_map_t[], Philippe Mathieu-Daudé, 2022/12/12
- [PATCH-for-8.0 04/10] hw/virtio: Extract config read/write accessors to virtio-config.c, Philippe Mathieu-Daudé, 2022/12/12
- [PATCH-for-8.0 05/10] hw/virtio: Extract QMP related code virtio-qmp.c, Philippe Mathieu-Daudé, 2022/12/12
- [RFC PATCH-for-8.0 06/10] hw/virtio: Cache access_is_big_endian value in VirtIODevice state, Philippe Mathieu-Daudé, 2022/12/12
- Re: [RFC PATCH-for-8.0 06/10] hw/virtio: Cache access_is_big_endian value in VirtIODevice state, Philippe Mathieu-Daudé, 2022/12/13
- Re: [RFC PATCH-for-8.0 06/10] hw/virtio: Cache access_is_big_endian value in VirtIODevice state, Richard Henderson, 2022/12/13
[RFC PATCH-for-8.0 07/10] hw/virtio: Directly access cached VirtIODevice::access_is_big_endian, Philippe Mathieu-Daudé, 2022/12/12
[PATCH-for-8.0 08/10] hw/virtio: Un-inline virtio_access_is_big_endian(), Philippe Mathieu-Daudé, 2022/12/12
[RFC PATCH-for-8.0 09/10] hw/virtio: Extract vhost_user_ram_slots_max() to vhost-user-target.c, Philippe Mathieu-Daudé, 2022/12/12
[RFC PATCH-for-8.0 10/10] hw/virtio: Make most of virtio devices target-independent, Philippe Mathieu-Daudé, 2022/12/12