From 8a08b3b41400e152cc1786ae5a8a53507f8e925c Mon Sep 17 00:00:00 2001 From: Jinhua Cao Date: Thu, 10 Feb 2022 14:16:17 +0800 Subject: [PATCH] virtio: print the guest virtio_net features that host does not support Signed-off-by: Jinhua Cao --- hw/net/virtio-net.c | 41 ++++++++++++++++++++++++++++++++++++++ hw/virtio/virtio.c | 7 +++++++ include/hw/virtio/virtio.h | 1 + 3 files changed, 49 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index b3a5d0b19e..6874c88bc0 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -3692,6 +3692,46 @@ static Property virtio_net_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void virtio_net_print_features(uint64_t features) +{ + Property *props = virtio_net_properties; + int feature_cnt = 0; + + if (!features) { + return; + } + printf("virtio_net_feature: "); + + for (; features && props->name; props++) { + /* The bitnr of property may be default(0) besides 'csum' property. */ + if (props->bitnr == 0 && strcmp(props->name, "csum")) { + continue; + } + + /* Features only support 64bit. */ + if (props->bitnr > 63) { + continue; + } + + if (virtio_has_feature(features, props->bitnr)) { + virtio_clear_feature(&features, props->bitnr); + if (feature_cnt != 0) { + printf(", "); + } + printf("%s", props->name); + feature_cnt++; + } + } + + if (features) { + if (feature_cnt != 0) { + printf(", "); + } + printf("unkown bits 0x%." PRIx64, features); + } + printf("\n"); +} + static void virtio_net_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -3706,6 +3746,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) vdc->set_config = virtio_net_set_config; vdc->get_features = virtio_net_get_features; vdc->set_features = virtio_net_set_features; + vdc->print_features = virtio_net_print_features; vdc->bad_features = virtio_net_bad_features; vdc->reset = virtio_net_reset; vdc->set_status = virtio_net_set_status; diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 0af9684881..9a2a83d507 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2967,6 +2967,13 @@ static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val) { VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); bool bad = (val & ~(vdev->host_features)) != 0; + uint64_t feat = val & ~(vdev->host_features); + + if (bad && k->print_features) { + qemu_log("error: Please check host config, "\ + "because host does not support required feature bits 0x%" PRIx64 "\n", feat); + k->print_features(feat); + } val &= vdev->host_features; if (k->set_features) { diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index b3749ce34b..7472145821 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -127,6 +127,7 @@ struct VirtioDeviceClass { int (*validate_features)(VirtIODevice *vdev); void (*get_config)(VirtIODevice *vdev, uint8_t *config); void (*set_config)(VirtIODevice *vdev, const uint8_t *config); + void (*print_features)(uint64_t features); void (*reset)(VirtIODevice *vdev); void (*set_status)(VirtIODevice *vdev, uint8_t val); /* For transitional devices, this is a bitmap of features -- 2.27.0