From c6c6d854447a7821288e01857d0f7fb28b82cf44 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 17 Oct 2025 13:50:05 +0200 Subject: [PATCH] hw/uefi/ovmf-log: add maxsize parameter Allow limiting the amount of log output sent. Allow up to 1 MiB. In case the guest log buffer is larger than 1 MiB limit the output instead of throwing an error. Acked-by: Markus Armbruster Signed-off-by: Gerd Hoffmann Message-ID: <20251017115006.2696991-4-kraxel@redhat.com> --- hmp-commands-info.hx | 4 ++-- hw/uefi/ovmf-log.c | 42 ++++++++++++++++++++++++++++++++++-------- qapi/machine.json | 5 +++++ 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 33cf740bbc..2a7f5810d7 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -998,8 +998,8 @@ ERST { .name = "firmware-log", - .args_type = "", - .params = "", + .args_type = "max-size:o?", + .params = "[max-size]", .help = "show the firmware (ovmf) debug log", .cmd = hmp_info_firmware_log, }, diff --git a/hw/uefi/ovmf-log.c b/hw/uefi/ovmf-log.c index fe8acbd192..98ebb02094 100644 --- a/hw/uefi/ovmf-log.c +++ b/hw/uefi/ovmf-log.c @@ -18,6 +18,7 @@ #include "qapi/error.h" #include "qapi/type-helpers.h" #include "qapi/qapi-commands-machine.h" +#include "qobject/qdict.h" /* ----------------------------------------------------------------------- */ @@ -164,7 +165,8 @@ static void handle_ovmf_log_range(GString *out, } } -FirmwareLog *qmp_query_firmware_log(Error **errp) +FirmwareLog *qmp_query_firmware_log(bool have_max_size, uint64_t max_size, + Error **errp) { MEM_DEBUG_LOG_HDR header; dma_addr_t offset, base; @@ -184,18 +186,40 @@ FirmwareLog *qmp_query_firmware_log(Error **errp) return NULL; } - if (header.DebugLogSize > MiB) { - /* default size is 128k (32 pages), allow up to 1M */ - error_setg(errp, "firmware log: log buffer is too big"); - return NULL; - } - if (header.DebugLogHeadOffset > header.DebugLogSize || header.DebugLogTailOffset > header.DebugLogSize) { error_setg(errp, "firmware log buffer header is invalid"); return NULL; } + if (have_max_size) { + if (max_size > MiB) { + error_setg(errp, "parameter 'max-size' exceeds 1MiB"); + return NULL; + } + } else { + max_size = MiB; + } + + /* adjust header.DebugLogHeadOffset so we return at most maxsize bytes */ + if (header.DebugLogHeadOffset > header.DebugLogTailOffset) { + /* wrap around */ + if (header.DebugLogTailOffset > max_size) { + header.DebugLogHeadOffset = header.DebugLogTailOffset - max_size; + } else { + uint64_t max_chunk = max_size - header.DebugLogTailOffset; + if (header.DebugLogSize > max_chunk && + header.DebugLogHeadOffset < header.DebugLogSize - max_chunk) { + header.DebugLogHeadOffset = header.DebugLogSize - max_chunk; + } + } + } else { + if (header.DebugLogTailOffset > max_size && + header.DebugLogHeadOffset < header.DebugLogTailOffset - max_size) { + header.DebugLogHeadOffset = header.DebugLogTailOffset - max_size; + } + } + base = offset + header.HeaderSize; if (header.DebugLogHeadOffset > header.DebugLogTailOffset) { /* wrap around */ @@ -239,8 +263,10 @@ void hmp_info_firmware_log(Monitor *mon, const QDict *qdict) Error *err = NULL; FirmwareLog *log; gsize log_len; + int64_t maxsize; - log = qmp_query_firmware_log(&err); + maxsize = qdict_get_try_int(qdict, "max-size", -1); + log = qmp_query_firmware_log(maxsize != -1, (uint64_t)maxsize, &err); if (err) { hmp_handle_error(mon, err); return; diff --git a/qapi/machine.json b/qapi/machine.json index 96133e5c71..c6dc6fe69b 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -1858,9 +1858,14 @@ # # Find firmware memory log buffer in guest memory, return content. # +# @max-size: limit the amount of log data returned. Up to 1 MiB of +# log data is allowed. In case the amount of log data is +# larger than @max-size the tail of the log is returned. +# # Since: 10.2 ## { 'command': 'query-firmware-log', + 'data': { '*max-size': 'size' }, 'returns': 'FirmwareLog' } ## -- 2.47.3