From 9dab7bbb017d11b64c52239fa4e2f910a6a004f2 Mon Sep 17 00:00:00 2001 From: Gregory Price Date: Thu, 7 Mar 2024 15:53:04 +0000 Subject: [PATCH 01/13] target/i386/tcg: Enable page walking from MMIO memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CXL emulation of interleave requires read and write hooks due to requirement for subpage granularity. The Linux kernel stack now enables using this memory as conventional memory in a separate NUMA node. If a process is deliberately forced to run from that node $ numactl --membind=1 ls the page table walk on i386 fails. Useful part of backtrace: (cpu=cpu@entry=0x555556fd9000, fmt=fmt@entry=0x555555fe3378 "cpu_io_recompile: could not find TB for pc=%p") at ../../cpu-target.c:359 (retaddr=0, addr=19595792376, attrs=..., xlat=, cpu=0x555556fd9000, out_offset=) at ../../accel/tcg/cputlb.c:1339 (cpu=0x555556fd9000, full=0x7fffee0d96e0, ret_be=ret_be@entry=0, addr=19595792376, size=size@entry=8, mmu_idx=4, type=MMU_DATA_LOAD, ra=0) at ../../accel/tcg/cputlb.c:2030 (cpu=cpu@entry=0x555556fd9000, p=p@entry=0x7ffff56fddc0, mmu_idx=, type=type@entry=MMU_DATA_LOAD, memop=, ra=ra@entry=0) at ../../accel/tcg/cputlb.c:2356 (cpu=cpu@entry=0x555556fd9000, addr=addr@entry=19595792376, oi=oi@entry=52, ra=ra@entry=0, access_type=access_type@entry=MMU_DATA_LOAD) at ../../accel/tcg/cputlb.c:2439 at ../../accel/tcg/ldst_common.c.inc:301 at ../../target/i386/tcg/sysemu/excp_helper.c:173 (err=0x7ffff56fdf80, out=0x7ffff56fdf70, mmu_idx=0, access_type=MMU_INST_FETCH, addr=18446744072116178925, env=0x555556fdb7c0) at ../../target/i386/tcg/sysemu/excp_helper.c:578 (cs=0x555556fd9000, addr=18446744072116178925, size=, access_type=MMU_INST_FETCH, mmu_idx=0, probe=, retaddr=0) at ../../target/i386/tcg/sysemu/excp_helper.c:604 Avoid this by plumbing the address all the way down from x86_cpu_tlb_fill() where is available as retaddr to the actual accessors which provide it to probe_access_full() which already handles MMIO accesses. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2180 Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2220 Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Suggested-by: Peter Maydell Signed-off-by: Gregory Price Signed-off-by: Jonathan Cameron Message-ID: <20240307155304.31241-2-Jonathan.Cameron@huawei.com> Signed-off-by: Philippe Mathieu-Daudé --- target/i386/tcg/sysemu/excp_helper.c | 57 +++++++++++++++------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c index 8f7011d966..7a57b7dd10 100644 --- a/target/i386/tcg/sysemu/excp_helper.c +++ b/target/i386/tcg/sysemu/excp_helper.c @@ -59,14 +59,14 @@ typedef struct PTETranslate { hwaddr gaddr; } PTETranslate; -static bool ptw_translate(PTETranslate *inout, hwaddr addr) +static bool ptw_translate(PTETranslate *inout, hwaddr addr, uint64_t ra) { CPUTLBEntryFull *full; int flags; inout->gaddr = addr; flags = probe_access_full(inout->env, addr, 0, MMU_DATA_STORE, - inout->ptw_idx, true, &inout->haddr, &full, 0); + inout->ptw_idx, true, &inout->haddr, &full, ra); if (unlikely(flags & TLB_INVALID_MASK)) { TranslateFault *err = inout->err; @@ -82,20 +82,20 @@ static bool ptw_translate(PTETranslate *inout, hwaddr addr) return true; } -static inline uint32_t ptw_ldl(const PTETranslate *in) +static inline uint32_t ptw_ldl(const PTETranslate *in, uint64_t ra) { if (likely(in->haddr)) { return ldl_p(in->haddr); } - return cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, 0); + return cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, ra); } -static inline uint64_t ptw_ldq(const PTETranslate *in) +static inline uint64_t ptw_ldq(const PTETranslate *in, uint64_t ra) { if (likely(in->haddr)) { return ldq_p(in->haddr); } - return cpu_ldq_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, 0); + return cpu_ldq_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, ra); } /* @@ -132,7 +132,8 @@ static inline bool ptw_setl(const PTETranslate *in, uint32_t old, uint32_t set) } static bool mmu_translate(CPUX86State *env, const TranslateParams *in, - TranslateResult *out, TranslateFault *err) + TranslateResult *out, TranslateFault *err, + uint64_t ra) { const target_ulong addr = in->addr; const int pg_mode = in->pg_mode; @@ -164,11 +165,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, * Page table level 5 */ pte_addr = (in->cr3 & ~0xfff) + (((addr >> 48) & 0x1ff) << 3); - if (!ptw_translate(&pte_trans, pte_addr)) { + if (!ptw_translate(&pte_trans, pte_addr, ra)) { return false; } restart_5: - pte = ptw_ldq(&pte_trans); + pte = ptw_ldq(&pte_trans, ra); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -188,11 +189,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, * Page table level 4 */ pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 39) & 0x1ff) << 3); - if (!ptw_translate(&pte_trans, pte_addr)) { + if (!ptw_translate(&pte_trans, pte_addr, ra)) { return false; } restart_4: - pte = ptw_ldq(&pte_trans); + pte = ptw_ldq(&pte_trans, ra); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -208,11 +209,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, * Page table level 3 */ pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3); - if (!ptw_translate(&pte_trans, pte_addr)) { + if (!ptw_translate(&pte_trans, pte_addr, ra)) { return false; } restart_3_lma: - pte = ptw_ldq(&pte_trans); + pte = ptw_ldq(&pte_trans, ra); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -235,12 +236,12 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, * Page table level 3 */ pte_addr = (in->cr3 & 0xffffffe0ULL) + ((addr >> 27) & 0x18); - if (!ptw_translate(&pte_trans, pte_addr)) { + if (!ptw_translate(&pte_trans, pte_addr, ra)) { return false; } rsvd_mask |= PG_HI_USER_MASK; restart_3_nolma: - pte = ptw_ldq(&pte_trans); + pte = ptw_ldq(&pte_trans, ra); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -257,11 +258,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, * Page table level 2 */ pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3); - if (!ptw_translate(&pte_trans, pte_addr)) { + if (!ptw_translate(&pte_trans, pte_addr, ra)) { return false; } restart_2_pae: - pte = ptw_ldq(&pte_trans); + pte = ptw_ldq(&pte_trans, ra); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -283,10 +284,10 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, * Page table level 1 */ pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3); - if (!ptw_translate(&pte_trans, pte_addr)) { + if (!ptw_translate(&pte_trans, pte_addr, ra)) { return false; } - pte = ptw_ldq(&pte_trans); + pte = ptw_ldq(&pte_trans, ra); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -301,11 +302,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, * Page table level 2 */ pte_addr = (in->cr3 & 0xfffff000ULL) + ((addr >> 20) & 0xffc); - if (!ptw_translate(&pte_trans, pte_addr)) { + if (!ptw_translate(&pte_trans, pte_addr, ra)) { return false; } restart_2_nopae: - pte = ptw_ldl(&pte_trans); + pte = ptw_ldl(&pte_trans, ra); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -330,10 +331,10 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, * Page table level 1 */ pte_addr = (pte & ~0xfffu) + ((addr >> 10) & 0xffc); - if (!ptw_translate(&pte_trans, pte_addr)) { + if (!ptw_translate(&pte_trans, pte_addr, ra)) { return false; } - pte = ptw_ldl(&pte_trans); + pte = ptw_ldl(&pte_trans, ra); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -526,7 +527,8 @@ static G_NORETURN void raise_stage2(CPUX86State *env, TranslateFault *err, static bool get_physical_address(CPUX86State *env, vaddr addr, MMUAccessType access_type, int mmu_idx, - TranslateResult *out, TranslateFault *err) + TranslateResult *out, TranslateFault *err, + uint64_t ra) { TranslateParams in; bool use_stage2 = env->hflags2 & HF2_NPT_MASK; @@ -546,7 +548,7 @@ static bool get_physical_address(CPUX86State *env, vaddr addr, env->nested_pg_mode & PG_MODE_LMA ? MMU_USER64_IDX : MMU_USER32_IDX; in.ptw_idx = MMU_PHYS_IDX; - if (!mmu_translate(env, &in, out, err)) { + if (!mmu_translate(env, &in, out, err, ra)) { err->stage2 = S2_GPA; return false; } @@ -577,7 +579,7 @@ static bool get_physical_address(CPUX86State *env, vaddr addr, return false; } } - return mmu_translate(env, &in, out, err); + return mmu_translate(env, &in, out, err, ra); } break; } @@ -597,7 +599,8 @@ bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, TranslateResult out; TranslateFault err; - if (get_physical_address(env, addr, access_type, mmu_idx, &out, &err)) { + if (get_physical_address(env, addr, access_type, mmu_idx, &out, &err, + retaddr)) { /* * Even if 4MB pages, we map only one 4KB page in the cache to * avoid filling it too fast. From 7c7a9f578e4fb1adff7ac8d9acaaaedb87474e76 Mon Sep 17 00:00:00 2001 From: Lorenz Brun Date: Fri, 15 Mar 2024 15:58:31 +0100 Subject: [PATCH 02/13] hw/scsi/scsi-generic: Fix io_timeout property not applying MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The io_timeout property, introduced in c9b6609 (part of 6.0) is silently overwritten by the hardcoded default value of 30 seconds (DEFAULT_IO_TIMEOUT) in scsi_generic_realize because that function is being called after the properties have already been applied. The property definition already has a default value which is applied correctly when no value is explicitly set, so we can just remove the code which overrides the io_timeout completely. This has been tested by stracing SG_IO operations with the io_timeout property set and unset and now sets the timeout field in the ioctl request to the proper value. Fixes: c9b6609b69facad ("scsi: make io_timeout configurable") Signed-off-by: Lorenz Brun Message-ID: <20240315145831.2531695-1-lorenz@brun.one> Reviewed-by: Alex Bennée Signed-off-by: Philippe Mathieu-Daudé --- hw/scsi/scsi-generic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index b7b04e1d63..ee945f87e3 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -752,7 +752,6 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp) /* Only used by scsi-block, but initialize it nevertheless to be clean. */ s->default_scsi_version = -1; - s->io_timeout = DEFAULT_IO_TIMEOUT; scsi_generic_read_device_inquiry(s); } From a158c63b3ba120f1656e4dd815d186c623fb5ef6 Mon Sep 17 00:00:00 2001 From: Yao Xingtao Date: Tue, 19 Mar 2024 10:16:10 +0800 Subject: [PATCH 03/13] monitor/hmp-cmds-target: Append a space in error message in gpa2hva() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In qemu monitor mode, when we use gpa2hva command to print the host virtual address corresponding to a guest physical address, if the gpa is not in RAM, the error message is below: (qemu) gpa2hva 0x750000000 Memory at address 0x750000000is not RAM A space is missed between '0x750000000' and 'is'. Signed-off-by: Yao Xingtao Fixes: e9628441df ("hmp: gpa2hva and gpa2hpa hostaddr command") Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Dr. David Alan Gilbert Message-ID: <20240319021610.2423844-1-ruansy.fnst@fujitsu.com> Signed-off-by: Philippe Mathieu-Daudé --- monitor/hmp-cmds-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monitor/hmp-cmds-target.c b/monitor/hmp-cmds-target.c index 9338ae8440..ff01cf9d8d 100644 --- a/monitor/hmp-cmds-target.c +++ b/monitor/hmp-cmds-target.c @@ -261,7 +261,7 @@ void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp) } if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) { - error_setg(errp, "Memory at address 0x%" HWADDR_PRIx "is not RAM", addr); + error_setg(errp, "Memory at address 0x%" HWADDR_PRIx " is not RAM", addr); memory_region_unref(mrs.mr); return NULL; } From e66d741467d3062e1d7d2150d2c8de0b805095d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 19 Mar 2024 06:00:46 +0100 Subject: [PATCH 04/13] target/tricore/helper: Use correct string format in cpu_tlb_fill() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'address' got converted from target_ulong to vaddr in commit 68d6eee73c ("target/tricore: Convert to CPUClass::tlb_fill"). Use the corresponding format string to avoid casting. Signed-off-by: Philippe Mathieu-Daudé Message-ID: <20240319051413.6956-1-philmd@linaro.org> Reviewed-by: Richard Henderson Reviewed-by: Bastian Koppelmann --- target/tricore/helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/tricore/helper.c b/target/tricore/helper.c index 6d9e80cc0c..76bd226370 100644 --- a/target/tricore/helper.c +++ b/target/tricore/helper.c @@ -76,9 +76,9 @@ bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size, ret = get_physical_address(env, &physical, &prot, address, rw, mmu_idx); - qemu_log_mask(CPU_LOG_MMU, "%s address=" TARGET_FMT_lx " ret %d physical " + qemu_log_mask(CPU_LOG_MMU, "%s address=0x%" VADDR_PRIx " ret %d physical " HWADDR_FMT_plx " prot %d\n", - __func__, (target_ulong)address, ret, physical, prot); + __func__, address, ret, physical, prot); if (ret == TLBRET_MATCH) { tlb_set_page(cs, address & TARGET_PAGE_MASK, From 52405b7f69d03428950c33ebe823e2256e6a4a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Mar 2024 16:48:17 +0100 Subject: [PATCH 05/13] hw/clock: Let clock_set_mul_div() return a boolean value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let clock_set_mul_div() return a boolean value whether the clock has been updated or not, similarly to clock_set(). Return early when clock_set_mul_div() is called with same mul/div values the clock has. Acked-by: Luc Michel Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-Id: <20240325152827.73817-2-philmd@linaro.org> --- docs/devel/clocks.rst | 4 ++++ hw/core/clock.c | 8 +++++++- include/hw/clock.h | 4 +++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst index c4d14bde04..b2d1148cdb 100644 --- a/docs/devel/clocks.rst +++ b/docs/devel/clocks.rst @@ -279,6 +279,10 @@ You can change the multiplier and divider of a clock at runtime, so you can use this to model clock controller devices which have guest-programmable frequency multipliers or dividers. +Similary to ``clock_set()``, ``clock_set_mul_div()`` returns ``true`` if +the clock state was modified; that is, if the multiplier or the diviser +or both were changed by the call. + Note that ``clock_set_mul_div()`` does not automatically call ``clock_propagate()``. If you make a runtime change to the multiplier or divider you must call clock_propagate() yourself. diff --git a/hw/core/clock.c b/hw/core/clock.c index d82e44cd1a..a19c7db7df 100644 --- a/hw/core/clock.c +++ b/hw/core/clock.c @@ -143,14 +143,20 @@ char *clock_display_freq(Clock *clk) return freq_to_str(clock_get_hz(clk)); } -void clock_set_mul_div(Clock *clk, uint32_t multiplier, uint32_t divider) +bool clock_set_mul_div(Clock *clk, uint32_t multiplier, uint32_t divider) { assert(divider != 0); + if (clk->multiplier == multiplier && clk->divider == divider) { + return false; + } + trace_clock_set_mul_div(CLOCK_PATH(clk), clk->multiplier, multiplier, clk->divider, divider); clk->multiplier = multiplier; clk->divider = divider; + + return true; } static void clock_initfn(Object *obj) diff --git a/include/hw/clock.h b/include/hw/clock.h index bb12117f67..eb58599131 100644 --- a/include/hw/clock.h +++ b/include/hw/clock.h @@ -357,6 +357,8 @@ char *clock_display_freq(Clock *clk); * @multiplier: multiplier value * @divider: divider value * + * @return: true if the clock is changed. + * * By default, a Clock's children will all run with the same period * as their parent. This function allows you to adjust the multiplier * and divider used to derive the child clock frequency. @@ -374,6 +376,6 @@ char *clock_display_freq(Clock *clk); * Note that this function does not call clock_propagate(); the * caller should do that if necessary. */ -void clock_set_mul_div(Clock *clk, uint32_t multiplier, uint32_t divider); +bool clock_set_mul_div(Clock *clk, uint32_t multiplier, uint32_t divider); #endif /* QEMU_HW_CLOCK_H */ From 1f439706a0675c67ff45ac92b6bd95c1f41db8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 25 Mar 2024 12:30:12 +0100 Subject: [PATCH 06/13] hw/misc/stm32l4x5_rcc: Inline clock_update() in clock_mux_update() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trivial inlining in preliminary patch to make the next one easier to review. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-Id: <20240325152827.73817-3-philmd@linaro.org> --- hw/misc/stm32l4x5_rcc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/misc/stm32l4x5_rcc.c b/hw/misc/stm32l4x5_rcc.c index bc2d63528b..49b90afdf0 100644 --- a/hw/misc/stm32l4x5_rcc.c +++ b/hw/misc/stm32l4x5_rcc.c @@ -48,6 +48,8 @@ static void clock_mux_update(RccClockMuxState *mux, bool bypass_source) uint64_t src_freq; Clock *current_source = mux->srcs[mux->src]; uint32_t freq_multiplier = 0; + bool clk_changed = false; + /* * To avoid rounding errors, we use the clock period instead of the * frequency. @@ -60,7 +62,10 @@ static void clock_mux_update(RccClockMuxState *mux, bool bypass_source) } clock_set_mul_div(mux->out, freq_multiplier, mux->multiplier); - clock_update(mux->out, clock_get(current_source)); + clk_changed |= clock_set(mux->out, clock_get(current_source)); + if (clk_changed) { + clock_propagate(mux->out); + } src_freq = clock_get_hz(current_source); /* TODO: can we simply detect if the config changed so that we reduce log spam ? */ From 32da7e207ce096f94b5d9659b0cc7f1aa9ae3ef5 Mon Sep 17 00:00:00 2001 From: Arnaud Minier Date: Sun, 17 Mar 2024 11:39:12 +0100 Subject: [PATCH 07/13] hw/misc/stm32l4x5_rcc: Propagate period when enabling a clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "clock_set_mul_div" function doesn't propagate the clock period to the children if it is changed (e.g. by enabling/disabling a clock multiplexer). This was overlooked during the implementation due to late changes. This commit propagates the change if the multiplier or divider changes. Fixes: ec7d83acbd ("hw/misc/stm32l4x5_rcc: Add an internal clock multiplexer object") Signed-off-by: Arnaud Minier Signed-off-by: Inès Varhol Message-ID: <20240317103918.44375-2-arnaud.minier@telecom-paris.fr> [PMD: Check clock_set_mul_div() return value] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-Id: <20240325152827.73817-4-philmd@linaro.org> --- hw/misc/stm32l4x5_rcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/misc/stm32l4x5_rcc.c b/hw/misc/stm32l4x5_rcc.c index 49b90afdf0..ed2dbd9dc3 100644 --- a/hw/misc/stm32l4x5_rcc.c +++ b/hw/misc/stm32l4x5_rcc.c @@ -61,7 +61,7 @@ static void clock_mux_update(RccClockMuxState *mux, bool bypass_source) freq_multiplier = mux->divider; } - clock_set_mul_div(mux->out, freq_multiplier, mux->multiplier); + clk_changed |= clock_set_mul_div(mux->out, freq_multiplier, mux->multiplier); clk_changed |= clock_set(mux->out, clock_get(current_source)); if (clk_changed) { clock_propagate(mux->out); From 1dd7754aca3b125d7697b9461730bc075c2508fe Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Sun, 24 Mar 2024 17:11:48 +0100 Subject: [PATCH 08/13] docs/system/ppc/amigang.rst: Fix formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing space to fix character formatting where it was missed in two places. Fixes: 623d9065b6 (docs/system/ppc: Document running Linux on AmigaNG machines) Signed-off-by: BALATON Zoltan Reviewed-by: Peter Maydell Message-ID: <20240324161148.4650D4E601F@zero.eik.bme.hu> Signed-off-by: Philippe Mathieu-Daudé --- docs/system/ppc/amigang.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/system/ppc/amigang.rst b/docs/system/ppc/amigang.rst index ba1a3d80b9..e2c9cb74b7 100644 --- a/docs/system/ppc/amigang.rst +++ b/docs/system/ppc/amigang.rst @@ -16,7 +16,7 @@ firmware to support AmigaOS 4. Emulated devices ---------------- - * PowerPC 7457 CPU (can also use``-cpu g3, 750cxe, 750fx`` or ``750gx``) + * PowerPC 7457 CPU (can also use ``-cpu g3, 750cxe, 750fx`` or ``750gx``) * Articia S north bridge * VIA VT82C686B south bridge * PCI VGA compatible card (guests may need other card instead) @@ -73,7 +73,7 @@ https://www.powerdeveloper.org/platforms/pegasos/schematics. Emulated devices ---------------- - * PowerPC 7457 CPU (can also use``-cpu g3`` or ``750cxe``) + * PowerPC 7457 CPU (can also use ``-cpu g3`` or ``750cxe``) * Marvell MV64361 Discovery II north bridge * VIA VT8231 south bridge * PCI VGA compatible card (guests may need other card instead) From d5866a7a4e5a4178ccab4ca19303ea09635e5fa4 Mon Sep 17 00:00:00 2001 From: Yao Xingtao Date: Mon, 25 Mar 2024 21:52:57 -0400 Subject: [PATCH 09/13] contrib/plugins/execlog: Fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. The g_pattern_match_string() is deprecated when glib2 version >= 2.70. Use g_pattern_spec_match_string() instead to avoid this problem. 2. The type of second parameter in g_ptr_array_add() is 'gpointer' {aka 'void *'}, but the type of reg->name is 'const char*'. Cast the type of reg->name to 'gpointer' to avoid this problem. compiler warning message: contrib/plugins/execlog.c:330:17: warning: ‘g_pattern_match_string’ is deprecated: Use 'g_pattern_spec_match_string' instead [-Wdeprecated-declarations] 330 | if (g_pattern_match_string(pat, rd->name) || | ^~ In file included from /usr/include/glib-2.0/glib.h:67, from contrib/plugins/execlog.c:9: /usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here 57 | gboolean g_pattern_match_string (GPatternSpec *pspec, | ^~~~~~~~~~~~~~~~~~~~~~ contrib/plugins/execlog.c:331:21: warning: ‘g_pattern_match_string’ is deprecated: Use 'g_pattern_spec_match_string' instead [-Wdeprecated-declarations] 331 | g_pattern_match_string(pat, rd_lower)) { | ^~~~~~~~~~~~~~~~~~~~~~ /usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here 57 | gboolean g_pattern_match_string (GPatternSpec *pspec, | ^~~~~~~~~~~~~~~~~~~~~~ contrib/plugins/execlog.c:339:63: warning: passing argument 2 of ‘g_ptr_array_add’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers] 339 | g_ptr_array_add(all_reg_names, reg->name); | ~~~^~~~~~ In file included from /usr/include/glib-2.0/glib.h:33: /usr/include/glib-2.0/glib/garray.h:198:62: note: expected ‘gpointer’ {aka ‘void *’} but argument is of type ‘const char *’ 198 | gpointer data); | ~~~~~~~~~~~~~~~~~~^~~~ Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2210 Signed-off-by: Yao Xingtao Message-ID: <20240326015257.21516-1-yaoxt.fnst@fujitsu.com> Reviewed-by: Pierrick Bouvier Reviewed-by: Peter Maydell Signed-off-by: Philippe Mathieu-Daudé --- contrib/plugins/execlog.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c index a1dfd59ab7..fab18113d4 100644 --- a/contrib/plugins/execlog.c +++ b/contrib/plugins/execlog.c @@ -311,6 +311,24 @@ static Register *init_vcpu_register(qemu_plugin_reg_descriptor *desc) return reg; } +/* + * g_pattern_match_string has been deprecated in Glib since 2.70 and + * will complain about it if you try to use it. Fortunately the + * signature of both functions is the same making it easy to work + * around. + */ +static inline +gboolean g_pattern_spec_match_string_qemu(GPatternSpec *pspec, + const gchar *string) +{ +#if GLIB_CHECK_VERSION(2, 70, 0) + return g_pattern_spec_match_string(pspec, string); +#else + return g_pattern_match_string(pspec, string); +#endif +}; +#define g_pattern_spec_match_string(p, s) g_pattern_spec_match_string_qemu(p, s) + static GPtrArray *registers_init(int vcpu_index) { g_autoptr(GPtrArray) registers = g_ptr_array_new(); @@ -327,8 +345,8 @@ static GPtrArray *registers_init(int vcpu_index) for (int p = 0; p < rmatches->len; p++) { g_autoptr(GPatternSpec) pat = g_pattern_spec_new(rmatches->pdata[p]); g_autofree gchar *rd_lower = g_utf8_strdown(rd->name, -1); - if (g_pattern_match_string(pat, rd->name) || - g_pattern_match_string(pat, rd_lower)) { + if (g_pattern_spec_match_string(pat, rd->name) || + g_pattern_spec_match_string(pat, rd_lower)) { Register *reg = init_vcpu_register(rd); g_ptr_array_add(registers, reg); @@ -336,7 +354,7 @@ static GPtrArray *registers_init(int vcpu_index) if (disas_assist) { g_mutex_lock(&add_reg_name_lock); if (!g_ptr_array_find(all_reg_names, reg->name, NULL)) { - g_ptr_array_add(all_reg_names, reg->name); + g_ptr_array_add(all_reg_names, (gpointer)reg->name); } g_mutex_unlock(&add_reg_name_lock); } From 5c5d00df67a33d3931c35d566329f3d90013732b Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Tue, 26 Mar 2024 13:26:30 +0100 Subject: [PATCH 10/13] hw/smbios: add stub for smbios_get_table_legacy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QEMU build fails with hw/i386/fw_cfg.c:74: undefined reference to `smbios_get_table_legacy' when it's built with only 'microvm' enabled i.e. with config patch +++ b/configs/devices/i386-softmmu/default.mak @@ -26,7 +26,7 @@ # Boards: # -CONFIG_ISAPC=y -CONFIG_I440FX=y -CONFIG_Q35=y +CONFIG_ISAPC=n +CONFIG_I440FX=n +CONFIG_Q35=n It happens because I've fogotten/lost smbios_get_table_legacy() stub. Fix it by adding missing stub as Philippe suggested. Fixes: b42b0e4daaa5 "smbios: build legacy mode code only for 'pc' machine" Reported-by: Michael Tokarev Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Igor Mammedov Message-ID: <20240326122630.85989-1-imammedo@redhat.com> Tested-by: Philippe Mathieu-Daudé --- hw/smbios/smbios_legacy_stub.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/smbios/smbios_legacy_stub.c b/hw/smbios/smbios_legacy_stub.c index f29b15316c..7d593dca98 100644 --- a/hw/smbios/smbios_legacy_stub.c +++ b/hw/smbios/smbios_legacy_stub.c @@ -13,3 +13,8 @@ void smbios_add_usr_blob_size(size_t size) { } + +uint8_t *smbios_get_table_legacy(size_t *length, Error **errp) +{ + g_assert_not_reached(); +} From d2ee0420a394bb0affb06659bdb5d706af24157b Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sat, 23 Mar 2024 15:20:01 +0900 Subject: [PATCH 11/13] ui/cocoa: Fix aspect ratio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [NSWindow setContentAspectRatio:] does not trigger window resize itself, so the wrong aspect ratio will persist if nothing resizes the window. Call [NSWindow setContentSize:] in such a case. Fixes: 91aa508d0274 ("ui/cocoa: Let the platform toggle fullscreen") Signed-off-by: Akihiko Odaki Reviewed-by: Peter Maydell Message-ID: <20240323-fixes-v2-1-18651a2b0394@daynix.com> Signed-off-by: Philippe Mathieu-Daudé --- ui/cocoa.m | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 810751cf26..17e125d66d 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -519,6 +519,43 @@ - (void) drawRect:(NSRect) rect } } +- (NSSize)fixAspectRatio:(NSSize)max +{ + NSSize scaled; + NSSize fixed; + + scaled.width = screen.width * max.height; + scaled.height = screen.height * max.width; + + /* + * Here screen is our guest's output size, and max is the size of the + * largest possible area of the screen we can display on. + * We want to scale up (screen.width x screen.height) by either: + * 1) max.height / screen.height + * 2) max.width / screen.width + * With the first scale factor the scale will result in an output height of + * max.height (i.e. we will fill the whole height of the available screen + * space and have black bars left and right) and with the second scale + * factor the scaling will result in an output width of max.width (i.e. we + * fill the whole width of the available screen space and have black bars + * top and bottom). We need to pick whichever keeps the whole of the guest + * output on the screen, which is to say the smaller of the two scale + * factors. + * To avoid doing more division than strictly necessary, instead of directly + * comparing scale factors 1 and 2 we instead calculate and compare those + * two scale factors multiplied by (screen.height * screen.width). + */ + if (scaled.width < scaled.height) { + fixed.width = scaled.width / screen.height; + fixed.height = max.height; + } else { + fixed.width = max.width; + fixed.height = scaled.height / screen.width; + } + + return fixed; +} + - (NSSize) screenSafeAreaSize { NSSize size = [[[self window] screen] frame].size; @@ -536,8 +573,10 @@ - (void) resizeWindow [[self window] setContentSize:NSMakeSize(screen.width, screen.height)]; [[self window] center]; } else if ([[self window] styleMask] & NSWindowStyleMaskFullScreen) { - [[self window] setContentSize:[self screenSafeAreaSize]]; + [[self window] setContentSize:[self fixAspectRatio:[self screenSafeAreaSize]]]; [[self window] center]; + } else { + [[self window] setContentSize:[self fixAspectRatio:[self frame].size]]; } } From f69a6f04133df61e2ab23553496a070f27f5b732 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sat, 23 Mar 2024 15:20:02 +0900 Subject: [PATCH 12/13] ui/cocoa: Resize window after toggling zoom-to-fit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resize the window so that the content will fit without zooming. Fixes: 91aa508d0274 ("ui/cocoa: Let the platform toggle fullscreen") Signed-off-by: Akihiko Odaki Reviewed-by: Peter Maydell Message-ID: <20240323-fixes-v2-2-18651a2b0394@daynix.com> Signed-off-by: Philippe Mathieu-Daudé --- ui/cocoa.m | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/cocoa.m b/ui/cocoa.m index 17e125d66d..3efa8ac1a9 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1408,6 +1408,7 @@ - (void)zoomToFit:(id) sender [[cocoaView window] setStyleMask:styleMask]; [sender setState:styleMask & NSWindowStyleMaskResizable ? NSControlStateValueOn : NSControlStateValueOff]; + [cocoaView resizeWindow]; } - (void)toggleZoomInterpolation:(id) sender From ccebb9ae352eea63cb1491cb829e4cd0f7576f1c Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sat, 23 Mar 2024 15:20:03 +0900 Subject: [PATCH 13/13] ui/cocoa: Use NSTrackingInVisibleRect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I observed [NSTrackingArea rect] becomes de-synchronized with the view frame with some unknown condition, and fails to track mouse movement on some area of the view. Specify NSTrackingInVisibleRect option to let Cocoa automatically update NSTrackingArea, which also saves code for synchronization. Fixes: 91aa508d0274 ("ui/cocoa: Let the platform toggle fullscreen") Signed-off-by: Akihiko Odaki Reviewed-by: Peter Maydell Message-ID: <20240323-fixes-v2-3-18651a2b0394@daynix.com> Signed-off-by: Philippe Mathieu-Daudé --- ui/cocoa.m | 48 ++++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 3efa8ac1a9..25e0db9dd0 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -307,7 +307,6 @@ static void handleAnyDeviceErrors(Error * err) */ @interface QemuCocoaView : NSView { - NSTrackingArea *trackingArea; QEMUScreen screen; pixman_image_t *pixman_image; BOOL isMouseGrabbed; @@ -359,6 +358,19 @@ - (id)initWithFrame:(NSRect)frameRect self = [super initWithFrame:frameRect]; if (self) { + NSTrackingAreaOptions options = NSTrackingActiveInKeyWindow | + NSTrackingMouseEnteredAndExited | + NSTrackingMouseMoved | + NSTrackingInVisibleRect; + + NSTrackingArea *trackingArea = + [[NSTrackingArea alloc] initWithRect:CGRectZero + options:options + owner:self + userInfo:nil]; + + [self addTrackingArea:trackingArea]; + [trackingArea release]; screen.width = frameRect.size.width; screen.height = frameRect.size.height; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_14_0 @@ -389,41 +401,9 @@ - (BOOL) isOpaque return YES; } -- (void) removeTrackingRect -{ - if (trackingArea) { - [self removeTrackingArea:trackingArea]; - [trackingArea release]; - trackingArea = nil; - } -} - -- (void) frameUpdated -{ - [self removeTrackingRect]; - - if ([self window]) { - NSTrackingAreaOptions options = NSTrackingActiveInKeyWindow | - NSTrackingMouseEnteredAndExited | - NSTrackingMouseMoved; - trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame] - options:options - owner:self - userInfo:nil]; - [self addTrackingArea:trackingArea]; - [self updateUIInfo]; - } -} - - (void) viewDidMoveToWindow { [self resizeWindow]; - [self frameUpdated]; -} - -- (void) viewWillMoveToWindow:(NSWindow *)newWindow -{ - [self removeTrackingRect]; } - (void) selectConsoleLocked:(unsigned int)index @@ -1314,7 +1294,7 @@ - (void)windowDidExitFullScreen:(NSNotification *)notification - (void)windowDidResize:(NSNotification *)notification { [cocoaView updateBounds]; - [cocoaView frameUpdated]; + [cocoaView updateUIInfo]; } /* Called when the user clicks on a window's close button */