All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer
@ 2021-10-20 14:02 Paolo Bonzini
  2021-10-20 14:02 ` [PATCH 1/3] target/i386: move linuxboot_dma_enabled to X86MachineState Paolo Bonzini
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Paolo Bonzini @ 2021-10-20 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: adam, marcus.haehnel

An updated version of the patch at
https://patchew.org/QEMU/YWM6jboU9fUib6Iy@os.inf.tu-dresden.de/,
which includes the necessary glue for compatibility with older
machine types.  When fw_cfg DMA is disabled, the existing ROM
is used instead.

Marcus Hähnel (1):
  optionrom: add a DMA-enabled multiboot ROM

Paolo Bonzini (2):
  target/i386: move linuxboot_dma_enabled to X86MachineState
  target/i386: use DMA-enabled multiboot ROM for new-enough QEMU machine
    types

 hw/i386/microvm.c                 |   5 ++-
 hw/i386/multiboot.c               |  10 ++++-
 hw/i386/multiboot.h               |   4 +-
 hw/i386/pc.c                      |   8 ++--
 hw/i386/pc_piix.c                 |   3 +-
 hw/i386/pc_q35.c                  |   3 +-
 hw/i386/x86.c                     |   7 ++--
 include/hw/i386/pc.h              |   3 --
 include/hw/i386/x86.h             |   5 ++-
 pc-bios/meson.build               |   1 +
 pc-bios/multiboot_dma.bin         | Bin 0 -> 1024 bytes
 pc-bios/optionrom/Makefile        |   4 +-
 pc-bios/optionrom/multiboot.S     |   4 +-
 pc-bios/optionrom/multiboot_dma.S |   2 +
 pc-bios/optionrom/optionrom.h     |  66 ++++++++++++++++++++++++++++++
 15 files changed, 102 insertions(+), 23 deletions(-)
 create mode 100644 pc-bios/multiboot_dma.bin
 create mode 100644 pc-bios/optionrom/multiboot_dma.S

-- 
2.31.1



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

* [PATCH 1/3] target/i386: move linuxboot_dma_enabled to X86MachineState
  2021-10-20 14:02 [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer Paolo Bonzini
@ 2021-10-20 14:02 ` Paolo Bonzini
  2021-10-20 19:13   ` Philippe Mathieu-Daudé
  2021-10-20 14:02 ` [PATCH 2/3] optionrom: add a DMA-enabled multiboot ROM Paolo Bonzini
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Paolo Bonzini @ 2021-10-20 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: adam, marcus.haehnel

This removes a parameter from x86_load_linux, and will avoid code
duplication between the linux and multiboot cases once multiboot
starts to support DMA.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/microvm.c     | 5 ++++-
 hw/i386/pc.c          | 5 ++---
 hw/i386/pc_piix.c     | 3 ++-
 hw/i386/pc_q35.c      | 3 ++-
 hw/i386/x86.c         | 5 +++--
 include/hw/i386/pc.h  | 3 ---
 include/hw/i386/x86.h | 5 +++--
 7 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index f257ec5a0b..837bafb64a 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -331,7 +331,7 @@ static void microvm_memory_init(MicrovmMachineState *mms)
     rom_set_fw(fw_cfg);
 
     if (machine->kernel_filename != NULL) {
-        x86_load_linux(x86ms, fw_cfg, 0, true, true);
+        x86_load_linux(x86ms, fw_cfg, 0, true);
     }
 
     if (mms->option_roms) {
@@ -667,6 +667,7 @@ static void microvm_machine_initfn(Object *obj)
 
 static void microvm_class_init(ObjectClass *oc, void *data)
 {
+    X86MachineClass *x86mc = X86_MACHINE_CLASS(oc);
     MachineClass *mc = MACHINE_CLASS(oc);
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
 
@@ -697,6 +698,8 @@ static void microvm_class_init(ObjectClass *oc, void *data)
     hc->unplug_request = microvm_device_unplug_request_cb;
     hc->unplug = microvm_device_unplug_cb;
 
+    x86mc->fwcfg_dma_enabled = true;
+
     object_class_property_add(oc, MICROVM_MACHINE_PIC, "OnOffAuto",
                               microvm_machine_get_pic,
                               microvm_machine_set_pic,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 86223acfd3..d203db7845 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -775,7 +775,7 @@ void xen_load_linux(PCMachineState *pcms)
     rom_set_fw(fw_cfg);
 
     x86_load_linux(x86ms, fw_cfg, pcmc->acpi_data_size,
-                   pcmc->pvh_enabled, pcmc->linuxboot_dma_enabled);
+                   pcmc->pvh_enabled);
     for (i = 0; i < nb_option_roms; i++) {
         assert(!strcmp(option_rom[i].name, "linuxboot.bin") ||
                !strcmp(option_rom[i].name, "linuxboot_dma.bin") ||
@@ -927,7 +927,7 @@ void pc_memory_init(PCMachineState *pcms,
 
     if (linux_boot) {
         x86_load_linux(x86ms, fw_cfg, pcmc->acpi_data_size,
-                       pcmc->pvh_enabled, pcmc->linuxboot_dma_enabled);
+                       pcmc->pvh_enabled);
     }
 
     for (i = 0; i < nb_option_roms; i++) {
@@ -1664,7 +1664,6 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
     /* BIOS ACPI tables: 128K. Other BIOS datastructures: less than 4K reported
      * to be used at the moment, 32K should be enough for a while.  */
     pcmc->acpi_data_size = 0x20000 + 0x8000;
-    pcmc->linuxboot_dma_enabled = true;
     pcmc->pvh_enabled = true;
     pcmc->kvmclock_create_always = true;
     assert(!mc->get_hotplug_handler);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 6ad0d763c5..223dd3e05d 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -620,11 +620,12 @@ DEFINE_I440FX_MACHINE(v2_7, "pc-i440fx-2.7", NULL,
 
 static void pc_i440fx_2_6_machine_options(MachineClass *m)
 {
+    X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
     PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
 
     pc_i440fx_2_7_machine_options(m);
     pcmc->legacy_cpu_hotplug = true;
-    pcmc->linuxboot_dma_enabled = false;
+    x86mc->fwcfg_dma_enabled = false;
     compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
     compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
 }
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index fcc6e4eb2b..797e09500b 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -573,11 +573,12 @@ DEFINE_Q35_MACHINE(v2_7, "pc-q35-2.7", NULL,
 
 static void pc_q35_2_6_machine_options(MachineClass *m)
 {
+    X86MachineClass *x86mc = X86_MACHINE_CLASS(m);
     PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
 
     pc_q35_2_7_machine_options(m);
     pcmc->legacy_cpu_hotplug = true;
-    pcmc->linuxboot_dma_enabled = false;
+    x86mc->fwcfg_dma_enabled = false;
     compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
     compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
 }
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 76de7e2265..a34498fe16 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -764,9 +764,9 @@ static bool load_elfboot(const char *kernel_filename,
 void x86_load_linux(X86MachineState *x86ms,
                     FWCfgState *fw_cfg,
                     int acpi_data_size,
-                    bool pvh_enabled,
-                    bool linuxboot_dma_enabled)
+                    bool pvh_enabled)
 {
+    bool linuxboot_dma_enabled = X86_MACHINE_GET_CLASS(x86ms)->fwcfg_dma_enabled;
     uint16_t protocol;
     int setup_size, kernel_size, cmdline_size;
     int dtb_size, setup_data_offset;
@@ -1332,6 +1332,7 @@ static void x86_machine_class_init(ObjectClass *oc, void *data)
     mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids;
     x86mc->compat_apic_id_mode = false;
     x86mc->save_tsc_khz = true;
+    x86mc->fwcfg_dma_enabled = true;
     nc->nmi_monitor_handler = x86_nmi;
 
     object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto",
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 11426e26dc..9162aded21 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -116,9 +116,6 @@ struct PCMachineClass {
     /* generate legacy CPU hotplug AML */
     bool legacy_cpu_hotplug;
 
-    /* use DMA capable linuxboot option rom */
-    bool linuxboot_dma_enabled;
-
     /* use PVH to load kernels that support this feature */
     bool pvh_enabled;
 
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index 23267a3674..bb1cfb8896 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -38,6 +38,8 @@ struct X86MachineClass {
     bool save_tsc_khz;
     /* Enables contiguous-apic-ID mode */
     bool compat_apic_id_mode;
+    /* use DMA capable linuxboot option rom */
+    bool fwcfg_dma_enabled;
 };
 
 struct X86MachineState {
@@ -120,8 +122,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
 void x86_load_linux(X86MachineState *x86ms,
                     FWCfgState *fw_cfg,
                     int acpi_data_size,
-                    bool pvh_enabled,
-                    bool linuxboot_dma_enabled);
+                    bool pvh_enabled);
 
 bool x86_machine_is_smm_enabled(const X86MachineState *x86ms);
 bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms);
-- 
2.31.1




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

* [PATCH 2/3] optionrom: add a DMA-enabled multiboot ROM
  2021-10-20 14:02 [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer Paolo Bonzini
  2021-10-20 14:02 ` [PATCH 1/3] target/i386: move linuxboot_dma_enabled to X86MachineState Paolo Bonzini
@ 2021-10-20 14:02 ` Paolo Bonzini
  2021-10-20 22:08   ` Philippe Mathieu-Daudé
  2021-10-20 14:02 ` [PATCH 3/3] target/i386: use DMA-enabled multiboot ROM for new-enough QEMU machine types Paolo Bonzini
  2021-10-21  7:23 ` [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer Stefano Garzarella
  3 siblings, 1 reply; 8+ messages in thread
From: Paolo Bonzini @ 2021-10-20 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: adam, marcus.haehnel

From: Marcus Hähnel <marcus.haehnel@kernkonzept.com>

Add a new option rom for the multiboot loader, using DMA transfers to copy
data instead of "rep insb".

This significantly lowers QEMU's startup latency by a factor of about 40,
for example, going from 30sec to 0.8sec when loading modules of 120MB
in size.

Signed-off-by: Marcus Hähnel <marcus.haehnel@kernkonzept.com>
Signed-off-by: Adam Lackorzynski <adam@l4re.org>
[Modified to keep the non-DMA code depending on #ifdef USE_FW_CFG_DMA;
 do not write below stack. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 pc-bios/meson.build               |   1 +
 pc-bios/multiboot_dma.bin         | Bin 0 -> 1024 bytes
 pc-bios/optionrom/Makefile        |   4 +-
 pc-bios/optionrom/multiboot.S     |   4 +-
 pc-bios/optionrom/multiboot_dma.S |   2 +
 pc-bios/optionrom/optionrom.h     |  66 ++++++++++++++++++++++++++++++
 6 files changed, 72 insertions(+), 5 deletions(-)
 create mode 100644 pc-bios/multiboot_dma.bin
 create mode 100644 pc-bios/optionrom/multiboot_dma.S

diff --git a/pc-bios/meson.build b/pc-bios/meson.build
index a44c9bc127..b40ff3f2bd 100644
--- a/pc-bios/meson.build
+++ b/pc-bios/meson.build
@@ -63,6 +63,7 @@ blobs = files(
   'petalogix-s3adsp1800.dtb',
   'petalogix-ml605.dtb',
   'multiboot.bin',
+  'multiboot_dma.bin',
   'linuxboot.bin',
   'linuxboot_dma.bin',
   'kvmvapic.bin',
diff --git a/pc-bios/multiboot_dma.bin b/pc-bios/multiboot_dma.bin
new file mode 100644
index 0000000000000000000000000000000000000000..c0e2c3102a3358207c61d3ae113524fb6007abc3
GIT binary patch
literal 1024
zcmd^-v1=1i9LIlmUTlcNU1}{N5`u&{DAHSmq6iKdix;GHRxaNnR0A<Lc978Fk#IvN
zaS+5wQE+fL&*iQWa#czc94ZyL>R{3q;@~8~^LMo;4s!p158nI!-tWur_ul*P<{!&%
z=%3>xm5f`4Bq!!)`Rkwf;(oFd*qcAb=mhXX1)X>Bw-tylkUpR_ETXkH1AnO4L$nJ|
zWJui_M1kmKmTID)P`mI^=HM`~{VB1t1l_Ye=Lor4X5{8Gd)zzw_o4<6zLQJ!dr<pW
z;7%~ysSHL?*HHx*O%k}?fCyRL<7_RWt(4;Aqn}X}S>MolrKNZG2Z|kTOyaJIhYFc^
zFhhuQ9`r5fQLCrm#T4^_QylQ>8kgs;ZX9bIEiXb`8AIxu;?h~d%9izBkKht%WM1G*
z^E{W9(OT9dt5in2qF}|dPH>dL>{=sV#-U1<quUb@YkIW%niI?8-7fCz#695e<V=WZ
zrVCY?W~`3Hw@^=cHALr#9F2GOTYJ;??9d*-Vbsi+;lz|<$jMX#;lr6ov3qKNLH7(W
z+>yFoWnOtw14D$&k*SUtsT%wS`ki@#&rUrnmtuDv`PtJm(Kg?H$Pdc0CL@YCy4R<D
pT|LnIbg(BnP0#tqRx5M!bkkaD-nd?`H;YU4Yi6yHwD{k({tHC8FAx9#

literal 0
HcmV?d00001

diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile
index 3482508a86..5d55d25acc 100644
--- a/pc-bios/optionrom/Makefile
+++ b/pc-bios/optionrom/Makefile
@@ -2,7 +2,7 @@ include config.mak
 SRC_DIR := $(TOPSRC_DIR)/pc-bios/optionrom
 VPATH = $(SRC_DIR)
 
-all: multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin pvh.bin
+all: multiboot.bin multiboot_dma.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin pvh.bin
 # Dummy command so that make thinks it has done something
 	@true
 
@@ -41,8 +41,6 @@ override CFLAGS += $(call cc-option, $(Wa)-32)
 LD_I386_EMULATION ?= elf_i386
 override LDFLAGS = -m $(LD_I386_EMULATION) -T $(SRC_DIR)/flat.lds
 
-all: multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin pvh.bin
-
 pvh.img: pvh.o pvh_main.o
 
 %.o: %.S
diff --git a/pc-bios/optionrom/multiboot.S b/pc-bios/optionrom/multiboot.S
index b7efe4de34..181a4b03a3 100644
--- a/pc-bios/optionrom/multiboot.S
+++ b/pc-bios/optionrom/multiboot.S
@@ -68,7 +68,7 @@ run_multiboot:
 	mov		%eax, %es
 
 	/* Read the bootinfo struct into RAM */
-	read_fw_blob(FW_CFG_INITRD)
+	read_fw_blob_dma(FW_CFG_INITRD)
 
 	/* FS = bootinfo_struct */
 	read_fw		FW_CFG_INITRD_ADDR
@@ -188,7 +188,7 @@ prot_mode:
 	movl		%eax, %gs
 
 	/* Read the kernel and modules into RAM */
-	read_fw_blob(FW_CFG_KERNEL)
+	read_fw_blob_dma(FW_CFG_KERNEL)
 
 	/* Jump off to the kernel */
 	read_fw		FW_CFG_KERNEL_ENTRY
diff --git a/pc-bios/optionrom/multiboot_dma.S b/pc-bios/optionrom/multiboot_dma.S
new file mode 100644
index 0000000000..d809af3e23
--- /dev/null
+++ b/pc-bios/optionrom/multiboot_dma.S
@@ -0,0 +1,2 @@
+#define USE_FW_CFG_DMA 1
+#include "multiboot.S"
diff --git a/pc-bios/optionrom/optionrom.h b/pc-bios/optionrom/optionrom.h
index a2b612f1a7..8d74c0ddf3 100644
--- a/pc-bios/optionrom/optionrom.h
+++ b/pc-bios/optionrom/optionrom.h
@@ -37,6 +37,17 @@
 #define BIOS_CFG_IOPORT_CFG	0x510
 #define BIOS_CFG_IOPORT_DATA	0x511
 
+#define FW_CFG_DMA_CTL_ERROR   0x01
+#define FW_CFG_DMA_CTL_READ    0x02
+#define FW_CFG_DMA_CTL_SKIP    0x04
+#define FW_CFG_DMA_CTL_SELECT  0x08
+#define FW_CFG_DMA_CTL_WRITE   0x10
+
+#define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* "QEMU CFG" */
+
+#define BIOS_CFG_DMA_ADDR_HIGH  0x514
+#define BIOS_CFG_DMA_ADDR_LOW   0x518
+
 /* Break the translation block flow so -d cpu shows us values */
 #define DEBUG_HERE \
 	jmp		1f;				\
@@ -62,6 +73,61 @@
 	bswap		%eax
 .endm
 
+
+/*
+ * Read data from the fw_cfg device using DMA.
+ * Clobbers:	%edx, %eax, ADDR, SIZE, memory[%esp-16] to memory[%esp]
+ */
+.macro read_fw_dma VAR, SIZE, ADDR
+        /* Address */
+	bswapl		\ADDR
+	pushl		\ADDR
+
+	/* We only support 32 bit target addresses */
+	xorl		%eax, %eax
+	pushl		%eax
+	mov		$BIOS_CFG_DMA_ADDR_HIGH, %dx
+	outl		%eax, (%dx)
+
+	/* Size */
+	bswapl		\SIZE
+	pushl		\SIZE
+
+        /* Control */
+	movl		$(\VAR << 16) | (FW_CFG_DMA_CTL_READ | FW_CFG_DMA_CTL_SELECT), %eax
+	bswapl		%eax
+	pushl		%eax
+
+	movl		%esp, %eax /* Address of the struct we generated */
+	bswapl		%eax
+	mov		$BIOS_CFG_DMA_ADDR_LOW, %dx
+	outl		%eax, (%dx) /* Initiate DMA */
+
+1:  mov		(%esp), %eax /* Wait for completion */
+	bswapl		%eax
+	testl		$~FW_CFG_DMA_CTL_ERROR, %eax
+	jnz		1b
+       addl            $16, %esp
+.endm
+
+
+/*
+ * Read a blob from the fw_cfg device using DMA
+ * Requires _ADDR, _SIZE and _DATA values for the parameter.
+ *
+ * Clobbers:	%eax, %edx, %es, %ecx, %edi and adresses %esp-20 to %esp
+ */
+#ifdef USE_FW_CFG_DMA
+#define read_fw_blob_dma(var) \
+	read_fw		var ## _SIZE; \
+	mov		%eax, %ecx; \
+	read_fw		var ## _ADDR; \
+	mov		%eax, %edi ;\
+	read_fw_dma	var ## _DATA, %ecx, %edi
+#else
+#define read_fw_blob_dma(var) read_fw_blob(var)
+#endif
+
 #define read_fw_blob_pre(var)				\
 	read_fw		var ## _SIZE;			\
 	mov		%eax, %ecx;			\
-- 
2.31.1




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

* [PATCH 3/3] target/i386: use DMA-enabled multiboot ROM for new-enough QEMU machine types
  2021-10-20 14:02 [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer Paolo Bonzini
  2021-10-20 14:02 ` [PATCH 1/3] target/i386: move linuxboot_dma_enabled to X86MachineState Paolo Bonzini
  2021-10-20 14:02 ` [PATCH 2/3] optionrom: add a DMA-enabled multiboot ROM Paolo Bonzini
@ 2021-10-20 14:02 ` Paolo Bonzini
  2021-10-20 19:19   ` Philippe Mathieu-Daudé
  2021-10-21  7:23 ` [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer Stefano Garzarella
  3 siblings, 1 reply; 8+ messages in thread
From: Paolo Bonzini @ 2021-10-20 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: adam, marcus.haehnel

As long as fw_cfg supports DMA, the new ROM can be used also on older
machine types because it has the same size as the existing one.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/multiboot.c | 10 ++++++++--
 hw/i386/multiboot.h |  4 +++-
 hw/i386/pc.c        |  3 ++-
 hw/i386/x86.c       |  2 +-
 4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
index 9e7d69d470..0a10089f14 100644
--- a/hw/i386/multiboot.c
+++ b/hw/i386/multiboot.c
@@ -143,7 +143,8 @@ static void mb_add_mod(MultibootState *s,
     s->mb_mods_count++;
 }
 
-int load_multiboot(FWCfgState *fw_cfg,
+int load_multiboot(X86MachineState *x86ms,
+                   FWCfgState *fw_cfg,
                    FILE *f,
                    const char *kernel_filename,
                    const char *initrd_filename,
@@ -151,6 +152,7 @@ int load_multiboot(FWCfgState *fw_cfg,
                    int kernel_file_size,
                    uint8_t *header)
 {
+    bool multiboot_dma_enabled = X86_MACHINE_GET_CLASS(x86ms)->fwcfg_dma_enabled;
     int i, is_multiboot = 0;
     uint32_t flags = 0;
     uint32_t mh_entry_addr;
@@ -401,7 +403,11 @@ int load_multiboot(FWCfgState *fw_cfg,
     fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, mb_bootinfo_data,
                      sizeof(bootinfo));
 
-    option_rom[nb_option_roms].name = "multiboot.bin";
+    if (multiboot_dma_enabled) {
+        option_rom[nb_option_roms].name = "multiboot_dma.bin";
+    } else {
+        option_rom[nb_option_roms].name = "multiboot.bin";
+    }
     option_rom[nb_option_roms].bootindex = 0;
     nb_option_roms++;
 
diff --git a/hw/i386/multiboot.h b/hw/i386/multiboot.h
index 60de309cd1..2b9182a8ea 100644
--- a/hw/i386/multiboot.h
+++ b/hw/i386/multiboot.h
@@ -2,8 +2,10 @@
 #define QEMU_MULTIBOOT_H
 
 #include "hw/nvram/fw_cfg.h"
+#include "hw/i386/x86.h"
 
-int load_multiboot(FWCfgState *fw_cfg,
+int load_multiboot(X86MachineState *x86ms,
+                   FWCfgState *fw_cfg,
                    FILE *f,
                    const char *kernel_filename,
                    const char *initrd_filename,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d203db7845..fcfb7f7139 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -780,7 +780,8 @@ void xen_load_linux(PCMachineState *pcms)
         assert(!strcmp(option_rom[i].name, "linuxboot.bin") ||
                !strcmp(option_rom[i].name, "linuxboot_dma.bin") ||
                !strcmp(option_rom[i].name, "pvh.bin") ||
-               !strcmp(option_rom[i].name, "multiboot.bin"));
+               !strcmp(option_rom[i].name, "multiboot.bin") ||
+               !strcmp(option_rom[i].name, "multiboot_dma.bin"));
         rom_add_option(option_rom[i].name, option_rom[i].bootindex);
     }
     x86ms->fw_cfg = fw_cfg;
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index a34498fe16..b84840a1bb 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -814,7 +814,7 @@ void x86_load_linux(X86MachineState *x86ms,
          * PVH), so we try multiboot first since we check the multiboot magic
          * header before to load it.
          */
-        if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename,
+        if (load_multiboot(x86ms, fw_cfg, f, kernel_filename, initrd_filename,
                            kernel_cmdline, kernel_size, header)) {
             return;
         }
-- 
2.31.1



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

* Re: [PATCH 1/3] target/i386: move linuxboot_dma_enabled to X86MachineState
  2021-10-20 14:02 ` [PATCH 1/3] target/i386: move linuxboot_dma_enabled to X86MachineState Paolo Bonzini
@ 2021-10-20 19:13   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-10-20 19:13 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: adam, marcus.haehnel

On 10/20/21 16:02, Paolo Bonzini wrote:
> This removes a parameter from x86_load_linux, and will avoid code
> duplication between the linux and multiboot cases once multiboot
> starts to support DMA.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/i386/microvm.c     | 5 ++++-
>  hw/i386/pc.c          | 5 ++---
>  hw/i386/pc_piix.c     | 3 ++-
>  hw/i386/pc_q35.c      | 3 ++-
>  hw/i386/x86.c         | 5 +++--
>  include/hw/i386/pc.h  | 3 ---
>  include/hw/i386/x86.h | 5 +++--
>  7 files changed, 16 insertions(+), 13 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>



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

* Re: [PATCH 3/3] target/i386: use DMA-enabled multiboot ROM for new-enough QEMU machine types
  2021-10-20 14:02 ` [PATCH 3/3] target/i386: use DMA-enabled multiboot ROM for new-enough QEMU machine types Paolo Bonzini
@ 2021-10-20 19:19   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-10-20 19:19 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: adam, marcus.haehnel

On 10/20/21 16:02, Paolo Bonzini wrote:
> As long as fw_cfg supports DMA, the new ROM can be used also on older
> machine types because it has the same size as the existing one.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/i386/multiboot.c | 10 ++++++++--
>  hw/i386/multiboot.h |  4 +++-
>  hw/i386/pc.c        |  3 ++-
>  hw/i386/x86.c       |  2 +-
>  4 files changed, 14 insertions(+), 5 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>



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

* Re: [PATCH 2/3] optionrom: add a DMA-enabled multiboot ROM
  2021-10-20 14:02 ` [PATCH 2/3] optionrom: add a DMA-enabled multiboot ROM Paolo Bonzini
@ 2021-10-20 22:08   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-10-20 22:08 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: adam, marcus.haehnel

On 10/20/21 16:02, Paolo Bonzini wrote:
> From: Marcus Hähnel <marcus.haehnel@kernkonzept.com>
> 
> Add a new option rom for the multiboot loader, using DMA transfers to copy
> data instead of "rep insb".
> 
> This significantly lowers QEMU's startup latency by a factor of about 40,
> for example, going from 30sec to 0.8sec when loading modules of 120MB
> in size.
> 
> Signed-off-by: Marcus Hähnel <marcus.haehnel@kernkonzept.com>
> Signed-off-by: Adam Lackorzynski <adam@l4re.org>
> [Modified to keep the non-DMA code depending on #ifdef USE_FW_CFG_DMA;
>  do not write below stack. - Paolo]
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  pc-bios/meson.build               |   1 +
>  pc-bios/multiboot_dma.bin         | Bin 0 -> 1024 bytes
>  pc-bios/optionrom/Makefile        |   4 +-
>  pc-bios/optionrom/multiboot.S     |   4 +-
>  pc-bios/optionrom/multiboot_dma.S |   2 +
>  pc-bios/optionrom/optionrom.h     |  66 ++++++++++++++++++++++++++++++
>  6 files changed, 72 insertions(+), 5 deletions(-)
>  create mode 100644 pc-bios/multiboot_dma.bin
>  create mode 100644 pc-bios/optionrom/multiboot_dma.S

> diff --git a/pc-bios/multiboot_dma.bin b/pc-bios/multiboot_dma.bin
> new file mode 100644
> index 0000000000000000000000000000000000000000..c0e2c3102a3358207c61d3ae113524fb6007abc3
> GIT binary patch
> literal 1024
> zcmd^-v1=1i9LIlmUTlcNU1}{N5`u&{DAHSmq6iKdix;GHRxaNnR0A<Lc978Fk#IvN
> zaS+5wQE+fL&*iQWa#czc94ZyL>R{3q;@~8~^LMo;4s!p158nI!-tWur_ul*P<{!&%
> z=%3>xm5f`4Bq!!)`Rkwf;(oFd*qcAb=mhXX1)X>Bw-tylkUpR_ETXkH1AnO4L$nJ|
> zWJui_M1kmKmTID)P`mI^=HM`~{VB1t1l_Ye=Lor4X5{8Gd)zzw_o4<6zLQJ!dr<pW
> z;7%~ysSHL?*HHx*O%k}?fCyRL<7_RWt(4;Aqn}X}S>MolrKNZG2Z|kTOyaJIhYFc^
> zFhhuQ9`r5fQLCrm#T4^_QylQ>8kgs;ZX9bIEiXb`8AIxu;?h~d%9izBkKht%WM1G*
> z^E{W9(OT9dt5in2qF}|dPH>dL>{=sV#-U1<quUb@YkIW%niI?8-7fCz#695e<V=WZ
> zrVCY?W~`3Hw@^=cHALr#9F2GOTYJ;??9d*-Vbsi+;lz|<$jMX#;lr6ov3qKNLH7(W
> z+>yFoWnOtw14D$&k*SUtsT%wS`ki@#&rUrnmtuDv`PtJm(Kg?H$Pdc0CL@YCy4R<D
> pT|LnIbg(BnP0#tqRx5M!bkkaD-nd?`H;YU4Yi6yHwD{k({tHC8FAx9#

Ideally this should be generated on CI as artifact, archived
and we commit the CI generated file.

> diff --git a/pc-bios/optionrom/optionrom.h b/pc-bios/optionrom/optionrom.h
> index a2b612f1a7..8d74c0ddf3 100644
> --- a/pc-bios/optionrom/optionrom.h
> +++ b/pc-bios/optionrom/optionrom.h
> @@ -37,6 +37,17 @@
>  #define BIOS_CFG_IOPORT_CFG	0x510
>  #define BIOS_CFG_IOPORT_DATA	0x511
>  
> +#define FW_CFG_DMA_CTL_ERROR   0x01
> +#define FW_CFG_DMA_CTL_READ    0x02
> +#define FW_CFG_DMA_CTL_SKIP    0x04
> +#define FW_CFG_DMA_CTL_SELECT  0x08
> +#define FW_CFG_DMA_CTL_WRITE   0x10
> +
> +#define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* "QEMU CFG" */
> +
> +#define BIOS_CFG_DMA_ADDR_HIGH  0x514
> +#define BIOS_CFG_DMA_ADDR_LOW   0x518
> +
>  /* Break the translation block flow so -d cpu shows us values */
>  #define DEBUG_HERE \
>  	jmp		1f;				\
> @@ -62,6 +73,61 @@
>  	bswap		%eax
>  .endm
>  
> +
> +/*
> + * Read data from the fw_cfg device using DMA.
> + * Clobbers:	%edx, %eax, ADDR, SIZE, memory[%esp-16] to memory[%esp]
> + */
> +.macro read_fw_dma VAR, SIZE, ADDR
> +        /* Address */
> +	bswapl		\ADDR
> +	pushl		\ADDR
> +
> +	/* We only support 32 bit target addresses */
> +	xorl		%eax, %eax
> +	pushl		%eax
> +	mov		$BIOS_CFG_DMA_ADDR_HIGH, %dx
> +	outl		%eax, (%dx)
> +
> +	/* Size */
> +	bswapl		\SIZE
> +	pushl		\SIZE
> +
> +        /* Control */

Indent off.

> +	movl		$(\VAR << 16) | (FW_CFG_DMA_CTL_READ | FW_CFG_DMA_CTL_SELECT), %eax
> +	bswapl		%eax
> +	pushl		%eax
> +
> +	movl		%esp, %eax /* Address of the struct we generated */
> +	bswapl		%eax
> +	mov		$BIOS_CFG_DMA_ADDR_LOW, %dx
> +	outl		%eax, (%dx) /* Initiate DMA */
> +
> +1:  mov		(%esp), %eax /* Wait for completion */
> +	bswapl		%eax
> +	testl		$~FW_CFG_DMA_CTL_ERROR, %eax
> +	jnz		1b
> +       addl            $16, %esp

Indent off.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>



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

* Re: [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer
  2021-10-20 14:02 [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer Paolo Bonzini
                   ` (2 preceding siblings ...)
  2021-10-20 14:02 ` [PATCH 3/3] target/i386: use DMA-enabled multiboot ROM for new-enough QEMU machine types Paolo Bonzini
@ 2021-10-21  7:23 ` Stefano Garzarella
  3 siblings, 0 replies; 8+ messages in thread
From: Stefano Garzarella @ 2021-10-21  7:23 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: adam, qemu-devel, marcus.haehnel

On Wed, Oct 20, 2021 at 04:02:41PM +0200, Paolo Bonzini wrote:
>An updated version of the patch at
>https://patchew.org/QEMU/YWM6jboU9fUib6Iy@os.inf.tu-dresden.de/,
>which includes the necessary glue for compatibility with older
>machine types.  When fw_cfg DMA is disabled, the existing ROM
>is used instead.
>
>Marcus Hähnel (1):
>  optionrom: add a DMA-enabled multiboot ROM
>
>Paolo Bonzini (2):
>  target/i386: move linuxboot_dma_enabled to X86MachineState
>  target/i386: use DMA-enabled multiboot ROM for new-enough QEMU machine
>    types
>
> hw/i386/microvm.c                 |   5 ++-
> hw/i386/multiboot.c               |  10 ++++-
> hw/i386/multiboot.h               |   4 +-
> hw/i386/pc.c                      |   8 ++--
> hw/i386/pc_piix.c                 |   3 +-
> hw/i386/pc_q35.c                  |   3 +-
> hw/i386/x86.c                     |   7 ++--
> include/hw/i386/pc.h              |   3 --
> include/hw/i386/x86.h             |   5 ++-
> pc-bios/meson.build               |   1 +
> pc-bios/multiboot_dma.bin         | Bin 0 -> 1024 bytes
> pc-bios/optionrom/Makefile        |   4 +-
> pc-bios/optionrom/multiboot.S     |   4 +-
> pc-bios/optionrom/multiboot_dma.S |   2 +
> pc-bios/optionrom/optionrom.h     |  66 ++++++++++++++++++++++++++++++
> 15 files changed, 102 insertions(+), 23 deletions(-)
> create mode 100644 pc-bios/multiboot_dma.bin
> create mode 100644 pc-bios/optionrom/multiboot_dma.S
>
>-- 
>2.31.1
>
>

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>



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

end of thread, other threads:[~2021-10-21  7:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-20 14:02 [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer Paolo Bonzini
2021-10-20 14:02 ` [PATCH 1/3] target/i386: move linuxboot_dma_enabled to X86MachineState Paolo Bonzini
2021-10-20 19:13   ` Philippe Mathieu-Daudé
2021-10-20 14:02 ` [PATCH 2/3] optionrom: add a DMA-enabled multiboot ROM Paolo Bonzini
2021-10-20 22:08   ` Philippe Mathieu-Daudé
2021-10-20 14:02 ` [PATCH 3/3] target/i386: use DMA-enabled multiboot ROM for new-enough QEMU machine types Paolo Bonzini
2021-10-20 19:19   ` Philippe Mathieu-Daudé
2021-10-21  7:23 ` [PATCH v2 0/3] multiboot: Use DMA instead port-based transfer Stefano Garzarella

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.