All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] m68k: virt: fix reboot
@ 2022-01-15 20:37 Laurent Vivier
  2022-01-15 20:37 ` [PATCH 1/3] exec/memory: Extract address_space_set() from dma_memory_set() Laurent Vivier
                   ` (3 more replies)
  0 siblings, 4 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é

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(-)

-- 
2.34.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [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

* [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 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

* 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

end of thread, other threads:[~2022-01-20  8:51 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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-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
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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.