* [PATCH 1/3] exec/memory: Extract address_space_set() from dma_memory_set()
2022-01-15 20:37 [PATCH 0/3] m68k: virt: fix reboot Laurent Vivier
@ 2022-01-15 20:37 ` Laurent Vivier
2022-01-17 8:23 ` David Hildenbrand
2022-01-17 8:57 ` Peter Xu
2022-01-15 20:37 ` [PATCH 2/3] hw/elf_ops: clear uninitialized segment space Laurent Vivier
` (2 subsequent siblings)
3 siblings, 2 replies; 7+ messages in thread
From: Laurent Vivier @ 2022-01-15 20:37 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Richard Henderson, Laurent Vivier, Peter Xu,
Philippe Mathieu-Daudé,
Paolo Bonzini, Philippe Mathieu-Daudé,
Stefano Garzarella
From: Philippe Mathieu-Daudé <philmd@redhat.com>
dma_memory_set() does a DMA barrier, set the address space with
a constant value. The constant value filling code is not specific
to DMA and can be used for AddressSpace. Extract it as a new
helper: address_space_set().
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
[lv: rebase]
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
include/exec/memory.h | 16 ++++++++++++++++
softmmu/dma-helpers.c | 15 +--------------
softmmu/physmem.c | 19 +++++++++++++++++++
3 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 20f1b27377ea..c00c50943107 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -2906,6 +2906,22 @@ address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
}
}
+/**
+ * address_space_set: Fill address space with a constant byte.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @c: constant byte to fill the memory
+ * @len: the number of bytes to fill with the constant byte
+ * @attrs: memory transaction attributes
+ */
+MemTxResult address_space_set(AddressSpace *as, hwaddr addr,
+ uint8_t c, hwaddr len, MemTxAttrs attrs);
+
#ifdef NEED_CPU_H
/* enum device_endian to MemOp. */
static inline MemOp devend_memop(enum device_endian end)
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index b0be1564797f..c2028b658582 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -23,20 +23,7 @@ MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
{
dma_barrier(as, DMA_DIRECTION_FROM_DEVICE);
-#define FILLBUF_SIZE 512
- uint8_t fillbuf[FILLBUF_SIZE];
- int l;
- MemTxResult error = MEMTX_OK;
-
- memset(fillbuf, c, FILLBUF_SIZE);
- while (len > 0) {
- l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE;
- error |= address_space_write(as, addr, attrs, fillbuf, l);
- len -= l;
- addr += l;
- }
-
- return error;
+ return address_space_set(as, addr, c, len, attrs);
}
void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint,
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 3524c04c2a16..dddf70edf5d2 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -2927,6 +2927,25 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
}
}
+MemTxResult address_space_set(AddressSpace *as, hwaddr addr,
+ uint8_t c, hwaddr len, MemTxAttrs attrs)
+{
+#define FILLBUF_SIZE 512
+ uint8_t fillbuf[FILLBUF_SIZE];
+ int l;
+ MemTxResult error = MEMTX_OK;
+
+ memset(fillbuf, c, FILLBUF_SIZE);
+ while (len > 0) {
+ l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE;
+ error |= address_space_write(as, addr, attrs, fillbuf, l);
+ len -= l;
+ addr += l;
+ }
+
+ return error;
+}
+
void cpu_physical_memory_rw(hwaddr addr, void *buf,
hwaddr len, bool is_write)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] exec/memory: Extract address_space_set() from dma_memory_set()
2022-01-15 20:37 ` [PATCH 1/3] exec/memory: Extract address_space_set() from dma_memory_set() Laurent Vivier
@ 2022-01-17 8:23 ` David Hildenbrand
2022-01-17 8:57 ` Peter Xu
1 sibling, 0 replies; 7+ messages in thread
From: David Hildenbrand @ 2022-01-17 8:23 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel
Cc: Richard Henderson, Philippe Mathieu-Daudé,
Peter Xu, Paolo Bonzini, Philippe Mathieu-Daudé,
Stefano Garzarella
On 15.01.22 21:37, Laurent Vivier wrote:
> From: Philippe Mathieu-Daudé <philmd@redhat.com>
>
> dma_memory_set() does a DMA barrier, set the address space with
> a constant value. The constant value filling code is not specific
> to DMA and can be used for AddressSpace. Extract it as a new
> helper: address_space_set().
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> [lv: rebase]
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> include/exec/memory.h | 16 ++++++++++++++++
> softmmu/dma-helpers.c | 15 +--------------
> softmmu/physmem.c | 19 +++++++++++++++++++
> 3 files changed, 36 insertions(+), 14 deletions(-)
>
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index 20f1b27377ea..c00c50943107 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -2906,6 +2906,22 @@ address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
> }
> }
>
> +/**
> + * address_space_set: Fill address space with a constant byte.
nit: Fill selected part of an address space with a constant byte.
:)
Reviewed-by: David Hildenbrand <david@redhat.com>
--
Thanks,
David / dhildenb
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] exec/memory: Extract address_space_set() from dma_memory_set()
2022-01-15 20:37 ` [PATCH 1/3] exec/memory: Extract address_space_set() from dma_memory_set() Laurent Vivier
2022-01-17 8:23 ` David Hildenbrand
@ 2022-01-17 8:57 ` Peter Xu
1 sibling, 0 replies; 7+ messages in thread
From: Peter Xu @ 2022-01-17 8:57 UTC (permalink / raw)
To: Laurent Vivier
Cc: David Hildenbrand, Richard Henderson, Philippe Mathieu-Daudé,
qemu-devel, Paolo Bonzini, Philippe Mathieu-Daudé,
Stefano Garzarella
On Sat, Jan 15, 2022 at 09:37:23PM +0100, Laurent Vivier wrote:
> From: Philippe Mathieu-Daudé <philmd@redhat.com>
>
> dma_memory_set() does a DMA barrier, set the address space with
> a constant value. The constant value filling code is not specific
> to DMA and can be used for AddressSpace. Extract it as a new
> helper: address_space_set().
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> [lv: rebase]
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Peter Xu <peterx@redhat.com>
--
Peter Xu
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/3] hw/elf_ops: clear uninitialized segment space
2022-01-15 20:37 [PATCH 0/3] m68k: virt: fix reboot Laurent Vivier
2022-01-15 20:37 ` [PATCH 1/3] exec/memory: Extract address_space_set() from dma_memory_set() Laurent Vivier
@ 2022-01-15 20:37 ` Laurent Vivier
2022-01-15 20:37 ` [PATCH 3/3] m68k: virt: correctly set the initial PC Laurent Vivier
2022-01-20 8:11 ` [PATCH 0/3] m68k: virt: fix reboot Laurent Vivier
3 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2022-01-15 20:37 UTC (permalink / raw)
To: qemu-devel
Cc: David Hildenbrand, Richard Henderson, Laurent Vivier, Peter Xu,
Philippe Mathieu-Daudé,
Paolo Bonzini, Philippe Mathieu-Daudé,
Stefano Garzarella
When the mem_size of the segment is bigger than the file_size,
and if this space doesn't overlap another segment, it needs
to be cleared.
This bug is very similar to the one we had for linux-user,
22d113b52f41 ("linux-user: Fix loading of BSS segments"),
where .bss section is encoded as an extension of the the data
one by setting the segment p_memsz > p_filesz.
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
[PMD: Use recently added address_space_set()]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
include/hw/elf_ops.h | 13 +++++++++++++
hw/core/loader.c | 4 ++++
2 files changed, 17 insertions(+)
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index 995de8495c27..7c3b1d0f6cc5 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -555,6 +555,19 @@ static ssize_t glue(load_elf, SZ)(const char *name, int fd,
if (res != MEMTX_OK) {
goto fail;
}
+ /*
+ * We need to zero'ify the space that is not copied
+ * from file
+ */
+ if (file_size < mem_size) {
+ res = address_space_set(as ? as : &address_space_memory,
+ addr + file_size, 0,
+ mem_size - file_size,
+ MEMTXATTRS_UNSPECIFIED);
+ if (res != MEMTX_OK) {
+ goto fail;
+ }
+ }
}
}
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 052a0fd7198b..19edb928e999 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -1164,9 +1164,13 @@ static void rom_reset(void *unused)
if (rom->mr) {
void *host = memory_region_get_ram_ptr(rom->mr);
memcpy(host, rom->data, rom->datasize);
+ memset(host + rom->datasize, 0, rom->romsize - rom->datasize);
} else {
address_space_write_rom(rom->as, rom->addr, MEMTXATTRS_UNSPECIFIED,
rom->data, rom->datasize);
+ address_space_set(rom->as, rom->addr + rom->datasize, 0,
+ rom->romsize - rom->datasize,
+ MEMTXATTRS_UNSPECIFIED);
}
if (rom->isrom) {
/* rom needs to be written only once */
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] m68k: virt: correctly set the initial PC
2022-01-15 20:37 [PATCH 0/3] m68k: virt: fix reboot Laurent Vivier
2022-01-15 20:37 ` [PATCH 1/3] exec/memory: Extract address_space_set() from dma_memory_set() Laurent Vivier
2022-01-15 20:37 ` [PATCH 2/3] hw/elf_ops: clear uninitialized segment space Laurent Vivier
@ 2022-01-15 20:37 ` Laurent Vivier
2022-01-20 8:11 ` [PATCH 0/3] m68k: virt: fix reboot Laurent Vivier
3 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2022-01-15 20:37 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, David Hildenbrand, Laurent Vivier, Peter Xu,
Philippe Mathieu-Daudé
According to QEMU parameter, set initial PC to the entry of
the loaded kernel.
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
hw/m68k/virt.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index 78e926a55457..bbaf630bbf20 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -85,14 +85,21 @@
#define VIRT_VIRTIO_MMIO_BASE 0xff010000 /* MMIO: 0xff010000 - 0xff01ffff */
#define VIRT_VIRTIO_IRQ_BASE PIC_IRQ(2, 1) /* PIC: 2, 3, 4, 5, IRQ: ALL */
+typedef struct {
+ M68kCPU *cpu;
+ hwaddr initial_pc;
+ hwaddr initial_stack;
+} ResetInfo;
+
static void main_cpu_reset(void *opaque)
{
- M68kCPU *cpu = opaque;
+ ResetInfo *reset_info = opaque;
+ M68kCPU *cpu = reset_info->cpu;
CPUState *cs = CPU(cpu);
cpu_reset(cs);
- cpu->env.aregs[7] = ldl_phys(cs->as, 0);
- cpu->env.pc = ldl_phys(cs->as, 4);
+ cpu->env.aregs[7] = reset_info->initial_stack;
+ cpu->env.pc = reset_info->initial_pc;
}
static void virt_init(MachineState *machine)
@@ -113,6 +120,7 @@ static void virt_init(MachineState *machine)
SysBusDevice *sysbus;
hwaddr io_base;
int i;
+ ResetInfo *reset_info;
if (ram_size > 3399672 * KiB) {
/*
@@ -124,9 +132,13 @@ static void virt_init(MachineState *machine)
exit(1);
}
+ reset_info = g_malloc0(sizeof(ResetInfo));
+
/* init CPUs */
cpu = M68K_CPU(cpu_create(machine->cpu_type));
- qemu_register_reset(main_cpu_reset, cpu);
+
+ reset_info->cpu = cpu;
+ qemu_register_reset(main_cpu_reset, reset_info);
/* RAM */
memory_region_add_subregion(get_system_memory(), 0, machine->ram);
@@ -206,7 +218,7 @@ static void virt_init(MachineState *machine)
error_report("could not load kernel '%s'", kernel_filename);
exit(1);
}
- stl_phys(cs->as, 4, elf_entry); /* reset initial PC */
+ reset_info->initial_pc = elf_entry;
parameters_base = (high + 1) & ~1;
BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT);
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] m68k: virt: fix reboot
2022-01-15 20:37 [PATCH 0/3] m68k: virt: fix reboot Laurent Vivier
` (2 preceding siblings ...)
2022-01-15 20:37 ` [PATCH 3/3] m68k: virt: correctly set the initial PC Laurent Vivier
@ 2022-01-20 8:11 ` Laurent Vivier
3 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2022-01-20 8:11 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Philippe Mathieu-Daudé, Peter Xu, David Hildenbrand
Le 15/01/2022 à 21:37, Laurent Vivier a écrit :
> This series fixes the reboot of the virt-m68k machine
> by correctly initializing the start address and fixing
> the ELF kernel image.
>
> The two first patches were already sent last year and
> never merged:
>
> https://patchwork.kernel.org/project/qemu-devel/cover/20210429141326.69245-1-laurent@vivier.eu/
>
> Thanks,
> Laurent
>
> Laurent Vivier (2):
> hw/elf_ops: clear uninitialized segment space
> m68k: virt: correctly set the initial PC
>
> Philippe Mathieu-Daudé (1):
> exec/memory: Extract address_space_set() from dma_memory_set()
>
> include/exec/memory.h | 16 ++++++++++++++++
> include/hw/elf_ops.h | 13 +++++++++++++
> hw/core/loader.c | 4 ++++
> hw/m68k/virt.c | 22 +++++++++++++++++-----
> softmmu/dma-helpers.c | 15 +--------------
> softmmu/physmem.c | 19 +++++++++++++++++++
> 6 files changed, 70 insertions(+), 19 deletions(-)
>
Applied to my m68k-for-7.0 branch
Thanks,
Laurent
^ permalink raw reply [flat|nested] 7+ messages in thread