hw/loongarch/virt.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
Since commit f2e61edb2946 ("hw/loongarch/virt: Use MemTxAttrs interface
for misc ops") which adds a call to g_assert_not_reached() in the path
of handling unimplemented IOCSRs, QEMU would abort when the guest
accesses unimplemented IOCSRs.
This is too serious since there's nothing fatal happening in QEMU
itself, and the guest could probably continue running if we give zero as
result for these reads, which also matches the behavior observed on
3A5000M real machine.
Replace the assertion with qemu_log_mask(LOG_UNIMP, ...), it's still
possible to examine unimplemented IOCSR access through "-d unimp"
command line arguments.
Fixes: f2e61edb2946 ("hw/loongarch/virt: Use MemTxAttrs interface for misc ops")
Signed-off-by: Yao Zi <me@ziyao.cc>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
Changed from v1
- Reword the commit message to avoid implying reading/writing
unimplemented IOCSRs is guaranteed to result in zero on LoongArch.
- Don't log writes to read-only {VERSION,FEATURE,VENDOR,CPUNAME}_REG as
unimplemented.
- Link to v1: https://lore.kernel.org/qemu-devel/20251221122511.56544-2-me@ziyao.cc/
hw/loongarch/virt.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 6efa15da4737..97ea1fb46d00 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -46,6 +46,7 @@
#include "hw/block/flash.h"
#include "hw/virtio/virtio-iommu.h"
#include "qemu/error-report.h"
+#include "qemu/log.h"
#include "kvm/kvm_loongarch.h"
static void virt_get_dmsi(Object *obj, Visitor *v, const char *name,
@@ -621,8 +622,15 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
features, attrs, NULL);
break;
+ case VERSION_REG:
+ case FEATURE_REG:
+ case VENDOR_REG:
+ case CPUNAME_REG:
+ break;
default:
- g_assert_not_reached();
+ qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n",
+ __func__, addr);
+ break;
}
return MEMTX_OK;
@@ -680,7 +688,9 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
}
break;
default:
- g_assert_not_reached();
+ qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n",
+ __func__, addr);
+ break;
}
*data = ret;
--
2.52.0
On 2026/1/11 下午6:50, Yao Zi wrote:
> Since commit f2e61edb2946 ("hw/loongarch/virt: Use MemTxAttrs interface
> for misc ops") which adds a call to g_assert_not_reached() in the path
> of handling unimplemented IOCSRs, QEMU would abort when the guest
> accesses unimplemented IOCSRs.
>
> This is too serious since there's nothing fatal happening in QEMU
> itself, and the guest could probably continue running if we give zero as
> result for these reads, which also matches the behavior observed on
> 3A5000M real machine.
>
> Replace the assertion with qemu_log_mask(LOG_UNIMP, ...), it's still
> possible to examine unimplemented IOCSR access through "-d unimp"
> command line arguments.
>
> Fixes: f2e61edb2946 ("hw/loongarch/virt: Use MemTxAttrs interface for misc ops")
> Signed-off-by: Yao Zi <me@ziyao.cc>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>
> Changed from v1
> - Reword the commit message to avoid implying reading/writing
> unimplemented IOCSRs is guaranteed to result in zero on LoongArch.
> - Don't log writes to read-only {VERSION,FEATURE,VENDOR,CPUNAME}_REG as
> unimplemented.
> - Link to v1: https://lore.kernel.org/qemu-devel/20251221122511.56544-2-me@ziyao.cc/
>
> hw/loongarch/virt.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
> index 6efa15da4737..97ea1fb46d00 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -46,6 +46,7 @@
> #include "hw/block/flash.h"
> #include "hw/virtio/virtio-iommu.h"
> #include "qemu/error-report.h"
> +#include "qemu/log.h"
> #include "kvm/kvm_loongarch.h"
>
> static void virt_get_dmsi(Object *obj, Visitor *v, const char *name,
> @@ -621,8 +622,15 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
> EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
> features, attrs, NULL);
> break;
> + case VERSION_REG:
> + case FEATURE_REG:
> + case VENDOR_REG:
> + case CPUNAME_REG:
> + break;
> default:
> - g_assert_not_reached();
> + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n",
> + __func__, addr);
> + break;
> }
>
> return MEMTX_OK;
> @@ -680,7 +688,9 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
> }
> break;
> default:
> - g_assert_not_reached();
> + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n",
> + __func__, addr);
> + break;
> }
>
> *data = ret;
>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
© 2016 - 2026 Red Hat, Inc.