On Wed, 29 Oct 2025, Akihiko Odaki wrote:
On 2025/10/28 21:59, BALATON Zoltan wrote:
On Tue, 28 Oct 2025, Philippe Mathieu-Daudé wrote:
On 27/10/25 20:47, BALATON Zoltan wrote:
On Mon, 27 Oct 2025, Philippe Mathieu-Daudé wrote:
On 25/10/25 01:31, BALATON Zoltan wrote:
These memory windows are a result of the address decoding in the
Articia S north bridge so better model it there and not in board code.
Suggested-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: BALATON Zoltan <[email protected]>
---
hw/pci-host/articia.c | 15 ++++++++++++++-
hw/ppc/amigaone.c | 28 +++++-----------------------
hw/ppc/pegasos2.c | 13 -------------
3 files changed, 19 insertions(+), 37 deletions(-)
@@ -169,6 +174,7 @@ static void articia_realize(DeviceState *dev, Error
**errp)
{
ArticiaState *s = ARTICIA(dev);
PCIHostState *h = PCI_HOST_BRIDGE(dev);
+ MemoryRegion *mr;
PCIDevice *pdev;
bitbang_i2c_init(&s->smbus, i2c_init_bus(dev, "smbus"));
@@ -180,6 +186,14 @@ static void articia_realize(DeviceState *dev,
Error **errp)
memory_region_init_io(&s->reg, OBJECT(s), &articia_reg_ops, s,
TYPE_ARTICIA, 0x1000000);
memory_region_add_subregion_overlap(&s->reg, 0, &s->io, 1);
+ mr = g_new(MemoryRegion, 1);
Won't Coverity or other analysis tools complain about the leak?
(this is why we usually keep a reference in the device state, here
ArticiaState). Otherwise:
According to https://www.qemu.org/docs/master/devel/ memory.html#region-
lifecycle
there should be no leak and keeping a reference should not be necessary
as the lifetime is managed by attaching it to the owner object so no need
to keep a reference when it's not needed otherwise. Not littering the
state struct with unneded references makes it easier to comprehend so I'd
only keep things there that are necessary.
IIUC this doc is about what happens within the allocated MemoryRegion,
regardless of where it is allocated.
That doc explicitely says:
"Destruction of a memory region happens automatically when the owner object
dies. When there are multiple memory regions under the same owner object,
the memory API will guarantee all memory regions will be properly detached
and finalized one by one. The order in which memory regions will be
finalized is not guaranteed."
Destruction in this context does not imply freeing the storage.
The documentation describes destruction in QOM. QOM performs the following
steps during destruction:
1. Delete properties
2. Call finalization callbacks
3. Free the storage
However, 3 will not happen in this case since you allocate the storage by
yourself and it is not managed by QOM.
Please also note that the documentation also says:
If however the memory region is part of a dynamically allocated data
structure, you should free the memory region in the instance_finalize
callback. For an example see VFIOMSIXInfo and VFIOQuirk in
hw/vfio/pci.c.
So the problem is probably using g_new() to allocate it. Maybe this should
be object_new() instead? I was trying to figure out how this should work
but not sure I understand everything. It looks like as long as the mr has
a name, memory_region_init() will add the mr as a child property to the
owner and unref it so the reference will be passed to the owner which will
own this mr after that. On destructing the owner it will delete all its
properties which should dereference the memory region so it would be freed
then if it had a free function set but it seems allocating with g_new and
init-ing the region with memory_region_init() won't set the free function.
Only way to set that seems to be object_new() but that also inits the
object so maybe using it would double init the mr or add an extra
reference so that may also not work. The extra ref could be solved by
unref'ing after memory_region_init() but double init seems to be
unnecessary. Maybe we need a memory_region_new_* set of functions or
simpler than that an object_alloc() that allocates the object without
init it that could be used in this case when init is done by other
function like memory_region_init in this case?
(and these pci-host objects are created once at machine init and never die
so the question seems quite theoretical). I'd like to keep object state
simple and not keep around references in it that nothing uses and should be
managed automatically. I'd only add fields to the state struct that other
methods need.
It is indeed theoretical. That said, I prefer the memory region to be
embedded into the device state struct as it will clarify that the lifetime of
the memory region is bound to the device.
But that way a lot of otherwise not needed fields would make the state
struct more crowded and harder to see what's actually used there. Maybe
this could be remedied by grouping these at the end below a comment but if
ref counting worked as the docs state it this should not be necessary.
Before my cleanup the state strcut in raven.c looked like this:
struct PRePPCIState {
PCIHostState parent_obj;
OrIRQState *or_irq;
qemu_irq pci_irqs[PCI_NUM_PINS];
PCIBus pci_bus;
AddressSpace pci_io_as;
MemoryRegion pci_io;
MemoryRegion pci_io_non_contiguous;
MemoryRegion pci_memory;
MemoryRegion pci_intack;
MemoryRegion bm;
MemoryRegion bm_ram_alias;
MemoryRegion bm_pci_memory_alias;
AddressSpace bm_as;
RavenPCIState pci_dev;
int contiguous_map;
};
which would become this after this series:
struct PREPPCIState {
PCIHostState parent_obj;
qemu_irq irq;
MemoryRegion pci_io;
MemoryRegion pci_discontiguous_io;
MemoryRegion pci_memory;
MemoryRegion pci_intack;
AddressSpace bm_as;
};
if we don't have to keep regions we don't use after realize so those can
be managed by QOM which is much more readable and comprehensible to me.
(Unrelated question but I'm still not sure what the bm_as is for. This
seems to be present in some pci-hosts and may be needed for bus master
cards but I just carried it over to my devices as a cargo cult without
really getting why is it needed and why is it needed here and not in
PCIHostState. Is there any explanation on that somewhere?)
Regards,
BALATON Zoltan