[xen-unstable test] 183489: tolerable FAIL

2023-10-22 Thread osstest service owner
flight 183489 xen-unstable real [real]
http://logs.test-lab.xenproject.org/osstest/logs/183489/

Failures :-/ but no regressions.

Tests which are failing intermittently (not blocking):
 test-amd64-coresched-i386-xl 20 guest-localmigrate/x10 fail in 183453 pass in 
183489
 test-armhf-armhf-xl-rtds 18 guest-start/debian.repeat fail in 183453 pass in 
183489
 test-amd64-i386-libvirt-xsm   7 xen-installfail pass in 183453
 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 18 
guest-start/debianhvm.repeat fail pass in 183453
 test-amd64-amd64-xl-qemuu-debianhvm-i386-xsm 12 debian-hvm-install fail pass 
in 183453

Tests which did not succeed, but are not blocking:
 test-amd64-i386-libvirt-xsm 15 migrate-support-check fail in 183453 never pass
 test-armhf-armhf-libvirt 16 saverestore-support-checkfail  like 183453
 test-amd64-amd64-xl-qemut-win7-amd64 19 guest-stopfail like 183453
 test-amd64-i386-xl-qemuu-win7-amd64 19 guest-stop fail like 183453
 test-amd64-amd64-xl-qemuu-ws16-amd64 19 guest-stopfail like 183453
 test-armhf-armhf-libvirt-raw 15 saverestore-support-checkfail  like 183453
 test-amd64-i386-xl-qemut-ws16-amd64 19 guest-stop fail like 183453
 test-amd64-amd64-qemuu-nested-amd 20 debian-hvm-install/l1/l2 fail like 183453
 test-amd64-i386-xl-qemut-win7-amd64 19 guest-stop fail like 183453
 test-amd64-amd64-xl-qemut-ws16-amd64 19 guest-stopfail like 183453
 test-armhf-armhf-libvirt-qcow2 15 saverestore-support-check   fail like 183453
 test-amd64-i386-xl-qemuu-ws16-amd64 19 guest-stop fail like 183453
 test-amd64-amd64-xl-qemuu-win7-amd64 19 guest-stopfail like 183453
 test-amd64-i386-xl-pvshim14 guest-start  fail   never pass
 test-amd64-i386-libvirt  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  16 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-amd64-amd64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-armhf-armhf-xl-arndale  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-multivcpu 15 migrate-support-checkfail  never pass
 test-armhf-armhf-xl-arndale  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-multivcpu 16 saverestore-support-checkfail  never pass
 test-armhf-armhf-xl-rtds 15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-rtds 16 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt 15 migrate-support-checkfail   never pass
 test-amd64-amd64-libvirt 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 15 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-vhd 14 migrate-support-checkfail   never pass
 test-amd64-i386-libvirt-raw  14 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-vhd  14 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-vhd  15 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt-raw 14 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-vhd  14 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-vhd  15 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt-qcow2 14 migrate-suppo

Re: NULL pointer dereference in xenbus_thread->...

2023-10-22 Thread Marek Marczykowski-Górecki
On Mon, Aug 28, 2023 at 11:50:36PM +0200, Marek Marczykowski-Górecki wrote:
> Hi,
> 
> I've noticed in Qubes's CI failure like this:
> 
> [  871.271292] BUG: kernel NULL pointer dereference, address: 
> [  871.275290] #PF: supervisor read access in kernel mode
> [  871.277282] #PF: error_code(0x) - not-present page
> [  871.279182] PGD 106fdb067 P4D 106fdb067 PUD 106fdc067 PMD 0 
> [  871.281071] Oops:  [#1] PREEMPT SMP NOPTI
> [  871.282698] CPU: 1 PID: 28 Comm: xenbus Not tainted 
> 6.1.43-1.qubes.fc37.x86_64 #1
> [  871.285222] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
> rel-1.16.0-0-gd239552-rebuilt.opensuse.org 04/01/2014
> [  871.23] RIP: e030:__wake_up_common+0x4c/0x180
> [  871.292838] Code: 24 0c 89 4c 24 08 4d 85 c9 74 0a 41 f6 01 04 0f 85 a3 00 
> 00 00 48 8b 43 08 4c 8d 40 e8 48 83 c3 08 49 8d 40 18 48 39 c3 74 5b <49> 8b 
> 40 18 31 ed 4c 8d 70 e8 45 8b 28 41 f6 c5 04 75 5f 49 8b 40
> [  871.299776] RSP: e02b:c900400f7e10 EFLAGS: 00010082
> [  871.301656] RAX:  RBX: 88810541ce98 RCX: 
> 
> [  871.304255] RDX: 0001 RSI: 0003 RDI: 
> 88810541ce90
> [  871.306714] RBP: c900400f0280 R08: ffe8 R09: 
> c900400f7e68
> [  871.309937] R10: 7ff0 R11: 888100ad3000 R12: 
> c900400f7e68
> [  871.312326] R13:  R14:  R15: 
> 
> [  871.314647] FS:  () GS:88813ff0() 
> knlGS:
> [  871.317677] CS:  1e030 DS:  ES:  CR0: 80050033
> [  871.319644] CR2:  CR3: 0001067fe000 CR4: 
> 00040660
> [  871.321973] Call Trace:
> [  871.322782]  
> [  871.323494]  ? show_trace_log_lvl+0x1d3/0x2ef
> [  871.324901]  ? show_trace_log_lvl+0x1d3/0x2ef
> [  871.326310]  ? show_trace_log_lvl+0x1d3/0x2ef
> [  871.327721]  ? __wake_up_common_lock+0x82/0xd0
> [  871.329147]  ? __die_body.cold+0x8/0xd
> [  871.330378]  ? page_fault_oops+0x163/0x1a0
> [  871.331691]  ? exc_page_fault+0x70/0x170
> [  871.332946]  ? asm_exc_page_fault+0x22/0x30
> [  871.334454]  ? __wake_up_common+0x4c/0x180
> [  871.335777]  __wake_up_common_lock+0x82/0xd0
> [  871.337183]  ? process_writes+0x240/0x240
> [  871.338461]  process_msg+0x18e/0x2f0
> [  871.339627]  xenbus_thread+0x165/0x1c0
> [  871.340830]  ? cpuusage_read+0x10/0x10
> [  871.342032]  kthread+0xe9/0x110
> [  871.343317]  ? kthread_complete_and_exit+0x20/0x20
> [  871.345020]  ret_from_fork+0x22/0x30
> [  871.346239]  
> [  871.347060] Modules linked in: snd_hda_codec_generic ledtrig_audio 
> snd_hda_intel snd_intel_dspcfg snd_intel_sdw_acpi snd_hda_codec snd_hda_core 
> snd_hwdep snd_seq snd_seq_device joydev snd_pcm intel_rapl_msr ppdev 
> intel_rapl_common snd_timer pcspkr e1000e snd soundcore i2c_piix4 parport_pc 
> parport loop fuse xenfs dm_crypt crct10dif_pclmul crc32_pclmul crc32c_intel 
> polyval_clmulni polyval_generic floppy ghash_clmulni_intel sha512_ssse3 
> serio_raw virtio_scsi virtio_console bochs xhci_pci xhci_pci_renesas xhci_hcd 
> qemu_fw_cfg drm_vram_helper drm_ttm_helper ttm ata_generic pata_acpi 
> xen_privcmd xen_pciback xen_blkback xen_gntalloc xen_gntdev xen_evtchn 
> scsi_dh_rdac scsi_dh_emc scsi_dh_alua uinput dm_multipath
> [  871.368892] CR2: 
> [  871.370160] ---[ end trace  ]---
> [  871.371719] RIP: e030:__wake_up_common+0x4c/0x180
> [  871.373273] Code: 24 0c 89 4c 24 08 4d 85 c9 74 0a 41 f6 01 04 0f 85 a3 00 
> 00 00 48 8b 43 08 4c 8d 40 e8 48 83 c3 08 49 8d 40 18 48 39 c3 74 5b <49> 8b 
> 40 18 31 ed 4c 8d 70 e8 45 8b 28 41 f6 c5 04 75 5f 49 8b 40
> [  871.379866] RSP: e02b:c900400f7e10 EFLAGS: 00010082
> [  871.381689] RAX:  RBX: 88810541ce98 RCX: 
> 
> [  871.383971] RDX: 0001 RSI: 0003 RDI: 
> 88810541ce90
> [  871.386235] RBP: c900400f0280 R08: ffe8 R09: 
> c900400f7e68
> [  871.388521] R10: 7ff0 R11: 888100ad3000 R12: 
> c900400f7e68
> [  871.390789] R13:  R14:  R15: 
> 
> [  871.393101] FS:  () GS:88813ff0() 
> knlGS:
> [  871.395671] CS:  1e030 DS:  ES:  CR0: 80050033
> [  871.397863] CR2:  CR3: 0001067fe000 CR4: 
> 00040660
> [  871.400441] Kernel panic - not syncing: Fatal exception
> [  871.402171] Kernel Offset: disabled
> (XEN) Hardware Dom0 crashed: rebooting machine in 5 seconds.
> 
> It isn't the first time I see similar crash, but I can't really
> reproduce it reliably. Restarted test usually passes.
> Note this is Xen nested in KVM, so it could very well be some oddity
> about nested virt, although looking at the stack trace, it's unlikely
> and more likely some race condition hit only on slower system.

Recently I've got the same crash on a real system in domU too. And

[linux-linus test] 183490: tolerable FAIL - PUSHED

2023-10-22 Thread osstest service owner
flight 183490 linux-linus real [real]
flight 183491 linux-linus real-retest [real]
http://logs.test-lab.xenproject.org/osstest/logs/183490/
http://logs.test-lab.xenproject.org/osstest/logs/183491/

Failures :-/ but no regressions.

Tests which are failing intermittently (not blocking):
 test-armhf-armhf-libvirt  8 xen-bootfail pass in 183491-retest

Tests which did not succeed, but are not blocking:
 test-armhf-armhf-libvirt 16 saverestore-support-check fail in 183491 like 
183476
 test-armhf-armhf-libvirt15 migrate-support-check fail in 183491 never pass
 test-amd64-amd64-xl-qemut-win7-amd64 19 guest-stopfail like 183476
 test-amd64-amd64-xl-qemuu-win7-amd64 19 guest-stopfail like 183476
 test-amd64-amd64-xl-qemuu-ws16-amd64 19 guest-stopfail like 183476
 test-armhf-armhf-libvirt-raw 15 saverestore-support-checkfail  like 183476
 test-amd64-amd64-xl-qemut-ws16-amd64 19 guest-stopfail like 183476
 test-armhf-armhf-libvirt-qcow2 15 saverestore-support-check   fail like 183476
 test-amd64-amd64-qemuu-nested-amd 20 debian-hvm-install/l1/l2 fail like 183476
 test-amd64-amd64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-amd64-amd64-libvirt 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  16 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-armhf-armhf-xl-multivcpu 15 migrate-support-checkfail  never pass
 test-armhf-armhf-xl-multivcpu 16 saverestore-support-checkfail  never pass
 test-armhf-armhf-xl-arndale  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-arndale  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  16 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-qcow2 14 migrate-support-checkfail never pass
 test-amd64-amd64-libvirt-raw 14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 15 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-vhd  14 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-vhd  15 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt-raw 14 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-vhd  14 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-vhd  15 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-rtds 15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-rtds 16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt-qcow2 14 migrate-support-checkfail never pass

version targeted for testing:
 linux1acfd2bd3f0d9dc34ea1871a445c554220945d9f
baseline version:
 linux4d7b04c0cda365f190c4a8f7fddc535b93aae9f9

Last test of basis   183476  2023-10-21 18:15:19 Z0 days
Testing same since   183490  2023-10-22 03:30:53 Z0 days1 attempts


People who touched revisions under test:
  Andrea Righi 
  Andy Shevchenko 
  Bartosz Golaszewski 
  Benno Lossin 
  Christophe Leroy 
  Dmitry Safonov <0x7f454...@gmail.com>
  Francis Laniel 
  Gary Guo 
  Haibo Chen 
  Linus Torvalds 
  Manmohan Shukla 
  Masami Hiramatsu (Google) 
  Michael Ellerman 
  Miguel Ojeda 
  Nicholas Piggin 
  Peter Zijlstra (Intel) 
  Peter Zijlstra 
  Sachin Sant 
  Shrikanth Hegde 
  Wedson Almeida Filho 

jobs:
 build-amd64-xsm

[PATCH 27/45] hw/arm/highbank: use qemu_create_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/arm/highbank.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index f12aacea6b..798e5391dc 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -296,19 +296,17 @@ static void calxeda_init(MachineState *machine, enum 
cxmachines machine_id)
 
 sysbus_create_simple(TYPE_SYSBUS_AHCI, 0xffe08000, pic[83]);
 
-if (nd_table[0].used) {
-qemu_check_nic_model(&nd_table[0], "xgmac");
-dev = qdev_new("xgmac");
-qdev_set_nic_properties(dev, &nd_table[0]);
+dev = qemu_create_nic_device("xgmac", true, NULL);
+if (dev) {
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff5);
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[77]);
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[78]);
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[79]);
+}
 
-qemu_check_nic_model(&nd_table[1], "xgmac");
-dev = qdev_new("xgmac");
-qdev_set_nic_properties(dev, &nd_table[1]);
+dev = qemu_create_nic_device("xgmac", true, NULL);
+if (dev) {
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff51000);
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[80]);
-- 
2.40.1




[PATCH 38/45] hw/riscv: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/riscv/microchip_pfsoc.c | 13 ++---
 hw/riscv/sifive_u.c|  7 +--
 2 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index b775aa8946..8e0e3aa20c 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -411,17 +411,8 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, 
Error **errp)
 memmap[MICROCHIP_PFSOC_USB].size);
 
 /* GEMs */
-
-nd = &nd_table[0];
-if (nd->used) {
-qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
-qdev_set_nic_properties(DEVICE(&s->gem0), nd);
-}
-nd = &nd_table[1];
-if (nd->used) {
-qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
-qdev_set_nic_properties(DEVICE(&s->gem1), nd);
-}
+qemu_configure_nic_device(DEVICE(&s->gem0), true, NULL);
+qemu_configure_nic_device(DEVICE(&s->gem1), true, NULL);
 
 object_property_set_int(OBJECT(&s->gem0), "revision", GEM_REVISION, errp);
 object_property_set_int(OBJECT(&s->gem0), "phy-addr", 8, errp);
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ec76dce6c9..5207ec1fa5 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -789,7 +789,6 @@ static void sifive_u_soc_realize(DeviceState *dev, Error 
**errp)
 MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
 char *plic_hart_config;
 int i, j;
-NICInfo *nd = &nd_table[0];
 
 qdev_prop_set_uint32(DEVICE(&s->u_cpus), "num-harts", ms->smp.cpus - 1);
 qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
@@ -893,11 +892,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error 
**errp)
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_DEV_OTP].base);
 
-/* FIXME use qdev NIC properties instead of nd_table[] */
-if (nd->used) {
-qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
-qdev_set_nic_properties(DEVICE(&s->gem), nd);
-}
+qemu_configure_nic_device(DEVICE(&s->gem), true, NULL);
 object_property_set_int(OBJECT(&s->gem), "revision", GEM_REVISION,
 &error_abort);
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->gem), errp)) {
-- 
2.40.1




[PATCH 18/45] hw/sh4/r2d: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Previously, the first PCI NIC would be assigned to slot 2 even if the
user override the model and made it something other than an rtl8139
which is the default. Everything else would be dynamically assigned.

Now, the first rtl8139 gets slot 2 and everything else is dynamic.

Signed-off-by: David Woodhouse 
---
 hw/sh4/r2d.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 4944994e9c..e9f316a6ce 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -240,7 +240,6 @@ static void r2d_init(MachineState *machine)
 MemoryRegion *sdram = g_new(MemoryRegion, 1);
 qemu_irq *irq;
 DriveInfo *dinfo;
-int i;
 DeviceState *dev;
 SysBusDevice *busdev;
 MemoryRegion *address_space_mem = get_system_memory();
@@ -309,9 +308,8 @@ static void r2d_init(MachineState *machine)
   0x555, 0x2aa, 0);
 
 /* NIC: rtl8139 on-board, and 2 slots. */
-for (i = 0; i < nb_nics; i++)
-pci_nic_init_nofail(&nd_table[i], pci_bus,
-mc->default_nic, i == 0 ? "2" : NULL);
+pci_init_nic_in_slot(pci_bus, mc->default_nic, NULL, "2");
+pci_init_nic_devices(pci_bus, mc->default_nic);
 
 /* USB keyboard */
 usb_create_simple(usb_bus_find(-1), "usb-kbd");
-- 
2.40.1




[PATCH 37/45] hw/openrisc/openrisc_sim: use qemu_create_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/openrisc/openrisc_sim.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 35da123aef..bffd6f721f 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -170,7 +170,7 @@ static void openrisc_create_fdt(Or1ksimState *state,
 
 static void openrisc_sim_net_init(Or1ksimState *state, hwaddr base, hwaddr 
size,
   int num_cpus, OpenRISCCPU *cpus[],
-  int irq_pin, NICInfo *nd)
+  int irq_pin)
 {
 void *fdt = state->fdt;
 DeviceState *dev;
@@ -178,8 +178,10 @@ static void openrisc_sim_net_init(Or1ksimState *state, 
hwaddr base, hwaddr size,
 char *nodename;
 int i;
 
-dev = qdev_new("open_eth");
-qdev_set_nic_properties(dev, nd);
+dev = qemu_create_nic_device("open_eth", true, NULL);
+if (!dev) {
+return;
+}
 
 s = SYS_BUS_DEVICE(dev);
 sysbus_realize_and_unref(s, &error_fatal);
@@ -313,12 +315,10 @@ static void openrisc_sim_init(MachineState *machine)
 openrisc_create_fdt(state, or1ksim_memmap, smp_cpus, machine->ram_size,
 machine->kernel_cmdline);
 
-if (nd_table[0].used) {
-openrisc_sim_net_init(state, or1ksim_memmap[OR1KSIM_ETHOC].base,
-  or1ksim_memmap[OR1KSIM_ETHOC].size,
-  smp_cpus, cpus,
-  OR1KSIM_ETHOC_IRQ, nd_table);
-}
+openrisc_sim_net_init(state, or1ksim_memmap[OR1KSIM_ETHOC].base,
+  or1ksim_memmap[OR1KSIM_ETHOC].size,
+  smp_cpus, cpus,
+  OR1KSIM_ETHOC_IRQ);
 
 if (smp_cpus > 1) {
 openrisc_sim_ompic_init(state, or1ksim_memmap[OR1KSIM_OMPIC].base,
-- 
2.40.1




[PATCH 24/45] hw/arm/fsl: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/arm/fsl-imx25.c  | 2 +-
 hw/arm/fsl-imx6.c   | 2 +-
 hw/arm/fsl-imx6ul.c | 2 +-
 hw/arm/fsl-imx7.c   | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 24c4374590..28084d2e5a 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -170,7 +170,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 }
 
 object_property_set_uint(OBJECT(&s->fec), "phy-num", s->phy_num, &err);
-qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]);
+qemu_configure_nic_device(DEVICE(&s->fec), true, NULL);
 
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->fec), errp)) {
 return;
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 4fa7f0b95e..273bc79283 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -380,7 +380,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
 }
 
 object_property_set_uint(OBJECT(&s->eth), "phy-num", s->phy_num, &err);
-qdev_set_nic_properties(DEVICE(&s->eth), &nd_table[0]);
+qemu_configure_nic_device(DEVICE(&s->eth), true, NULL);
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->eth), errp)) {
 return;
 }
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index e37b69a5e1..ca3dd439ec 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -442,7 +442,7 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error 
**errp)
  s->phy_num[i], &error_abort);
 object_property_set_uint(OBJECT(&s->eth[i]), "tx-ring-num",
  FSL_IMX6UL_ETH_NUM_TX_RINGS, &error_abort);
-qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
+qemu_configure_nic_device(DEVICE(&s->eth[i]), true, NULL);
 sysbus_realize(SYS_BUS_DEVICE(&s->eth[i]), &error_abort);
 
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0,
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 474cfdc87c..1acbe065db 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -446,7 +446,7 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
  s->phy_num[i], &error_abort);
 object_property_set_uint(OBJECT(&s->eth[i]), "tx-ring-num",
  FSL_IMX7_ETH_NUM_TX_RINGS, &error_abort);
-qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
+qemu_configure_nic_device(DEVICE(&s->eth[i]), true, NULL);
 sysbus_realize(SYS_BUS_DEVICE(&s->eth[i]), &error_abort);
 
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, FSL_IMX7_ENETn_ADDR[i]);
-- 
2.40.1




[PATCH 33/45] hw/m68k/q800: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Then fetch the MAC that was assigned, if any. And assign one if not,
ensuring that it uses the Apple OUI.

Signed-off-by: David Woodhouse 
---
 hw/m68k/q800.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 1d7cd5ff1c..94e7c0dd60 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -271,6 +271,7 @@ static void q800_machine_init(MachineState *machine)
 BusState *adb_bus;
 NubusBus *nubus;
 DriveInfo *dinfo;
+MACAddr mac;
 uint8_t rng_seed[32];
 
 linux_boot = (kernel_filename != NULL);
@@ -371,13 +372,6 @@ static void q800_machine_init(MachineState *machine)
 
 /* MACSONIC */
 
-if (nb_nics > 1) {
-error_report("q800 can only have one ethernet interface");
-exit(1);
-}
-
-qemu_check_nic_model(&nd_table[0], "dp83932");
-
 /*
  * MacSonic driver needs an Apple MAC address
  * Valid prefix are:
@@ -387,14 +381,22 @@ static void q800_machine_init(MachineState *machine)
  * 08:00:07 Apple
  * (Q800 use the last one)
  */
-nd_table[0].macaddr.a[0] = 0x08;
-nd_table[0].macaddr.a[1] = 0x00;
-nd_table[0].macaddr.a[2] = 0x07;
-
 object_initialize_child(OBJECT(machine), "dp8393x", &m->dp8393x,
 TYPE_DP8393X);
 dev = DEVICE(&m->dp8393x);
-qdev_set_nic_properties(dev, &nd_table[0]);
+if (qemu_configure_nic_device(dev, TYPE_DP8393X, true, "dp83932")) {
+gchar *macstr = object_property_get_str(OBJECT(dev));
+if (macstr) {
+net_parse_macaddr(mac.a, macstr);
+g_free(macstr);
+}
+}
+qemu_macaddr_default_if_unset(&mac);
+mac.a[0] = 0x08;
+mac.a[1] = 0x00;
+mac.a[2] = 0x07;
+qemu_prop_set_macaddr(dev, "mac", &mac.a);
+
 qdev_prop_set_uint8(dev, "it_shift", 2);
 qdev_prop_set_bit(dev, "big_endian", true);
 object_property_set_link(OBJECT(dev), "dma_mr",
@@ -415,7 +417,7 @@ static void q800_machine_init(MachineState *machine)
 prom = memory_region_get_ram_ptr(dp8393x_prom);
 checksum = 0;
 for (i = 0; i < 6; i++) {
-prom[i] = revbit8(nd_table[0].macaddr.a[i]);
+prom[i] = revbit8(mac.a[i]);
 checksum ^= prom[i];
 }
 prom[7] = 0xff - checksum;
-- 
2.40.1




[PATCH 14/45] hw/mips/loongson3_virt: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/mips/loongson3_virt.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index b74b358874..d9d6d4f5b6 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -452,9 +452,7 @@ static inline void loongson3_virt_devices_init(MachineState 
*machine,
 usb_create_simple(usb_bus_find(-1), "usb-tablet");
 }
 
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
-}
+pci_init_nic_devices(pci_bus, mc->default_nic);
 }
 
 static void mips_loongson3_virt_init(MachineState *machine)
-- 
2.40.1




[PATCH 05/45] hw/i386/pc: use qemu_get_nic_info() and pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Eliminate direct access to nd_table[] and nb_nics by processing the the
ISA NICs first and then calling pci_init_nic_devices() for the test.

It's important to do this *before* the subsequent patch which registers
the Xen PV network devices, because the code being remove here didn't
check whether nd->instantiated was already set before using each entry.

Signed-off-by: David Woodhouse 
---
 hw/i386/pc.c| 20 ++--
 include/hw/net/ne2000-isa.h |  2 --
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index bb3854d1d0..e08600cbb3 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -652,8 +652,10 @@ static void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd)
 {
 static int nb_ne2k = 0;
 
-if (nb_ne2k == NE2000_NB_MAX)
+if (nb_ne2k == NE2000_NB_MAX) {
+error_setg(&error_fatal, "maximum number of ISA NE2000 devices 
exceeded");
 return;
+}
 isa_ne2000_init(bus, ne2000_io[nb_ne2k],
 ne2000_irq[nb_ne2k], nd);
 nb_ne2k++;
@@ -1294,19 +1296,17 @@ void pc_basic_device_init(struct PCMachineState *pcms,
 void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus)
 {
 MachineClass *mc = MACHINE_CLASS(pcmc);
-int i;
+bool default_is_ne2k = g_str_equal(mc->default_nic, TYPE_ISA_NE2000);
+NICInfo *nd;
 
 rom_set_order_override(FW_CFG_ORDER_OVERRIDE_NIC);
-for (i = 0; i < nb_nics; i++) {
-NICInfo *nd = &nd_table[i];
-const char *model = nd->model ? nd->model : mc->default_nic;
 
-if (g_str_equal(model, "ne2k_isa")) {
-pc_init_ne2k_isa(isa_bus, nd);
-} else {
-pci_nic_init_nofail(nd, pci_bus, model, NULL);
-}
+while ((nd = qemu_find_nic_info(TYPE_ISA_NE2000, default_is_ne2k, NULL))) {
+pc_init_ne2k_isa(isa_bus, nd);
 }
+
+pci_init_nic_devices(pci_bus, mc->default_nic);
+
 rom_reset_order_override();
 }
 
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
index af59ee0b02..73bae10ad1 100644
--- a/include/hw/net/ne2000-isa.h
+++ b/include/hw/net/ne2000-isa.h
@@ -22,8 +22,6 @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int 
base, int irq,
 {
 ISADevice *d;
 
-qemu_check_nic_model(nd, "ne2k_isa");
-
 d = isa_try_new(TYPE_ISA_NE2000);
 if (d) {
 DeviceState *dev = DEVICE(d);
-- 
2.40.1




[PATCH 02/45] net: report list of available models according to platform

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

By noting the models for which a configuration was requested, we can give
the user an accurate list of which NIC models were actually available on
the platform/configuration that was otherwise chosen.

Signed-off-by: David Woodhouse 
---
 net/net.c | 94 +++
 1 file changed, 94 insertions(+)

diff --git a/net/net.c b/net/net.c
index 606816a3b3..6e20f9d2e9 100644
--- a/net/net.c
+++ b/net/net.c
@@ -75,6 +75,8 @@ typedef QSIMPLEQ_HEAD(, NetdevQueueEntry) NetdevQueue;
 
 static NetdevQueue nd_queue = QSIMPLEQ_HEAD_INITIALIZER(nd_queue);
 
+static GHashTable *nic_model_help;
+
 /***/
 /* network device redirectors */
 
@@ -1072,12 +1074,94 @@ static int net_init_nic(const Netdev *netdev, const 
char *name,
 return idx;
 }
 
+static gboolean add_nic_result(gpointer key, gpointer value, gpointer 
user_data)
+{
+GPtrArray *results = user_data;
+GPtrArray *alias_list = value;
+const char *model = key;
+char *result;
+
+if (!alias_list) {
+result = g_strdup(model);
+} else {
+GString *result_str = g_string_new(model);
+int i;
+
+g_string_append(result_str, " (aka ");
+for (i = 0; i < alias_list->len; i++) {
+if (i) {
+g_string_append(result_str, ", ");
+}
+g_string_append(result_str, alias_list->pdata[i]);
+}
+g_string_append(result_str, ")");
+result = result_str->str;
+g_string_free(result_str, false);
+g_ptr_array_unref(alias_list);
+}
+g_ptr_array_add(results, result);
+return true;
+}
+
+static int model_cmp(char **a, char **b)
+{
+return strcmp(*a, *b);
+}
+
+static void show_nic_models(void)
+{
+GPtrArray *results = g_ptr_array_new();
+int i;
+
+g_hash_table_foreach_remove(nic_model_help, add_nic_result, results);
+g_ptr_array_sort(results, (GCompareFunc)model_cmp);
+
+printf("Available NIC models for this configuration:\n");
+for (i = 0 ; i < results->len; i++) {
+printf("%s\n", (char *)results->pdata[i]);
+}
+g_hash_table_unref(nic_model_help);
+nic_model_help = NULL;
+}
+
+static void add_nic_model_help(const char *model, const char *alias)
+{
+GPtrArray *alias_list = NULL;
+
+if (g_hash_table_lookup_extended(nic_model_help, model, NULL,
+ (gpointer *)&alias_list)) {
+/* Already exists, no alias to add: return */
+if (!alias) {
+return;
+}
+if (alias_list) {
+/* Check if this alias is already in the list. Add if not. */
+if (!g_ptr_array_find_with_equal_func(alias_list, alias,
+  g_str_equal, NULL)) {
+g_ptr_array_add(alias_list, g_strdup(alias));
+}
+return;
+}
+}
+/* Either this model wasn't in the list already, or a first alias added */
+if (alias) {
+alias_list = g_ptr_array_new();
+g_ptr_array_set_free_func(alias_list, g_free);
+g_ptr_array_add(alias_list, g_strdup(alias));
+}
+g_hash_table_replace(nic_model_help, g_strdup(model), alias_list);
+}
+
 NICInfo *qemu_find_nic_info(const char *typename, bool match_default,
 const char *alias)
 {
 NICInfo *nd;
 int i;
 
+if (nic_model_help) {
+add_nic_model_help(typename, alias);
+}
+
 for (i = 0; i < nb_nics; i++) {
 nd = &nd_table[i];
 
@@ -1590,6 +1674,10 @@ void net_check_clients(void)
 NetClientState *nc;
 int i;
 
+if (nic_model_help) {
+show_nic_models();
+exit(0);
+}
 net_hub_check_clients();
 
 QTAILQ_FOREACH(nc, &net_clients, next) {
@@ -1669,6 +1757,12 @@ static int net_param_nic(void *dummy, QemuOpts *opts, 
Error **errp)
 memset(ni, 0, sizeof(*ni));
 ni->model = qemu_opt_get_del(opts, "model");
 
+if (!nic_model_help && !g_strcmp0(ni->model, "help")) {
+nic_model_help = g_hash_table_new_full(g_str_hash, g_str_equal,
+   g_free, NULL);
+return 0;
+}
+
 /* Create an ID if the user did not specify one */
 nd_id = g_strdup(qemu_opts_id(opts));
 if (!nd_id) {
-- 
2.40.1




[PATCH 08/45] hw/arm/sbsa-ref: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/arm/sbsa-ref.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index 3c7dfcd6dc..582a28ce92 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -691,9 +691,7 @@ static void create_pcie(SBSAMachineState *sms)
 
 pci = PCI_HOST_BRIDGE(dev);
 if (pci->bus) {
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci->bus, mc->default_nic, NULL);
-}
+pci_init_nic_devices(pci->bus, mc->default_nic);
 }
 
 pci_create_simple(pci->bus, -1, "bochs-display");
-- 
2.40.1




[PATCH 35/45] hw/mips: use qemu_create_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

The Jazz and MIPS SIM platforms both instantiate their NIC only if a
corresponding configuration exists for it. Convert them to use the
qemu_create_nic_device() function for that.

Signed-off-by: David Woodhouse 
---
 hw/mips/jazz.c| 16 ++--
 hw/mips/mipssim.c | 13 +++--
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index c32d2b0b0a..b0f4aa2763 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -114,7 +114,7 @@ static const MemoryRegionOps dma_dummy_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void mips_jazz_init_net(NICInfo *nd, IOMMUMemoryRegion *rc4030_dma_mr,
+static void mips_jazz_init_net(IOMMUMemoryRegion *rc4030_dma_mr,
DeviceState *rc4030, MemoryRegion *dp8393x_prom)
 {
 DeviceState *dev;
@@ -122,10 +122,11 @@ static void mips_jazz_init_net(NICInfo *nd, 
IOMMUMemoryRegion *rc4030_dma_mr,
 int checksum, i;
 uint8_t *prom;
 
-qemu_check_nic_model(nd, "dp83932");
+dev = qemu_create_nic_device("dp8393x", true, "dp82932");
+if (!dev) {
+return;
+}
 
-dev = qdev_new("dp8393x");
-qdev_set_nic_properties(dev, nd);
 qdev_prop_set_uint8(dev, "it_shift", 2);
 qdev_prop_set_bit(dev, "big_endian", TARGET_BIG_ENDIAN);
 object_property_set_link(OBJECT(dev), "dma_mr",
@@ -314,12 +315,7 @@ static void mips_jazz_init(MachineState *machine,
 }
 
 /* Network controller */
-if (nb_nics == 1) {
-mips_jazz_init_net(&nd_table[0], rc4030_dma_mr, rc4030, dp8393x_prom);
-} else if (nb_nics > 1) {
-error_report("This machine only supports one NIC");
-exit(1);
-}
+mips_jazz_init_net(rc4030_dma_mr, rc4030, dp8393x_prom);
 
 /* SCSI adapter */
 dev = qdev_new(TYPE_SYSBUS_ESP);
diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c
index 2f951f7fc6..072864f539 100644
--- a/hw/mips/mipssim.c
+++ b/hw/mips/mipssim.c
@@ -111,13 +111,15 @@ static void main_cpu_reset(void *opaque)
 }
 }
 
-static void mipsnet_init(int base, qemu_irq irq, NICInfo *nd)
+static void mipsnet_init(int base, qemu_irq irq)
 {
 DeviceState *dev;
 SysBusDevice *s;
 
-dev = qdev_new("mipsnet");
-qdev_set_nic_properties(dev, nd);
+dev = qemu_create_nic_device("mipsnet", true, NULL);
+if (!dev) {
+return;
+}
 
 s = SYS_BUS_DEVICE(dev);
 sysbus_realize_and_unref(s, &error_fatal);
@@ -218,9 +220,8 @@ mips_mipssim_init(MachineState *machine)
   sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
 }
 
-if (nd_table[0].used)
-/* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
-mipsnet_init(0x4200, env->irq[2], &nd_table[0]);
+/* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
+mipsnet_init(0x4200, env->irq[2]);
 }
 
 static void mips_mipssim_machine_init(MachineClass *mc)
-- 
2.40.1




[PATCH 21/45] hw/arm/allwinner: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/arm/allwinner-a10.c |  6 +-
 hw/arm/allwinner-h3.c  |  6 +-
 hw/arm/allwinner-r40.c | 27 ++-
 3 files changed, 4 insertions(+), 35 deletions(-)

diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index b0ea3f7f66..57f52871ec 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -142,11 +142,7 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
 sysbus_realize(SYS_BUS_DEVICE(&s->dramc), &error_fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->dramc), 0, AW_A10_DRAMC_BASE);
 
-/* FIXME use qdev NIC properties instead of nd_table[] */
-if (nd_table[0].used) {
-qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
-qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
-}
+qemu_configure_nic_device(DEVICE(&s->emac), true, NULL);
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->emac), errp)) {
 return;
 }
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index f05afddf7e..4f102ad082 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -369,11 +369,7 @@ static void allwinner_h3_realize(DeviceState *dev, Error 
**errp)
   "sd-bus");
 
 /* EMAC */
-/* FIXME use qdev NIC properties instead of nd_table[] */
-if (nd_table[0].used) {
-qemu_check_nic_model(&nd_table[0], TYPE_AW_SUN8I_EMAC);
-qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
-}
+qemu_configure_nic_device(DEVICE(&s->emac), true, NULL);
 object_property_set_link(OBJECT(&s->emac), "dma-memory",
  OBJECT(get_system_memory()), &error_fatal);
 sysbus_realize(SYS_BUS_DEVICE(&s->emac), &error_fatal);
diff --git a/hw/arm/allwinner-r40.c b/hw/arm/allwinner-r40.c
index a0d367c60d..4d5661b014 100644
--- a/hw/arm/allwinner-r40.c
+++ b/hw/arm/allwinner-r40.c
@@ -294,7 +294,6 @@ static void allwinner_r40_init(Object *obj)
 
 static void allwinner_r40_realize(DeviceState *dev, Error **errp)
 {
-const char *r40_nic_models[] = { "gmac", "emac", NULL };
 AwR40State *s = AW_R40(dev);
 
 /* CPUs */
@@ -454,31 +453,8 @@ static void allwinner_r40_realize(DeviceState *dev, Error 
**errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->dramc), 2,
 s->memmap[AW_R40_DEV_DRAMPHY]);
 
-/* nic support gmac and emac */
-for (int i = 0; i < ARRAY_SIZE(r40_nic_models) - 1; i++) {
-NICInfo *nic = &nd_table[i];
-
-if (!nic->used) {
-continue;
-}
-if (qemu_show_nic_models(nic->model, r40_nic_models)) {
-exit(0);
-}
-
-switch (qemu_find_nic_model(nic, r40_nic_models, r40_nic_models[0])) {
-case 0: /* gmac */
-qdev_set_nic_properties(DEVICE(&s->gmac), nic);
-break;
-case 1: /* emac */
-qdev_set_nic_properties(DEVICE(&s->emac), nic);
-break;
-default:
-exit(1);
-break;
-}
-}
-
 /* GMAC */
+qemu_configure_nic_device(DEVICE(&s->gmac), true, "gmac");
 object_property_set_link(OBJECT(&s->gmac), "dma-memory",
  OBJECT(get_system_memory()), 
&error_fatal);
 sysbus_realize(SYS_BUS_DEVICE(&s->gmac), &error_fatal);
@@ -487,6 +463,7 @@ static void allwinner_r40_realize(DeviceState *dev, Error 
**errp)
qdev_get_gpio_in(DEVICE(&s->gic), AW_R40_GIC_SPI_GMAC));
 
 /* EMAC */
+qemu_configure_nic_device(DEVICE(&s->emac), true, "emac");
 sysbus_realize(SYS_BUS_DEVICE(&s->emac), &error_fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->emac), 0, s->memmap[AW_R40_DEV_EMAC]);
 sysbus_connect_irq(SYS_BUS_DEVICE(&s->emac), 0,
-- 
2.40.1




[PATCH 31/45] hw/net/etraxfs-eth: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/cris/axis_dev88.c  | 9 -
 hw/net/etraxfs_eth.c  | 5 ++---
 include/hw/cris/etraxfs.h | 2 +-
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index d82050d927..b41c4de9ff 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -308,15 +308,14 @@ void axisdev88_init(MachineState *machine)
 
 /* Add the two ethernet blocks.  */
 dma_eth = g_malloc0(sizeof dma_eth[0] * 4); /* Allocate 4 channels.  */
-etraxfs_eth_init(&nd_table[0], 0x30034000, 1, &dma_eth[0], &dma_eth[1]);
-if (nb_nics > 1) {
-etraxfs_eth_init(&nd_table[1], 0x30036000, 2, &dma_eth[2], 
&dma_eth[3]);
-}
 
+etraxfs_eth_init(0x30034000, 1, &dma_eth[0], &dma_eth[1]);
 /* The DMA Connector block is missing, hardwire things for now.  */
 etraxfs_dmac_connect_client(etraxfs_dmac, 0, &dma_eth[0]);
 etraxfs_dmac_connect_client(etraxfs_dmac, 1, &dma_eth[1]);
-if (nb_nics > 1) {
+
+if (qemu_find_nic_info(dev, true, "fseth")) {
+etraxfs_eth_init(0x30036000, 2, &dma_eth[2], &dma_eth[3]);
 etraxfs_dmac_connect_client(etraxfs_dmac, 6, &dma_eth[2]);
 etraxfs_dmac_connect_client(etraxfs_dmac, 7, &dma_eth[3]);
 }
diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c
index 1b82aec794..ab60eaac04 100644
--- a/hw/net/etraxfs_eth.c
+++ b/hw/net/etraxfs_eth.c
@@ -646,15 +646,14 @@ static void etraxfs_eth_class_init(ObjectClass *klass, 
void *data)
 
 /* Instantiate an ETRAXFS Ethernet MAC.  */
 DeviceState *
-etraxfs_eth_init(NICInfo *nd, hwaddr base, int phyaddr,
+etraxfs_eth_init(hwaddr base, int phyaddr,
  struct etraxfs_dma_client *dma_out,
  struct etraxfs_dma_client *dma_in)
 {
 DeviceState *dev;
-qemu_check_nic_model(nd, "fseth");
 
 dev = qdev_new("etraxfs-eth");
-qdev_set_nic_properties(dev, nd);
+qemu_configure_nic_device(dev, true, "fseth");
 qdev_prop_set_uint32(dev, "phyaddr", phyaddr);
 
 /*
diff --git a/include/hw/cris/etraxfs.h b/include/hw/cris/etraxfs.h
index 467b529dc0..012c4e9974 100644
--- a/include/hw/cris/etraxfs.h
+++ b/include/hw/cris/etraxfs.h
@@ -31,7 +31,7 @@
 #include "hw/sysbus.h"
 #include "qapi/error.h"
 
-DeviceState *etraxfs_eth_init(NICInfo *nd, hwaddr base, int phyaddr,
+DeviceState *etraxfs_eth_init(hwaddr base, int phyaddr,
   struct etraxfs_dma_client *dma_out,
   struct etraxfs_dma_client *dma_in);
 
-- 
2.40.1




[PATCH 36/45] hw/net/lasi_i82596: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/net/lasi_i82596.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/net/lasi_i82596.c b/hw/net/lasi_i82596.c
index e37f7fabe9..c4c197aaa8 100644
--- a/hw/net/lasi_i82596.c
+++ b/hw/net/lasi_i82596.c
@@ -125,11 +125,10 @@ SysBusI82596State *lasi_82596_init(MemoryRegion 
*addr_space,
 static const MACAddr HP_MAC = {
 .a = { 0x08, 0x00, 0x09, 0xef, 0x34, 0xf6 } };
 
-qemu_check_nic_model(&nd_table[0], TYPE_LASI_82596);
 dev = qdev_new(TYPE_LASI_82596);
 s = SYSBUS_I82596(dev);
 s->state.irq = lan_irq;
-qdev_set_nic_properties(dev, &nd_table[0]);
+qemu_configure_nic_device(dev, true, NULL);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 s->state.conf.macaddr = HP_MAC; /* set HP MAC prefix */
 
-- 
2.40.1




[PATCH 44/45] net: remove qemu_show_nic_models(), qemu_find_nic_model()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

These old functions can be removed now too. Let net_param_nic() print
the full set of network devices directly, and also make it note that a
list more specific to this platform/config will be available by using
'-nic model=help' instead.

Signed-off-by: David Woodhouse 
---
 include/net/net.h |  3 ---
 net/net.c | 39 ++-
 2 files changed, 6 insertions(+), 36 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 1512650190..290e604f03 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -201,9 +201,6 @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
 int qemu_set_vnet_le(NetClientState *nc, bool is_le);
 int qemu_set_vnet_be(NetClientState *nc, bool is_be);
 void qemu_macaddr_default_if_unset(MACAddr *macaddr);
-int qemu_show_nic_models(const char *arg, const char *const *models);
-int qemu_find_nic_model(NICInfo *nd, const char * const *models,
-const char *default_model);
 NICInfo *qemu_find_nic_info(const char *typename, bool match_default,
 const char *alias);
 bool qemu_configure_nic_device(DeviceState *dev, bool match_default,
diff --git a/net/net.c b/net/net.c
index bdb31dcb27..ed0d638454 100644
--- a/net/net.c
+++ b/net/net.c
@@ -962,38 +962,6 @@ GPtrArray *qemu_get_nic_models(const char *device_type)
 return nic_models;
 }
 
-int qemu_show_nic_models(const char *arg, const char *const *models)
-{
-int i;
-
-if (!arg || !is_help_option(arg)) {
-return 0;
-}
-
-printf("Available NIC models:\n");
-for (i = 0 ; models[i]; i++) {
-printf("%s\n", models[i]);
-}
-return 1;
-}
-
-int qemu_find_nic_model(NICInfo *nd, const char * const *models,
-const char *default_model)
-{
-int i;
-
-if (!nd->model)
-nd->model = g_strdup(default_model);
-
-for (i = 0 ; models[i]; i++) {
-if (strcmp(nd->model, models[i]) == 0)
-return i;
-}
-
-error_report("Unsupported NIC model: %s", nd->model);
-return -1;
-}
-
 static int net_init_nic(const Netdev *netdev, const char *name,
 NetClientState *peer, Error **errp)
 {
@@ -1775,9 +1743,14 @@ static int net_param_nic(void *dummy, QemuOpts *opts, 
Error **errp)
 }
 if (is_help_option(type)) {
 GPtrArray *nic_models = qemu_get_nic_models(TYPE_DEVICE);
+int i;
 show_netdevs();
 printf("\n");
-qemu_show_nic_models(type, (const char **)nic_models->pdata);
+printf("Supported NIC models "
+   "(use -nic model=help for a filtered list):\n");
+for (i = 0 ; nic_models->pdata[i]; i++) {
+printf("%s\n", (char *)nic_models->pdata[i]);
+}
 g_ptr_array_free(nic_models, true);
 exit(0);
 }
-- 
2.40.1




[PATCH 39/45] hw/s390x/s390-virtio-ccw: use qemu_create_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/s390x/s390-virtio-ccw.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 2d75f2131f..b8b8a2a201 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -217,16 +217,9 @@ static void s390_init_ipl_dev(const char *kernel_filename,
 
 static void s390_create_virtio_net(BusState *bus, const char *name)
 {
-int i;
-
-for (i = 0; i < nb_nics; i++) {
-NICInfo *nd = &nd_table[i];
-DeviceState *dev;
-
-qemu_check_nic_model(nd, "virtio");
+DeviceState *dev;
 
-dev = qdev_new(name);
-qdev_set_nic_properties(dev, nd);
+while ((dev = qemu_create_nic_device(name, true, "virtio")) {
 qdev_realize_and_unref(dev, bus, &error_fatal);
 }
 }
-- 
2.40.1




[PATCH 29/45] hw/arm/stellaris: use qemu_find_nic_info()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Rather than just using qemu_configure_nic_device(), populate the MAC
address in the system-registers device by peeking at the NICInfo before
it's assigned to the device.

Generate the MAC address early, if there is no matching -nic option.
Otherwise the MAC address wouldn't be generated until net_client_init1()
runs.

Signed-off-by: David Woodhouse 
---
 hw/arm/stellaris.c | 30 ++
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index aa5b0ddfaa..9385ccaafb 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1025,7 +1025,8 @@ static void stellaris_init(MachineState *ms, 
stellaris_board_info *board)
 DeviceState *ssys_dev;
 int i;
 int j;
-const uint8_t *macaddr;
+NICInfo *nd;
+MACAddr mac;
 
 MemoryRegion *sram = g_new(MemoryRegion, 1);
 MemoryRegion *flash = g_new(MemoryRegion, 1);
@@ -1048,12 +1049,22 @@ static void stellaris_init(MachineState *ms, 
stellaris_board_info *board)
  * need its sysclk output.
  */
 ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
-/* Most devices come preprogrammed with a MAC address in the user data. */
-macaddr = nd_table[0].macaddr.a;
+
+/*
+ * Most devices come preprogrammed with a MAC address in the user data.
+ * Generate a MAC address now, if there isn't a matching -nic for it.
+ */
+nd = qemu_find_nic_info("stellaris_enet", true, "stellaris");
+if (nd) {
+memcpy(mac.a, nd->macaddr.a, sizeof(mac.a));
+} else {
+qemu_macaddr_default_if_unset(&mac);
+}
+
 qdev_prop_set_uint32(ssys_dev, "user0",
- macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16));
+ mac.a[0] | (mac.a[1] << 8) | (mac.a[2] << 16));
 qdev_prop_set_uint32(ssys_dev, "user1",
- macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16));
+ mac.a[3] | (mac.a[4] << 8) | (mac.a[5] << 16));
 qdev_prop_set_uint32(ssys_dev, "did0", board->did0);
 qdev_prop_set_uint32(ssys_dev, "did1", board->did1);
 qdev_prop_set_uint32(ssys_dev, "dc0", board->dc0);
@@ -1265,10 +1276,13 @@ static void stellaris_init(MachineState *ms, 
stellaris_board_info *board)
 if (board->dc4 & (1 << 28)) {
 DeviceState *enet;
 
-qemu_check_nic_model(&nd_table[0], "stellaris");
-
 enet = qdev_new("stellaris_enet");
-qdev_set_nic_properties(enet, &nd_table[0]);
+if (nd) {
+qdev_set_nic_properties(enet, nd);
+} else {
+qdev_prop_set_macaddr(enet, "mac", mac.a);
+}
+
 sysbus_realize_and_unref(SYS_BUS_DEVICE(enet), &error_fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(enet), 0, 0x40048000);
 sysbus_connect_irq(SYS_BUS_DEVICE(enet), 0, qdev_get_gpio_in(nvic, 
42));
-- 
2.40.1




[PATCH 32/45] hw/m68k/mcf5208: use qemu_create_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/m68k/mcf5208.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index be1033f84f..cf23b7dc6e 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -206,16 +206,16 @@ static void mcf5208_sys_init(MemoryRegion *address_space, 
qemu_irq *pic)
 }
 }
 
-static void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd, hwaddr base,
- qemu_irq *irqs)
+static void mcf_fec_init(MemoryRegion *sysmem, hwaddr base, qemu_irq *irqs)
 {
 DeviceState *dev;
 SysBusDevice *s;
 int i;
 
-qemu_check_nic_model(nd, TYPE_MCF_FEC_NET);
-dev = qdev_new(TYPE_MCF_FEC_NET);
-qdev_set_nic_properties(dev, nd);
+dev = qemu_create_nic_device(TYPE_MCF_FEC_NET, true, NULL);
+if (!dev) {
+return;
+}
 
 s = SYS_BUS_DEVICE(dev);
 sysbus_realize_and_unref(s, &error_fatal);
@@ -267,17 +267,9 @@ static void mcf5208evb_init(MachineState *machine)
 
 mcf5208_sys_init(address_space_mem, pic);
 
-if (nb_nics > 1) {
-error_report("Too many NICs");
-exit(1);
-}
-if (nd_table[0].used) {
-mcf_fec_init(address_space_mem, &nd_table[0],
- 0xfc03, pic + 36);
-}
+mcf_fec_init(address_space_mem, 0xfc03, pic + 36);
 
 g_free(pic);
-
 /*  0xfc00 SCM.  */
 /*  0xfc004000 XBS.  */
 /*  0xfc008000 FlexBus CS.  */
-- 
2.40.1




[PATCH 25/45] hw/net/smc91c111: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Some callers instantiate the device unconditionally, others will do so only
if there is a NICInfo to go with it. This appears to be fairly random, but
preserve the existing behaviour for now.

Signed-off-by: David Woodhouse 
---
 hw/arm/gumstix.c   |  6 ++
 hw/arm/integratorcp.c  |  5 +++--
 hw/arm/mainstone.c |  3 +--
 hw/arm/realview.c  | 25 ++---
 hw/arm/versatilepb.c   | 15 ---
 hw/net/smc91c111.c |  5 ++---
 include/hw/net/smc91c111.h |  2 +-
 7 files changed, 23 insertions(+), 38 deletions(-)

diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 2ca4140c9f..f58c4da7f9 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -74,8 +74,7 @@ static void connex_init(MachineState *machine)
   FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0);
 
 /* Interrupt line of NIC is connected to GPIO line 36 */
-smc91c111_init(&nd_table[0], 0x04000300,
-qdev_get_gpio_in(cpu->gpio, 36));
+smc91c111_init(0x04000300, qdev_get_gpio_in(cpu->gpio, 36));
 }
 
 static void verdex_init(MachineState *machine)
@@ -98,8 +97,7 @@ static void verdex_init(MachineState *machine)
   FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0);
 
 /* Interrupt line of NIC is connected to GPIO line 99 */
-smc91c111_init(&nd_table[0], 0x04000300,
-qdev_get_gpio_in(cpu->gpio, 99));
+smc91c111_init(0x04000300, qdev_get_gpio_in(cpu->gpio, 99));
 }
 
 static void connex_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index d176e9af7e..29bc128992 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -669,8 +669,9 @@ static void integratorcp_init(MachineState *machine)
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x1d00);
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[25]);
 
-if (nd_table[0].used)
-smc91c111_init(&nd_table[0], 0xc800, pic[27]);
+if (qemu_find_nic_info("smc91c111", true, NULL)) {
+smc91c111_init(0xc800, pic[27]);
+}
 
 sysbus_create_simple("pl110", 0xc000, pic[22]);
 
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 68329c4617..84dbb6e525 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -153,8 +153,7 @@ static void mainstone_common_init(MachineState *machine,
 qdev_get_gpio_in(mst_irq, S1_IRQ),
 qdev_get_gpio_in(mst_irq, S1_CD_IRQ));
 
-smc91c111_init(&nd_table[0], MST_ETH_PHYS,
-qdev_get_gpio_in(mst_irq, ETHERNET_IRQ));
+smc91c111_init(MST_ETH_PHYS, qdev_get_gpio_in(mst_irq, ETHERNET_IRQ));
 
 mainstone_binfo.board_id = arm_id;
 arm_load_kernel(mpu->cpu, machine, &mainstone_binfo);
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 8f89526596..591f50581e 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -89,7 +89,6 @@ static void realview_init(MachineState *machine,
 I2CBus *i2c;
 int n;
 unsigned int smp_cpus = machine->smp.cpus;
-int done_nic = 0;
 qemu_irq cpu_irq[4];
 int is_mpcore = 0;
 int is_pb = 0;
@@ -295,24 +294,20 @@ static void realview_init(MachineState *machine,
 n--;
 }
 }
-for(n = 0; n < nb_nics; n++) {
-nd = &nd_table[n];
-
-if (!done_nic && (!nd->model ||
-strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) {
-if (is_pb) {
-lan9118_init(nd, 0x4e00, pic[28]);
-} else {
-smc91c111_init(nd, 0x4e00, pic[28]);
-}
-done_nic = 1;
+
+nd = qemu_find_nic_info(is_pb ? "lan9118" : "smc91c111", true, NULL);
+if (nd) {
+if (is_pb) {
+lan9118_init(nd, 0x4e00, pic[28]);
 } else {
-if (pci_bus) {
-pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL);
-}
+smc91c111_init(0x4e00, pic[28]);
 }
 }
 
+if (pci_bus) {
+pci_init_nic_devices(pci_bus, "rtl8139");
+}
+
 dev = sysbus_create_simple(TYPE_ARM_SBCON_I2C, 0x10002000, NULL);
 i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
 i2c_slave_create_simple(i2c, "ds1338", 0x68);
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 2f22dc890f..7bf2ba7c21 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -192,10 +192,8 @@ static void versatile_init(MachineState *machine, int 
board_id)
 SysBusDevice *busdev;
 DeviceState *pl041;
 PCIBus *pci_bus;
-NICInfo *nd;
 I2CBus *i2c;
 int n;
-int done_smc = 0;
 DriveInfo *dinfo;
 
 if (machine->ram_size > 0x1000) {
@@ -263,16 +261,11 @@ static void versatile_init(MachineState *machine, int 
board_id)
 sysbus_connect_irq(busdev, 3, sic[30]);
 pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
 
-for(n = 0; n < nb_nics; n++) {
-nd = &nd_table[n];
-
-if (!done_smc 

[PATCH 01/45] net: add qemu_{configure,create}_nic_device(), qemu_find_nic_info()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Most code which directly accesses nd_table[] and nb_nics uses them for
one of two things. Either "I have created a NIC device and I'd like a
configuration for it", or "I will create a NIC device *if* there is a
configuration for it".  With some variants on the theme around whether
they actually *check* if the model specified in the configuration is
the right one.

Provide functions which perform both of those, allowing platforms to
be a little more consistent and as a step towards making nd_table[]
and nb_nics private to the net code.

Also export the qemu_find_nic_info() helper, as some platforms have
special cases they need to handle.

Signed-off-by: David Woodhouse 
---
 include/net/net.h |  7 ++-
 net/net.c | 50 +++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/include/net/net.h b/include/net/net.h
index 2fb1c9181c..56be694c75 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -205,7 +205,12 @@ int qemu_show_nic_models(const char *arg, const char 
*const *models);
 void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
-
+NICInfo *qemu_find_nic_info(const char *typename, bool match_default,
+const char *alias);
+bool qemu_configure_nic_device(DeviceState *dev, bool match_default,
+   const char *alias);
+DeviceState *qemu_create_nic_device(const char *typename, bool match_default,
+const char *alias);
 void print_net_client(Monitor *mon, NetClientState *nc);
 void net_socket_rs_init(SocketReadState *rs,
 SocketReadStateFinalize *finalize,
diff --git a/net/net.c b/net/net.c
index bbe33da176..606816a3b3 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1072,6 +1072,56 @@ static int net_init_nic(const Netdev *netdev, const char 
*name,
 return idx;
 }
 
+NICInfo *qemu_find_nic_info(const char *typename, bool match_default,
+const char *alias)
+{
+NICInfo *nd;
+int i;
+
+for (i = 0; i < nb_nics; i++) {
+nd = &nd_table[i];
+
+if (!nd->used || nd->instantiated)
+continue;
+
+if ((match_default && !nd->model) || !g_strcmp0(nd->model, typename)
+|| (alias && !g_strcmp0(nd->model, alias))) {
+return nd;
+}
+}
+return NULL;
+}
+
+
+/* "I have created a device. Please configure it if you can" */
+bool qemu_configure_nic_device(DeviceState *dev, bool match_default,
+   const char *alias)
+{
+NICInfo *nd = qemu_find_nic_info(object_get_typename(OBJECT(dev)),
+ match_default, alias);
+
+if (nd) {
+qdev_set_nic_properties(dev, nd);
+return true;
+}
+return false;
+}
+
+/* "Please create a device, if you have a configuration for it" */
+DeviceState *qemu_create_nic_device(const char *typename, bool match_default,
+const char *alias)
+{
+NICInfo *nd = qemu_find_nic_info(typename, match_default, alias);
+DeviceState *dev;
+
+if (!nd) {
+return NULL;
+}
+
+dev = qdev_new(typename);
+qdev_set_nic_properties(dev, nd);
+return dev;
+}
 
 static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
 const Netdev *netdev,
-- 
2.40.1




[PATCH 09/45] hw/arm/virt: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/arm/virt.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 15e74249f9..6b43b92b89 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1477,9 +1477,7 @@ static void create_pcie(VirtMachineState *vms)
 pci->bypass_iommu = vms->default_bus_bypass_iommu;
 vms->bus = pci->bus;
 if (vms->bus) {
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci->bus, mc->default_nic, NULL);
-}
+pci_init_nic_devices(pci->bus, mc->default_nic);
 }
 
 nodename = vms->pciehb_nodename = g_strdup_printf("/pcie@%" PRIx64, base);
-- 
2.40.1




[PATCH 13/45] hw/mips/malta: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

The Malta board setup code would previously place the first NIC into PCI
slot 11 if was a PCNet card, and the rest (including the first if it was
anything other than a PCNet card) would be dynamically assigned.

Now it will place any PCNet NIC into slot 11, and then anything else will
be dynamically assigned.

Signed-off-by: David Woodhouse 
---
 hw/mips/malta.c | 15 +++
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index dac27fad9d..9357cb4c91 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -606,18 +606,9 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion 
*address_space,
 /* Network support */
 static void network_init(PCIBus *pci_bus)
 {
-int i;
-
-for (i = 0; i < nb_nics; i++) {
-NICInfo *nd = &nd_table[i];
-const char *default_devaddr = NULL;
-
-if (i == 0 && (!nd->model || strcmp(nd->model, "pcnet") == 0))
-/* The malta board has a PCNet card using PCI SLOT 11 */
-default_devaddr = "0b";
-
-pci_nic_init_nofail(nd, pci_bus, "pcnet", default_devaddr);
-}
+/* The malta board has a PCNet card using PCI SLOT 11 */
+pci_init_nic_in_slot(pci_bus, "pcnet", NULL, "0b");
+pci_init_nic_devices(pci_bus, "pcnet");
 }
 
 static void bl_setup_gt64120_jump_kernel(void **p, uint64_t run_addr,
-- 
2.40.1




[PATCH 20/45] hw/xtensa/virt: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/xtensa/virt.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/xtensa/virt.c b/hw/xtensa/virt.c
index a6cf646e99..5310a88861 100644
--- a/hw/xtensa/virt.c
+++ b/hw/xtensa/virt.c
@@ -102,9 +102,7 @@ static void create_pcie(MachineState *ms, CPUXtensaState 
*env, int irq_base,
 
 pci = PCI_HOST_BRIDGE(dev);
 if (pci->bus) {
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci->bus, mc->default_nic, NULL);
-}
+pci_init_nic_devices(pci->bus, mc->default_nic);
 }
 }
 
-- 
2.40.1




[PATCH 22/45] hw/arm/aspeed: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/arm/aspeed.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index f8ba67531a..945ad97835 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -356,7 +356,6 @@ static void aspeed_machine_init(MachineState *machine)
 AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
 AspeedSoCClass *sc;
 int i;
-NICInfo *nd = &nd_table[0];
 
 object_initialize_child(OBJECT(machine), "soc", &bmc->soc, amc->soc_name);
 
@@ -370,10 +369,10 @@ static void aspeed_machine_init(MachineState *machine)
  &error_fatal);
 
 for (i = 0; i < sc->macs_num; i++) {
-if ((amc->macs_mask & (1 << i)) && nd->used) {
-qemu_check_nic_model(nd, TYPE_FTGMAC100);
-qdev_set_nic_properties(DEVICE(&bmc->soc.ftgmac100[i]), nd);
-nd++;
+if ((amc->macs_mask & (1 << i)) &&
+!qemu_configure_nic_device(DEVICE(&bmc->soc.ftgmac100[i]),
+   true, NULL)) {
+break; /* No configs left; stop asking */
 }
 }
 
-- 
2.40.1




[PATCH 40/45] hw/sparc/sun4m: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/sparc/sun4m.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 17bf5f2879..259cf2f383 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -299,7 +299,7 @@ static void *iommu_init(hwaddr addr, uint32_t version, 
qemu_irq irq)
 
 static void *sparc32_dma_init(hwaddr dma_base,
   hwaddr esp_base, qemu_irq espdma_irq,
-  hwaddr le_base, qemu_irq ledma_irq, NICInfo *nd)
+  hwaddr le_base, qemu_irq ledma_irq)
 {
 DeviceState *dma;
 ESPDMADeviceState *espdma;
@@ -320,7 +320,7 @@ static void *sparc32_dma_init(hwaddr dma_base,
 
 lance = SYSBUS_PCNET(object_resolve_path_component(
  OBJECT(ledma), "lance"));
-qdev_set_nic_properties(DEVICE(lance), nd);
+qemu_configure_nic_device(DEVICE(lance), true, NULL);
 
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dma), &error_fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(dma), 0, dma_base);
@@ -832,7 +832,6 @@ static void sun4m_hw_init(MachineState *machine)
 unsigned int smp_cpus = machine->smp.cpus;
 unsigned int max_cpus = machine->smp.max_cpus;
 HostMemoryBackend *ram_memdev = machine->memdev;
-NICInfo *nd = &nd_table[0];
 
 if (machine->ram_size > hwdef->max_mem) {
 error_report("Too much memory for this machine: %" PRId64 ","
@@ -893,10 +892,9 @@ static void sun4m_hw_init(MachineState *machine)
 hwdef->iommu_pad_base, hwdef->iommu_pad_len);
 }
 
-qemu_check_nic_model(nd, TYPE_LANCE);
 sparc32_dma_init(hwdef->dma_base,
  hwdef->esp_base, slavio_irq[18],
- hwdef->le_base, slavio_irq[16], nd);
+ hwdef->le_base, slavio_irq[16]);
 
 if (graphic_depth != 8 && graphic_depth != 24) {
 error_report("Unsupported depth: %d", graphic_depth);
-- 
2.40.1




[PATCH 04/45] hw/pci: add pci_init_nic_devices(), pci_init_nic_in_slot()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

The loop over nd_table[] to add PCI NICs is repeated in quite a few
places. Add a helper function to do it.

Some platforms also try to instantiate a specific model in a specific
slot, to match the real hardware. Add pci_init_nic_in_slot() for that
purpose.

Signed-off-by: David Woodhouse 
---
 hw/pci/pci.c | 45 
 include/hw/pci/pci.h |  4 +++-
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index b0d21bf43a..904f189d30 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1932,6 +1932,51 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus 
*rootbus,
 return pci_dev;
 }
 
+void pci_init_nic_devices(PCIBus *bus, const char *default_model)
+{
+qemu_create_nic_bus_devices(&bus->qbus, TYPE_PCI_DEVICE, default_model,
+"virtio", "virtio-net-pci");
+}
+
+bool pci_init_nic_in_slot(PCIBus *rootbus, const char *model,
+  const char *alias, const char *devaddr)
+{
+NICInfo *nd = qemu_find_nic_info(model, true, alias);
+int dom, busnr, devfn;
+PCIDevice *pci_dev;
+unsigned slot;
+PCIBus *bus;
+
+if (!nd) {
+return false;
+}
+
+if (!devaddr || pci_parse_devaddr(devaddr, &dom, &busnr, &slot, NULL) < 0) 
{
+error_report("Invalid PCI device address %s for device %s",
+ devaddr, model);
+exit(1);
+}
+
+if (dom != 0) {
+error_report("No support for non-zero PCI domains");
+exit(1);
+}
+
+devfn = PCI_DEVFN(slot, 0);
+
+bus = pci_find_bus_nr(rootbus, busnr);
+if (!bus) {
+error_report("Invalid PCI device address %s for device %s",
+ devaddr, model);
+exit(1);
+}
+
+pci_dev = pci_new(devfn, model);
+qdev_set_nic_properties(&pci_dev->qdev, nd);
+pci_realize_and_unref(pci_dev, bus, &error_fatal);
+return true;
+}
+
 PCIDevice *pci_vga_init(PCIBus *bus)
 {
 vga_interface_created = true;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index b70a0b95ff..76d3ddab25 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -320,7 +320,9 @@ void pci_device_reset(PCIDevice *dev);
 PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
const char *default_model,
const char *default_devaddr);
-
+void pci_init_nic_devices(PCIBus *bus, const char *default_model);
+bool pci_init_nic_in_slot(PCIBus *rootbus, const char *default_model,
+  const char *alias, const char *devaddr);
 PCIDevice *pci_vga_init(PCIBus *bus);
 
 static inline PCIBus *pci_get_bus(const PCIDevice *dev)
-- 
2.40.1




[PATCH 30/45] hw/arm: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/arm/mps2-tz.c |  8 ++--
 hw/arm/msf2-soc.c|  6 +-
 hw/arm/musicpal.c|  3 +--
 hw/arm/xilinx_zynq.c | 11 ---
 hw/arm/xlnx-versal.c |  7 +--
 hw/arm/xlnx-zynqmp.c |  8 +---
 6 files changed, 10 insertions(+), 33 deletions(-)

diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index eae3639da2..6808143a07 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -499,14 +499,12 @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState 
*mms, void *opaque,
   const PPCExtraData *extradata)
 {
 SysBusDevice *s;
-NICInfo *nd = &nd_table[0];
 
 /* In hardware this is a LAN9220; the LAN9118 is software compatible
  * except that it doesn't support the checksum-offload feature.
  */
-qemu_check_nic_model(nd, "lan9118");
 mms->lan9118 = qdev_new(TYPE_LAN9118);
-qdev_set_nic_properties(mms->lan9118, nd);
+qemu_configure_nic_device(mms->lan9118, true, NULL);
 
 s = SYS_BUS_DEVICE(mms->lan9118);
 sysbus_realize_and_unref(s, &error_fatal);
@@ -524,7 +522,6 @@ static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, 
void *opaque,
  * irqs[] is the ethernet IRQ.
  */
 SysBusDevice *s;
-NICInfo *nd = &nd_table[0];
 
 memory_region_init(&mms->eth_usb_container, OBJECT(mms),
"mps2-tz-eth-usb-container", 0x20);
@@ -533,9 +530,8 @@ static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, 
void *opaque,
  * In hardware this is a LAN9220; the LAN9118 is software compatible
  * except that it doesn't support the checksum-offload feature.
  */
-qemu_check_nic_model(nd, "lan9118");
 mms->lan9118 = qdev_new(TYPE_LAN9118);
-qdev_set_nic_properties(mms->lan9118, nd);
+qemu_configure_nic_device(mms->lan9118, true, NULL);
 
 s = SYS_BUS_DEVICE(mms->lan9118);
 sysbus_realize_and_unref(s, &error_fatal);
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
index b5fe9f364d..35bf1d64e1 100644
--- a/hw/arm/msf2-soc.c
+++ b/hw/arm/msf2-soc.c
@@ -197,12 +197,8 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error 
**errp)
 g_free(bus_name);
 }
 
-/* FIXME use qdev NIC properties instead of nd_table[] */
-if (nd_table[0].used) {
-qemu_check_nic_model(&nd_table[0], TYPE_MSS_EMAC);
-qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
-}
 dev = DEVICE(&s->emac);
+qemu_configure_nic_device(dev, true, NULL);
 object_property_set_link(OBJECT(&s->emac), "ahb-bus",
  OBJECT(get_system_memory()), &error_abort);
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->emac), errp)) {
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 9703bfb97f..a60139ce53 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1286,9 +1286,8 @@ static void musicpal_init(MachineState *machine)
 }
 sysbus_create_simple(TYPE_MV88W8618_FLASHCFG, MP_FLASHCFG_BASE, NULL);
 
-qemu_check_nic_model(&nd_table[0], "mv88w8618");
 dev = qdev_new(TYPE_MV88W8618_ETH);
-qdev_set_nic_properties(dev, &nd_table[0]);
+qemu_configure_nic_device(dev, true, "mv88w8618");
 object_property_set_link(OBJECT(dev), "dma-memory",
  OBJECT(get_system_memory()), &error_fatal);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 8dc2ea83a9..bc093b6f77 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -108,16 +108,13 @@ static void zynq_write_board_setup(ARMCPU *cpu,
 
 static struct arm_boot_info zynq_binfo = {};
 
-static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
+static void gem_init(uint32_t base, qemu_irq irq)
 {
 DeviceState *dev;
 SysBusDevice *s;
 
 dev = qdev_new(TYPE_CADENCE_GEM);
-if (nd->used) {
-qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
-qdev_set_nic_properties(dev, nd);
-}
+qemu_configure_nic_device(dev, true, NULL);
 object_property_set_int(OBJECT(dev), "phy-addr", 7, &error_abort);
 s = SYS_BUS_DEVICE(dev);
 sysbus_realize_and_unref(s, &error_fatal);
@@ -279,8 +276,8 @@ static void zynq_init(MachineState *machine)
 sysbus_create_varargs("cadence_ttc", 0xF8002000,
 pic[69-IRQ_OFFSET], pic[70-IRQ_OFFSET], pic[71-IRQ_OFFSET], NULL);
 
-gem_init(&nd_table[0], 0xE000B000, pic[54-IRQ_OFFSET]);
-gem_init(&nd_table[1], 0xE000C000, pic[77-IRQ_OFFSET]);
+gem_init(0xE000B000, pic[54-IRQ_OFFSET]);
+gem_init(0xE000C000, pic[77-IRQ_OFFSET]);
 
 for (n = 0; n < 2; n++) {
 int hci_irq = n ? 79 : 56;
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index fa556d8764..08106f172c 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -249,18 +249,13 @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
 static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0};
 stati

[PATCH 43/45] hw/pci: remove pci_nic_init_nofail()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

This function is no longer used.

Signed-off-by: David Woodhouse 
---
 hw/pci/pci.c | 72 
 include/hw/pci/pci.h |  3 --
 2 files changed, 75 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 904f189d30..439458374e 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1860,78 +1860,6 @@ const pci_class_desc *get_class_desc(int class)
 return desc;
 }
 
-/* Initialize a PCI NIC.  */
-PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
-   const char *default_model,
-   const char *default_devaddr)
-{
-const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
-GPtrArray *pci_nic_models;
-PCIBus *bus;
-PCIDevice *pci_dev;
-DeviceState *dev;
-int devfn;
-int i;
-int dom, busnr;
-unsigned slot;
-
-if (nd->model && !strcmp(nd->model, "virtio")) {
-g_free(nd->model);
-nd->model = g_strdup("virtio-net-pci");
-}
-
-pci_nic_models = qemu_get_nic_models(TYPE_PCI_DEVICE);
-
-if (qemu_show_nic_models(nd->model, (const char **)pci_nic_models->pdata)) 
{
-exit(0);
-}
-
-i = qemu_find_nic_model(nd, (const char **)pci_nic_models->pdata,
-default_model);
-if (i < 0) {
-exit(1);
-}
-
-if (!rootbus) {
-error_report("No primary PCI bus");
-exit(1);
-}
-
-assert(!rootbus->parent_dev);
-
-if (!devaddr) {
-devfn = -1;
-busnr = 0;
-} else {
-if (pci_parse_devaddr(devaddr, &dom, &busnr, &slot, NULL) < 0) {
-error_report("Invalid PCI device address %s for device %s",
- devaddr, nd->model);
-exit(1);
-}
-
-if (dom != 0) {
-error_report("No support for non-zero PCI domains");
-exit(1);
-}
-
-devfn = PCI_DEVFN(slot, 0);
-}
-
-bus = pci_find_bus_nr(rootbus, busnr);
-if (!bus) {
-error_report("Invalid PCI device address %s for device %s",
- devaddr, nd->model);
-exit(1);
-}
-
-pci_dev = pci_new(devfn, nd->model);
-dev = &pci_dev->qdev;
-qdev_set_nic_properties(dev, nd);
-pci_realize_and_unref(pci_dev, bus, &error_fatal);
-g_ptr_array_free(pci_nic_models, true);
-return pci_dev;
-}
-
 void pci_init_nic_devices(PCIBus *bus, const char *default_model)
 {
 qemu_create_nic_bus_devices(&bus->qbus, TYPE_PCI_DEVICE, default_model,
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 76d3ddab25..7ea36467a5 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -317,9 +317,6 @@ void pci_device_set_intx_routing_notifier(PCIDevice *dev,
   PCIINTxRoutingNotifier notifier);
 void pci_device_reset(PCIDevice *dev);
 
-PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
-   const char *default_model,
-   const char *default_devaddr);
 void pci_init_nic_devices(PCIBus *bus, const char *default_model);
 bool pci_init_nic_in_slot(PCIBus *rootbus, const char *default_model,
   const char *alias, const char *devaddr);
-- 
2.40.1




[PATCH 17/45] hw/ppc: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/ppc/e500.c  |  4 +---
 hw/ppc/mac_newworld.c  |  4 +---
 hw/ppc/mac_oldworld.c  |  4 +---
 hw/ppc/ppc440_bamboo.c | 13 +
 4 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index e04114fb3c..f62eeb3411 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1075,9 +1075,7 @@ void ppce500_init(MachineState *machine)
 
 if (pci_bus) {
 /* Register network interfaces. */
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
-}
+pci_init_nic_devices(pci_bus, mc->default_nic);
 }
 
 /* Register spinning region */
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 535710314a..b36dbaf2b6 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -444,9 +444,7 @@ static void ppc_core99_init(MachineState *machine)
 graphic_depth = 15;
 }
 
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
-}
+pci_init_nic_devices(pci_bus, mc->default_nic);
 
 /* The NewWorld NVRAM is not located in the MacIO device */
 if (kvm_enabled() && qemu_real_host_page_size() > 4096) {
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 9acc7adfc9..1981d3d8f6 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -277,9 +277,7 @@ static void ppc_heathrow_init(MachineState *machine)
 
 pci_vga_init(pci_bus);
 
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
-}
+pci_init_nic_devices(pci_bus, mc->default_nic);
 
 /* MacIO IDE */
 ide_drive_get(hd, ARRAY_SIZE(hd));
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 45f409c838..e63289144a 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -235,14 +235,11 @@ static void bamboo_init(MachineState *machine)
 }
 
 if (pcibus) {
-/* Register network interfaces. */
-for (i = 0; i < nb_nics; i++) {
-/*
- * There are no PCI NICs on the Bamboo board, but there are
- * PCI slots, so we can pick whatever default model we want.
- */
-pci_nic_init_nofail(&nd_table[i], pcibus, mc->default_nic, NULL);
-}
+/*
+ * There are no PCI NICs on the Bamboo board, but there are
+ * PCI slots, so we can pick whatever default model we want.
+ */
+pci_init_nic_devices(pcibus, mc->default_nic);
 }
 
 /* Load kernel. */
-- 
2.40.1




[PATCH 07/45] hw/alpha/dp264: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/alpha/dp264.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index 03495e1e60..52a1fa310b 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -124,9 +124,7 @@ static void clipper_init(MachineState *machine)
 pci_vga_init(pci_bus);
 
 /* Network setup.  e1000 is good enough, failing Tulip support.  */
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
-}
+pci_init_nic_devices(pci_bus, mc->default_nic);
 
 /* Super I/O */
 isa_create_simple(isa_bus, TYPE_SMC37C669_SUPERIO);
-- 
2.40.1




[PATCH 15/45] hw/ppc/prep: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Previously, the first PCI NIC would be placed in PCI slot 3 and the rest
would be dynamically assigned. Even if the user overrode the default NIC
type and made it something other than PCNet.

Now, the first PCNet NIC (that is, anything not explicitly specified
to be anything different) will go to slot 3 even if it isn't the first
NIC specified on the commnd line. And anything else will be dynamically
assigned.

Signed-off-by: David Woodhouse 
---
 hw/ppc/prep.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 137276bcb9..1a08e74945 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -336,10 +336,9 @@ static void ibm_40p_init(MachineState *machine)
 /* XXX: s3-trio at PCI_DEVFN(2, 0) */
 pci_vga_init(pci_bus);
 
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic,
-i == 0 ? "3" : NULL);
-}
+/* First PCNET device at PCI_DEVFN(3, 0) */
+pci_init_nic_in_slot(pci_bus, mc->default_nic, NULL, "3");
+pci_init_nic_devices(pci_bus, mc->default_nic);
 }
 
 /* Prepare firmware configuration for OpenBIOS */
-- 
2.40.1




[PATCH 19/45] hw/sparc64/sun4u: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

The first sunhme NIC gets placed a function 1 on slot 1 of PCI bus A,
and the rest are dynamically assigned on PCI bus B.

Previously, any PCI NIC would get the special treatment purely by
virtue of being first in the list.

Signed-off-by: David Woodhouse 
---
 hw/sparc64/sun4u.c | 27 ---
 1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index d908a38f73..13e4380f30 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -642,29 +642,18 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
 
 memset(&macaddr, 0, sizeof(MACAddr));
 onboard_nic = false;
-for (i = 0; i < nb_nics; i++) {
-PCIBus *bus;
-nd = &nd_table[i];
-
-if (!nd->model || strcmp(nd->model, mc->default_nic) == 0) {
-if (!onboard_nic) {
-pci_dev = pci_new_multifunction(PCI_DEVFN(1, 1), 
mc->default_nic);
-bus = pci_busA;
-memcpy(&macaddr, &nd->macaddr.a, sizeof(MACAddr));
-onboard_nic = true;
-} else {
-pci_dev = pci_new(-1, mc->default_nic);
-bus = pci_busB;
-}
-} else {
-pci_dev = pci_new(-1, nd->model);
-bus = pci_busB;
-}
 
+nd = qemu_find_nic_info(mc->default_nic, true, NULL);
+if (nd) {
+pci_dev = pci_new_multifunction(PCI_DEVFN(1, 1), mc->default_nic);
 dev = &pci_dev->qdev;
 qdev_set_nic_properties(dev, nd);
-pci_realize_and_unref(pci_dev, bus, &error_fatal);
+pci_realize_and_unref(pci_dev, pci_busA, &error_fatal);
+
+memcpy(&macaddr, &nd->macaddr.a, sizeof(MACAddr));
+onboard_nic = true;
 }
+pci_init_nic_devices(pci_busB, mc->default_nic);
 
 /* If we don't have an onboard NIC, grab a default MAC address so that
  * we have a valid machine id */
-- 
2.40.1




[PATCH 16/45] hw/ppc/spapr: use qemu_get_nic_info() and pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Avoid directly referencing nd_table[] by first instantiating any
spapr-vlan devices using a qemu_get_nic_info() loop, then calling
pci_init_nic_devices() to do the rest.

No functional change intended.

Signed-off-by: David Woodhouse 
---
 hw/ppc/spapr.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index cb840676d3..7db6c6641a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2775,6 +2775,7 @@ static void spapr_machine_init(MachineState *machine)
 MemoryRegion *sysmem = get_system_memory();
 long load_limit, fw_size;
 Error *resize_hpt_err = NULL;
+NICInfo *nd;
 
 if (!filename) {
 error_report("Could not find LPAR firmware '%s'", bios_name);
@@ -2982,21 +2983,12 @@ static void spapr_machine_init(MachineState *machine)
 
 phb = spapr_create_default_phb();
 
-for (i = 0; i < nb_nics; i++) {
-NICInfo *nd = &nd_table[i];
-
-if (!nd->model) {
-nd->model = g_strdup("spapr-vlan");
-}
-
-if (g_str_equal(nd->model, "spapr-vlan") ||
-g_str_equal(nd->model, "ibmveth")) {
-spapr_vlan_create(spapr->vio_bus, nd);
-} else {
-pci_nic_init_nofail(&nd_table[i], phb->bus, nd->model, NULL);
-}
+while ((nd = qemu_get_nic_info("spapr-vlan", true, "ibmveth"))) {
+spapr_vlan_create(spapr->vio_bus, nd);
 }
 
+pci_init_nic_devices(phb->bus, NULL);
+
 for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) {
 spapr_vscsi_create(spapr->vio_bus);
 }
-- 
2.40.1




[PATCH 23/45] hw/arm/exynos4: use qemu_create_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/arm/exynos4_boards.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index ef5bcbc212..b804357e2a 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -76,10 +76,8 @@ static void lan9215_init(uint32_t base, qemu_irq irq)
 SysBusDevice *s;
 
 /* This should be a 9215 but the 9118 is close enough */
-if (nd_table[0].used) {
-qemu_check_nic_model(&nd_table[0], "lan9118");
-dev = qdev_new(TYPE_LAN9118);
-qdev_set_nic_properties(dev, &nd_table[0]);
+dev = qemu_create_nic_device(TYPE_LAN9118, true, NULL);
+if (dev) {
 qdev_prop_set_uint32(dev, "mode_16bit", 1);
 s = SYS_BUS_DEVICE(dev);
 sysbus_realize_and_unref(s, &error_fatal);
-- 
2.40.1




[PATCH 12/45] hw/mips/fuloong2e: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

The previous behaviour was: *if* the first NIC specified on the command
line was an RTL8139 (or unspecified model) then it gets assigned to PCI
slot 7, which is where the Fuloong board had an RTL8139. All other
devices (including the first, if it was specified a anything other then
an rtl8319) get dynamically assigned on the bus.

The new behaviour is subtly different: If the first NIC was given a
specific model *other* than rtl8139, and a subsequent NIC was not,
then the rtl8139 (or unspecified) NIC will go to slot 7 and the rest
will be dynamically assigned.

Signed-off-by: David Woodhouse 
---
 hw/mips/fuloong2e.c | 16 +++-
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index c6109633fe..32a9d9d603 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -202,19 +202,9 @@ static void main_cpu_reset(void *opaque)
 /* Network support */
 static void network_init(PCIBus *pci_bus)
 {
-int i;
-
-for (i = 0; i < nb_nics; i++) {
-NICInfo *nd = &nd_table[i];
-const char *default_devaddr = NULL;
-
-if (i == 0 && (!nd->model || strcmp(nd->model, "rtl8139") == 0)) {
-/* The Fuloong board has a RTL8139 card using PCI SLOT 7 */
-default_devaddr = "07";
-}
-
-pci_nic_init_nofail(nd, pci_bus, "rtl8139", default_devaddr);
-}
+/* The Fuloong board has a RTL8139 card using PCI SLOT 7 */
+pci_init_nic_in_slot(pci_bus, "rtl8139", NULL, "07");
+pci_init_nic_devices(pci_bus, "rtl8139");
 }
 
 static void mips_fuloong2e_init(MachineState *machine)
-- 
2.40.1




[PATCH 28/45] hw/arm/npcm7xx: use qemu_configure_nic_device, allow emc0/emc1 as aliases

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Also update the test to specify which device to attach the test socket
to, and remove the comment lamenting the fact that we can't do so.

Signed-off-by: David Woodhouse 
---
 hw/arm/npcm7xx.c   | 16 +---
 tests/qtest/npcm7xx_emc-test.c | 18 --
 2 files changed, 13 insertions(+), 21 deletions(-)

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 15ff21d047..7124547b50 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -655,8 +655,9 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 
 /*
  * EMC Modules. Cannot fail.
- * The mapping of the device to its netdev backend works as follows:
- * emc[i] = nd_table[i]
+ * Use the available NIC configurations in order, allowing 'emc0' and
+ * 'emc1' to by used as aliases for the model= parameter to override.
+ *
  * This works around the inability to specify the netdev property for the
  * emc device: it's not pluggable and thus the -device option can't be
  * used.
@@ -664,12 +665,13 @@ static void npcm7xx_realize(DeviceState *dev, Error 
**errp)
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_emc_addr) != ARRAY_SIZE(s->emc));
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->emc) != 2);
 for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
-s->emc[i].emc_num = i;
 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->emc[i]);
-if (nd_table[i].used) {
-qemu_check_nic_model(&nd_table[i], TYPE_NPCM7XX_EMC);
-qdev_set_nic_properties(DEVICE(sbd), &nd_table[i]);
-}
+char alias[6];
+
+s->emc[i].emc_num = i;
+snprintf(alias, sizeof(alias), "%u", i);
+qemu_configure_nic_device(DEVICE(sbd), true, alias);
+
 /*
  * The device exists regardless of whether it's connected to a QEMU
  * netdev backend. So always instantiate it even if there is no
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
index b046f1d76a..506f6980d4 100644
--- a/tests/qtest/npcm7xx_emc-test.c
+++ b/tests/qtest/npcm7xx_emc-test.c
@@ -225,21 +225,11 @@ static int *packet_test_init(int module_num, GString 
*cmd_line)
 g_assert_cmpint(ret, != , -1);
 
 /*
- * KISS and use -nic. We specify two nics (both emc{0,1}) because there's
- * currently no way to specify only emc1: The driver implicitly relies on
- * emc[i] == nd_table[i].
+ * KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
+ * in the 'model' field to specify the device to match.
  */
-if (module_num == 0) {
-g_string_append_printf(cmd_line,
-   " -nic socket,fd=%d,model=" TYPE_NPCM7XX_EMC " "
-   " -nic user,model=" TYPE_NPCM7XX_EMC " ",
-   test_sockets[1]);
-} else {
-g_string_append_printf(cmd_line,
-   " -nic user,model=" TYPE_NPCM7XX_EMC " "
-   " -nic socket,fd=%d,model=" TYPE_NPCM7XX_EMC " 
",
-   test_sockets[1]);
-}
+g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
+   test_sockets[1], module_num);
 
 g_test_queue_destroy(packet_test_clear, test_sockets);
 return test_sockets;
-- 
2.40.1




[PATCH 03/45] net: add qemu_create_nic_bus_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

This will instantiate any NICs which live on a given bus type. Each bus
is allowed *one* substitution (for PCI it's virtio → virtio-net-pci, for
Xen it's xen → xen-net-device; no point in overengineering it unless we
actually want more).

Signed-off-by: David Woodhouse 
---
 include/net/net.h |  3 +++
 net/net.c | 53 +++
 2 files changed, 56 insertions(+)

diff --git a/include/net/net.h b/include/net/net.h
index 56be694c75..ce830a47d0 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -211,6 +211,9 @@ bool qemu_configure_nic_device(DeviceState *dev, bool 
match_default,
const char *alias);
 DeviceState *qemu_create_nic_device(const char *typename, bool match_default,
 const char *alias);
+void qemu_create_nic_bus_devices(BusState *bus, const char *parent_type,
+ const char *default_model,
+ const char *alias, const char *alias_target);
 void print_net_client(Monitor *mon, NetClientState *nc);
 void net_socket_rs_init(SocketReadState *rs,
 SocketReadStateFinalize *finalize,
diff --git a/net/net.c b/net/net.c
index 6e20f9d2e9..23fd716b98 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1207,6 +1207,59 @@ DeviceState *qemu_create_nic_device(const char 
*typename, bool match_default,
 return dev;
 }
 
+void qemu_create_nic_bus_devices(BusState *bus, const char *parent_type,
+ const char *default_model,
+ const char *alias, const char *alias_target)
+{
+GPtrArray *nic_models = qemu_get_nic_models(parent_type);
+const char *model;
+DeviceState *dev;
+NICInfo *nd;
+int i;
+
+if (nic_model_help) {
+if (alias_target) {
+add_nic_model_help(alias_target, alias);
+}
+for (i = 0; i < nic_models->len - 1; i++) {
+add_nic_model_help(nic_models->pdata[i], NULL);
+}
+}
+
+/* Drop the NULL terminator which would make g_str_equal() unhappy */
+nic_models->len--;
+
+for (i = 0; i < nb_nics; i++) {
+nd = &nd_table[i];
+
+if (!nd->used || nd->instantiated) {
+continue;
+}
+
+model = nd->model ? nd->model : default_model;
+if (!model) {
+continue;
+}
+
+/* Each bus type is allowed *one* substitution */
+if (g_str_equal(model, alias)) {
+model = alias_target;
+}
+
+if (!g_ptr_array_find_with_equal_func(nic_models, model,
+  g_str_equal, NULL)) {
+/* This NIC does not live on this bus. */
+continue;
+}
+
+dev = qdev_new(model);
+qdev_set_nic_properties(dev, nd);
+qdev_realize_and_unref(dev, bus, &error_fatal);
+}
+
+g_ptr_array_free(nic_models, true);
+}
+
 static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
 const Netdev *netdev,
 const char *name,
-- 
2.40.1




[PATCH 10/45] hw/hppa: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/hppa/machine.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index cf28cb9586..97d9b44c4f 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -272,10 +272,8 @@ static void machine_hppa_init(MachineState *machine)
 qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA));
 }
 
-for (i = 0; i < nb_nics; i++) {
-if (!enable_lasi_lan()) {
-pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
-}
+if (!enable_lasi_lan()) {
+pci_init_nic_devices(pci_bus, mc->default_nic);
 }
 
 /* PS/2 Keyboard/Mouse */
-- 
2.40.1




[PATCH 41/45] hw/xtensa/xtfpga: use qemu_create_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/xtensa/xtfpga.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index fbad1c83a3..519e461354 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -147,8 +147,10 @@ static void xtfpga_net_init(MemoryRegion *address_space,
 SysBusDevice *s;
 MemoryRegion *ram;
 
-dev = qdev_new("open_eth");
-qdev_set_nic_properties(dev, nd);
+dev = qemu_create_nic_device("open_eth", true, NULL);
+if (!dev) {
+return;
+}
 
 s = SYS_BUS_DEVICE(dev);
 sysbus_realize_and_unref(s, &error_fatal);
@@ -301,10 +303,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, 
MachineState *machine)
 memory_region_add_subregion(system_memory, board->io[1], io);
 }
 xtfpga_fpga_init(system_io, 0x0d02, freq);
-if (nd_table[0].used) {
-xtfpga_net_init(system_io, 0x0d03, 0x0d030400, 0x0d80,
-extints[1], nd_table);
-}
+xtfpga_net_init(system_io, 0x0d03, 0x0d030400, 0x0d80, extints[1]);
 
 serial_mm_init(system_io, 0x0d050020, 2, extints[0],
115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
-- 
2.40.1




[PATCH 42/45] net: remove qemu_check_nic_model()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 include/net/net.h |  1 -
 net/net.c | 13 -
 2 files changed, 14 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index ce830a47d0..1512650190 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -202,7 +202,6 @@ int qemu_set_vnet_le(NetClientState *nc, bool is_le);
 int qemu_set_vnet_be(NetClientState *nc, bool is_be);
 void qemu_macaddr_default_if_unset(MACAddr *macaddr);
 int qemu_show_nic_models(const char *arg, const char *const *models);
-void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 NICInfo *qemu_find_nic_info(const char *typename, bool match_default,
diff --git a/net/net.c b/net/net.c
index 23fd716b98..bdb31dcb27 100644
--- a/net/net.c
+++ b/net/net.c
@@ -977,19 +977,6 @@ int qemu_show_nic_models(const char *arg, const char 
*const *models)
 return 1;
 }
 
-void qemu_check_nic_model(NICInfo *nd, const char *model)
-{
-const char *models[2];
-
-models[0] = model;
-models[1] = NULL;
-
-if (qemu_show_nic_models(nd->model, models))
-exit(0);
-if (qemu_find_nic_model(nd, models, model) < 0)
-exit(1);
-}
-
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model)
 {
-- 
2.40.1




[PATCH 11/45] hw/loongarch: use pci_init_nic_devices()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/loongarch/virt.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 2952fe452e..9905e525b1 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -504,9 +504,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, 
LoongArchMachineState *
 fdt_add_uart_node(lams);
 
 /* Network init */
-for (i = 0; i < nb_nics; i++) {
-pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
-}
+pci_init_nic_devices(pci_bus, mc->default_nic);
 
 /*
  * There are some invalid guest memory access.
-- 
2.40.1




[PATCH 06/45] hw/xen: use qemu_create_nic_bus_devices() to instantiate Xen NICs

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

When instantiating XenBus itself, for each NIC which is configured with
either the model unspecified, or set to to "xen" or "xen-net-device",
create a corresponding xen-net-device for it.

Now we can launch emulated Xen guests with '-nic user', and this fixes
the setup for Xen PV guests, which was previously broken in various
ways and never actually managed to peer with the netdev.

Signed-off-by: David Woodhouse 
---
 hw/xen/xen-bus.c|  4 
 hw/xen/xen_devconfig.c  | 25 -
 hw/xenpv/xen_machine_pv.c   |  9 -
 include/hw/xen/xen-legacy-backend.h |  1 -
 4 files changed, 4 insertions(+), 35 deletions(-)

diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 0da2aa219a..194c1b7311 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -19,6 +19,7 @@
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
 #include "sysemu/sysemu.h"
+#include "net/net.h"
 #include "trace.h"
 
 static char *xen_device_get_backend_path(XenDevice *xendev)
@@ -1134,4 +1135,7 @@ void xen_bus_init(void)
 
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 qbus_set_bus_hotplug_handler(bus);
+
+qemu_create_nic_bus_devices(bus, TYPE_XEN_DEVICE, "xen-net-device",
+"xen", "xen-net-device");
 }
diff --git a/hw/xen/xen_devconfig.c b/hw/xen/xen_devconfig.c
index 3f77c675c6..2150869f60 100644
--- a/hw/xen/xen_devconfig.c
+++ b/hw/xen/xen_devconfig.c
@@ -46,31 +46,6 @@ static int xen_config_dev_all(char *fe, char *be)
 
 /* - */
 
-int xen_config_dev_nic(NICInfo *nic)
-{
-char fe[256], be[256];
-char mac[20];
-int vlan_id = -1;
-
-net_hub_id_for_client(nic->netdev, &vlan_id);
-snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
- nic->macaddr.a[0], nic->macaddr.a[1], nic->macaddr.a[2],
- nic->macaddr.a[3], nic->macaddr.a[4], nic->macaddr.a[5]);
-xen_pv_printf(NULL, 1, "config nic %d: mac=\"%s\"\n", vlan_id, mac);
-xen_config_dev_dirs("vif", "qnic", vlan_id, fe, be, sizeof(fe));
-
-/* frontend */
-xenstore_write_int(fe, "handle", vlan_id);
-xenstore_write_str(fe, "mac",mac);
-
-/* backend */
-xenstore_write_int(be, "handle", vlan_id);
-xenstore_write_str(be, "mac",mac);
-
-/* common stuff */
-return xen_config_dev_all(fe, be);
-}
-
 int xen_config_dev_vfb(int vdev, const char *type)
 {
 char fe[256], be[256];
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index 9f9f137f99..1130d1a147 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -32,8 +32,6 @@
 
 static void xen_init_pv(MachineState *machine)
 {
-int i;
-
 setup_xen_backend_ops();
 
 /* Initialize backend core & drivers */
@@ -62,13 +60,6 @@ static void xen_init_pv(MachineState *machine)
 vga_interface_created = true;
 }
 
-/* configure nics */
-for (i = 0; i < nb_nics; i++) {
-if (!nd_table[i].model || 0 != strcmp(nd_table[i].model, "xen"))
-continue;
-xen_config_dev_nic(nd_table + i);
-}
-
 xen_bus_init();
 
 /* config cleanup hook */
diff --git a/include/hw/xen/xen-legacy-backend.h 
b/include/hw/xen/xen-legacy-backend.h
index fc42146bc2..2cca174778 100644
--- a/include/hw/xen/xen-legacy-backend.h
+++ b/include/hw/xen/xen-legacy-backend.h
@@ -81,7 +81,6 @@ extern struct XenDevOps xen_usb_ops;  /* xen-usb.c
 */
 
 /* configuration (aka xenbus setup) */
 void xen_config_cleanup(void);
-int xen_config_dev_nic(NICInfo *nic);
 int xen_config_dev_vfb(int vdev, const char *type);
 int xen_config_dev_vkbd(int vdev);
 int xen_config_dev_console(int vdev);
-- 
2.40.1




[PATCH 34/45] hw/microblaze: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 hw/microblaze/petalogix_ml605_mmu.c  | 3 +--
 hw/microblaze/petalogix_s3adsp1800_mmu.c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/microblaze/petalogix_ml605_mmu.c 
b/hw/microblaze/petalogix_ml605_mmu.c
index fb7889cf67..0f5fabc32e 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -133,7 +133,6 @@ petalogix_ml605_init(MachineState *machine)
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);
 
 /* axi ethernet and dma initialization. */
-qemu_check_nic_model(&nd_table[0], "xlnx.axi-ethernet");
 eth0 = qdev_new("xlnx.axi-ethernet");
 dma = qdev_new("xlnx.axi-dma");
 
@@ -145,7 +144,7 @@ petalogix_ml605_init(MachineState *machine)
   "axistream-connected-target", NULL);
 cs = object_property_get_link(OBJECT(dma),
   "axistream-control-connected-target", NULL);
-qdev_set_nic_properties(eth0, &nd_table[0]);
+qemu_configure_nic_device(eth0, true, NULL);
 qdev_prop_set_uint32(eth0, "rxmem", 0x1000);
 qdev_prop_set_uint32(eth0, "txmem", 0x1000);
 object_property_set_link(OBJECT(eth0), "axistream-connected", ds,
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c 
b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index 505639c298..dad46bd7f9 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -114,9 +114,8 @@ petalogix_s3adsp1800_init(MachineState *machine)
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);
 
-qemu_check_nic_model(&nd_table[0], "xlnx.xps-ethernetlite");
 dev = qdev_new("xlnx.xps-ethernetlite");
-qdev_set_nic_properties(dev, &nd_table[0]);
+qemu_configure_nic_device(dev, true, NULL);
 qdev_prop_set_uint32(dev, "tx-ping-pong", 0);
 qdev_prop_set_uint32(dev, "rx-ping-pong", 0);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
-- 
2.40.1




[PATCH 0/45] Rework matching of network devices to -nic options

2023-10-22 Thread David Woodhouse
In 
https://lore.kernel.org/qemu-devel/20231019154020.99080-20-dw...@infradead.org/
I lamented that the default NIC creation seemed fairly hackish but "that
isn't a yak I want to shave today."

Yet here we are...

Most platforms iterating directly over the nd_table[] are doing one of 
two things. Either they are creating the NIC for their platform and want
to find a matching -nic configuration for it, if such exists. Or they
are only going to create that platform NIC if a matching config *does*
exist.

All of those can be converted to the new qemu_configure_nic_device()
and qemu_create_nic_device() functions. The latter of which will call
qdev_new() to create the device (and apply the config) if a matching
NIC config does exist for it. The existing behaviour of each platform
has been preserved for now, despite it being apparently fairly random.

PCI and indeed XenBus can use a qemu_create_nic_bus_devices() which will 
create all NICs that live on a given bus type. That covers most 
platforms, but some PCI platforms do something special with the first 
NIC of a given type, placing it in the slot where it would have been on 
the real hardware. There were various inconsistencies in the way the 
platforms did so, and whether they cared what model the NIC was. Those 
subtle behavioural changes I *have* allowed to change, and now the 
pci_init_nic_slot() function will pick the first NIC that the user 
specified which isn't explicitly *not* the default type, and put that
in  the specified slot.

The tests for npcm7xx used to lament that they had to instantiate both
NICs even when they wanted to test only the second, because there was
no way to specify which hardware devices gets which configuration. I
made that untrue, by allowing 'emc0' and 'emc1' aliases, and fixed up
the test accordingly.

There are one or two special cases which want to do special things with
the MAC address of the primary NIC, to set up a system identification
(or force it to use an Apple OUI, in the case of m68k/q400). All those
work out relatively cleanly too.

And I can ditch the two ugly patches which fixed up the Xen network
device handling, and replace them with a simple call to the new
qemu_create_nic_bus_devices() function.

I suspect that we can remove the pci_init_nic_devices() from platform
code and just do it later, except for platforms which *care* which
PCI bus the dynamic devices go on (is that just sun4u which puts its
primary NIC onto a different bus?).

Finally, while we're at it, clean up -nic model=help to only print
the device models which are actually usable on the given platform
rather than just listing them *all*.

And now we can make nd_table[] and nb_nics static in net/net.c because
nothing else has any business poking at them directly.

David Woodhouse (45):
  net: add qemu_{configure,create}_nic_device(), qemu_find_nic_info()
  net: report list of available models according to platform
  net: add qemu_create_nic_bus_devices()
  hw/pci: add pci_init_nic_devices(), pci_init_nic_in_slot()
  hw/i386/pc: use qemu_get_nic_info() and pci_init_nic_devices()
  hw/xen: use qemu_create_nic_bus_devices() to instantiate Xen NICs
  hw/alpha/dp264: use pci_init_nic_devices()
  hw/arm/sbsa-ref: use pci_init_nic_devices()
  hw/arm/virt: use pci_init_nic_devices()
  hw/hppa: use pci_init_nic_devices()
  hw/loongarch: use pci_init_nic_devices()
  hw/mips/fuloong2e: use pci_init_nic_devices()
  hw/mips/malta: use pci_init_nic_devices()
  hw/mips/loongson3_virt: use pci_init_nic_devices()
  hw/ppc/prep: use pci_init_nic_devices()
  hw/ppc/spapr: use qemu_get_nic_info() and pci_init_nic_devices()
  hw/ppc: use pci_init_nic_devices()
  hw/sh4/r2d: use pci_init_nic_devices()
  hw/sparc64/sun4u: use pci_init_nic_devices()
  hw/xtensa/virt: use pci_init_nic_devices()
  hw/arm/allwinner: use qemu_configure_nic_device()
  hw/arm/aspeed: use qemu_configure_nic_device()
  hw/arm/exynos4: use qemu_create_nic_device()
  hw/arm/fsl: use qemu_configure_nic_device()
  hw/net/smc91c111: use qemu_configure_nic_device()
  hw/net/lan9118: use qemu_configure_nic_device()
  hw/arm/highbank: use qemu_create_nic_device()
  hw/arm/npcm7xx: use qemu_configure_nic_device, allow emc0/emc1 as aliases
  hw/arm/stellaris: use qemu_find_nic_info()
  hw/arm: use qemu_configure_nic_device()
  hw/net/etraxfs-eth: use qemu_configure_nic_device()
  hw/m68k/mcf5208: use qemu_create_nic_device()
  hw/m68k/q800: use qemu_configure_nic_device()
  hw/microblaze: use qemu_configure_nic_device()
  hw/mips: use qemu_create_nic_device()
  hw/net/lasi_i82596: use qemu_configure_nic_device()
  hw/openrisc/openrisc_sim: use qemu_create_nic_device()
  hw/riscv: use qemu_configure_nic_device()
  hw/s390x/s390-virtio-ccw: use qemu_create_nic_device()
  hw/sparc/sun4m: use qemu_configure_nic_device()
  hw/xtensa/xtfpga: use

[PATCH 26/45] hw/net/lan9118: use qemu_configure_nic_device()

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Some callers instantiate the device unconditionally, others will do so only
if there is a NICInfo to go with it. This appears to be fairly random, but
preseve the existing behaviour for now.

Signed-off-by: David Woodhouse 
---
 hw/arm/kzm.c | 4 ++--
 hw/arm/mps2.c| 2 +-
 hw/arm/realview.c| 6 ++
 hw/arm/vexpress.c| 4 ++--
 hw/net/lan9118.c | 5 ++---
 include/hw/net/lan9118.h | 2 +-
 6 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index b1b281c9ac..9f2d120f57 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -112,8 +112,8 @@ static void kzm_init(MachineState *machine)
 alias_offset += ram[i].size;
 }
 
-if (nd_table[0].used) {
-lan9118_init(&nd_table[0], KZM_LAN9118_ADDR,
+if (qemu_find_nic_info("lan9118", true, NULL)) {
+lan9118_init(KZM_LAN9118_ADDR,
  qdev_get_gpio_in(DEVICE(&s->soc.avic), 52));
 }
 
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index d92fd60684..cb3da1ef5c 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -458,7 +458,7 @@ static void mps2_common_init(MachineState *machine)
 /* In hardware this is a LAN9220; the LAN9118 is software compatible
  * except that it doesn't support the checksum-offload feature.
  */
-lan9118_init(&nd_table[0], mmc->ethernet_base,
+lan9118_init(mmc->ethernet_base,
  qdev_get_gpio_in(armv7m,
   mmc->fpga_type == FPGA_AN511 ? 47 : 13));
 
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 591f50581e..68f8aefac3 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -84,7 +84,6 @@ static void realview_init(MachineState *machine,
 SysBusDevice *busdev;
 qemu_irq pic[64];
 PCIBus *pci_bus = NULL;
-NICInfo *nd;
 DriveInfo *dinfo;
 I2CBus *i2c;
 int n;
@@ -295,10 +294,9 @@ static void realview_init(MachineState *machine,
 }
 }
 
-nd = qemu_find_nic_info(is_pb ? "lan9118" : "smc91c111", true, NULL);
-if (nd) {
+if (qemu_find_nic_info(is_pb ? "lan9118" : "smc91c111", true, NULL)) {
 if (is_pb) {
-lan9118_init(nd, 0x4e00, pic[28]);
+lan9118_init(0x4e00, pic[28]);
 } else {
 smc91c111_init(0x4e00, pic[28]);
 }
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 8ff37f52ca..4a6cb3bdf5 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -686,8 +686,8 @@ static void vexpress_common_init(MachineState *machine)
 memory_region_add_subregion(sysmem, map[VE_VIDEORAM], &vms->vram);
 
 /* 0x4e00 LAN9118 Ethernet */
-if (nd_table[0].used) {
-lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]);
+if (qemu_find_nic_info("lan9118", true, NULL)) {
+lan9118_init(map[VE_ETHERNET], pic[15]);
 }
 
 /* VE_USB: not modelled */
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index e5c4af182d..42fe5efd8c 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -1407,14 +1407,13 @@ static void lan9118_register_types(void)
 
 /* Legacy helper function.  Should go away when machine config files are
implemented.  */
-void lan9118_init(NICInfo *nd, uint32_t base, qemu_irq irq)
+void lan9118_init(uint32_t base, qemu_irq irq)
 {
 DeviceState *dev;
 SysBusDevice *s;
 
-qemu_check_nic_model(nd, "lan9118");
 dev = qdev_new(TYPE_LAN9118);
-qdev_set_nic_properties(dev, nd);
+qemu_configure_nic_device(dev, true, NULL);
 s = SYS_BUS_DEVICE(dev);
 sysbus_realize_and_unref(s, &error_fatal);
 sysbus_mmio_map(s, 0, base);
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
index 3d0c67f339..4bf9da7a63 100644
--- a/include/hw/net/lan9118.h
+++ b/include/hw/net/lan9118.h
@@ -15,6 +15,6 @@
 
 #define TYPE_LAN9118 "lan9118"
 
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
+void lan9118_init(uint32_t, qemu_irq);
 
 #endif
-- 
2.40.1




[PATCH 45/45] net: make nb_nics and nd_table[] static in net/net.c

2023-10-22 Thread David Woodhouse
From: David Woodhouse 

Signed-off-by: David Woodhouse 
---
 include/net/net.h | 4 
 net/net.c | 3 +++
 system/globals.c  | 2 --
 3 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 290e604f03..5a38766942 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -245,10 +245,6 @@ struct NICInfo {
 int nvectors;
 };
 
-extern int nb_nics;
-extern NICInfo nd_table[MAX_NICS];
-extern const char *host_net_devices[];
-
 /* from net.c */
 extern NetClientStateList net_clients;
 bool netdev_is_modern(const char *optstr);
diff --git a/net/net.c b/net/net.c
index ed0d638454..9043566abf 100644
--- a/net/net.c
+++ b/net/net.c
@@ -77,6 +77,9 @@ static NetdevQueue nd_queue = 
QSIMPLEQ_HEAD_INITIALIZER(nd_queue);
 
 static GHashTable *nic_model_help;
 
+static int nb_nics;
+static NICInfo nd_table[MAX_NICS];
+
 /***/
 /* network device redirectors */
 
diff --git a/system/globals.c b/system/globals.c
index e83b5428d1..b6d4e72530 100644
--- a/system/globals.c
+++ b/system/globals.c
@@ -36,8 +36,6 @@ int display_opengl;
 const char* keyboard_layout;
 bool enable_mlock;
 bool enable_cpu_pm;
-int nb_nics;
-NICInfo nd_table[MAX_NICS];
 int autostart = 1;
 int vga_interface_type = VGA_NONE;
 bool vga_interface_created;
-- 
2.40.1




Re: [PATCH for-4.19] xen/xmalloc: XMEM_POOL_POISON improvements

2023-10-22 Thread Julien Grall

Hi Andrew,

On 20/10/2023 21:26, Andrew Cooper wrote:

When in use, the spew:

   (XEN) Assertion '!memchr_inv(b->ptr.buffer + MIN_BLOCK_SIZE, POISON_BYTE, 
(b->size & BLOCK_SIZE_MASK) - MIN_BLOCK_SIZE)' failed at common/xmalloc_tlsf.c:246

is unweidly and meaningless to non-Xen developers.  Therefore:

  * Switch to IS_ENABLED().  There's no need for full #ifdef-ary.
  * Pull memchr_inv() out into the if(), and provide a better error message.

Signed-off-by: Andrew Cooper 
---
CC: George Dunlap 
CC: Jan Beulich 
CC: Stefano Stabellini 
CC: Wei Liu 
CC: Julien Grall 
CC: Roger Pau Monné 

Observations from the debugging of:
   https://github.com/Dasharo/dasharo-issues/issues/488

There's a further bug.  XMEM_POOL_POISON can be enabled in release builds,
where the ASSERT() gets dropped.

However, upping to a BUG() can't provide any helpful message out to the user.

I tried modifying BUG() to take an optional message, but xen/bug.h needs
untangling substantially before that will work, and I don't have time right now.


Do we actually care about the registers values? If not, we can either use:

printk(...);
BUG();

Or

panic(...);

This would allow us to use XMEM_POOL_POISON in prod build before BUG() 
can accept string.



---
  xen/common/xmalloc_tlsf.c | 15 +++
  1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/xen/common/xmalloc_tlsf.c b/xen/common/xmalloc_tlsf.c
index 349b31cb4cc1..13305cd87c2f 100644
--- a/xen/common/xmalloc_tlsf.c
+++ b/xen/common/xmalloc_tlsf.c
@@ -249,11 +249,11 @@ static inline void EXTRACT_BLOCK(struct bhdr *b, struct 
xmem_pool *p, int fl,
  }
  b->ptr.free_ptr = (struct free_ptr) {NULL, NULL};
  
-#ifdef CONFIG_XMEM_POOL_POISON

-if ( (b->size & BLOCK_SIZE_MASK) > MIN_BLOCK_SIZE )
-ASSERT(!memchr_inv(b->ptr.buffer + MIN_BLOCK_SIZE, POISON_BYTE,
-   (b->size & BLOCK_SIZE_MASK) - MIN_BLOCK_SIZE));
-#endif /* CONFIG_XMEM_POOL_POISON */
+if ( IS_ENABLED(CONFIG_XMEM_POOL_POISON) &&
+ (b->size & BLOCK_SIZE_MASK) > MIN_BLOCK_SIZE &&
+ memchr_inv(b->ptr.buffer + MIN_BLOCK_SIZE, POISON_BYTE,
+(b->size & BLOCK_SIZE_MASK) - MIN_BLOCK_SIZE) )
+ASSERT(!"XMEM Pool corruption found");
  }
  
  /**

@@ -261,11 +261,10 @@ static inline void EXTRACT_BLOCK(struct bhdr *b, struct 
xmem_pool *p, int fl,
   */
  static inline void INSERT_BLOCK(struct bhdr *b, struct xmem_pool *p, int fl, 
int sl)
  {
-#ifdef CONFIG_XMEM_POOL_POISON
-if ( (b->size & BLOCK_SIZE_MASK) > MIN_BLOCK_SIZE )
+if ( IS_ENABLED(CONFIG_XMEM_POOL_POISON) &&
+ (b->size & BLOCK_SIZE_MASK) > MIN_BLOCK_SIZE )
  memset(b->ptr.buffer + MIN_BLOCK_SIZE, POISON_BYTE,
 (b->size & BLOCK_SIZE_MASK) - MIN_BLOCK_SIZE);
-#endif /* CONFIG_XMEM_POOL_POISON */
  
  b->ptr.free_ptr = (struct free_ptr) {NULL, p->matrix[fl][sl]};

  if ( p->matrix[fl][sl] )



Cheers,

--
Julien Grall



[PATCH v8 0/8] xen/arm: Split MMU code as the prepration of MPU work

2023-10-22 Thread Henry Wang
Based on the discussion in the Xen Summit [1], sending this series out after
addressing the comments in v7 [2] as the preparation work to add MPU support.
The series passed the GitLab CI check in [3].

Mostly code movement and function folding, with some of Kconfig and build
system (mainly Makefiles) adjustment.

This series is based on:
bad1ac345b x86: support data operand independent timing mode

[1] 
https://lore.kernel.org/xen-devel/as8pr08mb799122f8b0cb841ded64f48192...@as8pr08mb7991.eurprd08.prod.outlook.com/
[2] 
https://lore.kernel.org/xen-devel/20231009010313.3668423-1-henry.w...@arm.com/
[3] https://gitlab.com/xen-project/people/henryw/xen/-/pipelines/1045604579

Henry Wang (6):
  xen/arm: Split page table related code to mmu/pt.c
  xen/arm: Split MMU system SMP MM bringup code to mmu/smpboot.c
  xen/arm: Fold mmu_init_secondary_cpu() to head.S
  xen/arm: Extract MMU-specific MM code
  xen/arm: Split MMU-specific setup_mm() and related code out
  xen/arm: Fold pmap and fixmap into MMU system

Penny Zheng (2):
  xen/arm: Rename init_secondary_pagetables() to prepare_secondary_mm()
  xen/arm: mmu: move MMU specific P2M code to mmu/p2m.{c,h}

 xen/arch/arm/Kconfig   |2 +-
 xen/arch/arm/Makefile  |1 +
 xen/arch/arm/arm32/Makefile|1 +
 xen/arch/arm/arm32/head.S  |   22 +-
 xen/arch/arm/arm32/mmu/Makefile|1 +
 xen/arch/arm/arm32/mmu/mm.c|  301 +
 xen/arch/arm/arm64/Makefile|1 -
 xen/arch/arm/arm64/mmu/Makefile|1 +
 xen/arch/arm/arm64/mmu/head.S  |   18 +-
 xen/arch/arm/arm64/{ => mmu}/mm.c  |   84 ++
 xen/arch/arm/domain.c  |   11 +-
 xen/arch/arm/include/asm/mm.h  |   32 +-
 xen/arch/arm/include/asm/mmu/mm.h  |   44 +
 xen/arch/arm/include/asm/mmu/p2m.h |   26 +
 xen/arch/arm/include/asm/p2m.h |   32 +-
 xen/arch/arm/include/asm/page.h|   15 -
 xen/arch/arm/include/asm/setup.h   |5 +
 xen/arch/arm/kernel.c  |   28 -
 xen/arch/arm/mm.c  | 1212 --
 xen/arch/arm/mmu/Makefile  |4 +
 xen/arch/arm/mmu/p2m.c | 1834 ++
 xen/arch/arm/mmu/pt.c  |  736 +++
 xen/arch/arm/mmu/setup.c   |  376 ++
 xen/arch/arm/mmu/smpboot.c |  124 ++
 xen/arch/arm/p2m.c | 1909 +---
 xen/arch/arm/setup.c   |  324 +
 xen/arch/arm/smpboot.c |4 +-
 27 files changed, 3655 insertions(+), 3493 deletions(-)
 create mode 100644 xen/arch/arm/arm32/mmu/Makefile
 create mode 100644 xen/arch/arm/arm32/mmu/mm.c
 rename xen/arch/arm/arm64/{ => mmu}/mm.c (60%)
 create mode 100644 xen/arch/arm/include/asm/mmu/mm.h
 create mode 100644 xen/arch/arm/include/asm/mmu/p2m.h
 create mode 100644 xen/arch/arm/mmu/Makefile
 create mode 100644 xen/arch/arm/mmu/p2m.c
 create mode 100644 xen/arch/arm/mmu/pt.c
 create mode 100644 xen/arch/arm/mmu/setup.c
 create mode 100644 xen/arch/arm/mmu/smpboot.c

-- 
2.25.1




[PATCH v8 1/8] xen/arm: Split page table related code to mmu/pt.c

2023-10-22 Thread Henry Wang
The extraction of MMU related code is the basis of MPU support.
This commit starts this work by firstly splitting the page table
related code to mmu/pt.c, so that we will not end up with again
massive mm.c files.

Introduce a mmu specific directory and setup the Makefiles for it.
Move the page table related functions and macros from arch/arm/mm.c
to arch/arm/mmu/pt.c.

Take the opportunity to fix the in-code comment coding styles when
possible, and drop the unnecessary #include headers in the original
arch/arm/mm.c.

Signed-off-by: Henry Wang 
Signed-off-by: Penny Zheng 
Reviewed-by: Julien Grall 
---
v8:
- Add Julien's Reviewed-by tag.
v7:
- Do not move pte_of_xenaddr() to mmu/pt.c.
- Do not expose global variable phys_offset.
v6:
- Rework the original patch "[v5,07/13] xen/arm: Extract MMU-specific
  code", only split the page table related code out in this patch.
---
 xen/arch/arm/Makefile |   1 +
 xen/arch/arm/mm.c | 717 -
 xen/arch/arm/mmu/Makefile |   1 +
 xen/arch/arm/mmu/pt.c | 736 ++
 4 files changed, 738 insertions(+), 717 deletions(-)
 create mode 100644 xen/arch/arm/mmu/Makefile
 create mode 100644 xen/arch/arm/mmu/pt.c

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 7bf07e9920..c45b08b31e 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_ARM_32) += arm32/
 obj-$(CONFIG_ARM_64) += arm64/
+obj-$(CONFIG_MMU) += mmu/
 obj-$(CONFIG_ACPI) += acpi/
 obj-$(CONFIG_HAS_PCI) += pci/
 ifneq ($(CONFIG_NO_PLAT),y)
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index c34cc94c90..fd02493564 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -9,22 +9,14 @@
  */
 
 #include 
-#include 
 #include 
 #include 
-#include 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
 
 #include 
 
-#include 
 #include 
 
 #include 
@@ -35,19 +27,6 @@
 #undef mfn_to_virt
 #define mfn_to_virt(mfn) __mfn_to_virt(mfn_x(mfn))
 
-#ifdef NDEBUG
-static inline void
-__attribute__ ((__format__ (__printf__, 1, 2)))
-mm_printk(const char *fmt, ...) {}
-#else
-#define mm_printk(fmt, args...) \
-do  \
-{   \
-dprintk(XENLOG_ERR, fmt, ## args);  \
-WARN(); \
-} while (0)
-#endif
-
 /* Static start-of-day pagetables that we use before the allocators
  * are up. These are used by all CPUs during bringup before switching
  * to the CPUs own pagetables.
@@ -92,12 +71,10 @@ DEFINE_BOOT_PAGE_TABLES(boot_third, XEN_NR_ENTRIES(2));
  */
 
 #ifdef CONFIG_ARM_64
-#define HYP_PT_ROOT_LEVEL 0
 DEFINE_PAGE_TABLE(xen_pgtable);
 static DEFINE_PAGE_TABLE(xen_first);
 #define THIS_CPU_PGTABLE xen_pgtable
 #else
-#define HYP_PT_ROOT_LEVEL 1
 /* Per-CPU pagetable pages */
 /* xen_pgtable == root of the trie (zeroeth level on 64-bit, first on 32-bit) 
*/
 DEFINE_PER_CPU(lpae_t *, xen_pgtable);
@@ -200,179 +177,6 @@ static void __init __maybe_unused build_assertions(void)
 #undef CHECK_DIFFERENT_SLOT
 }
 
-static lpae_t *xen_map_table(mfn_t mfn)
-{
-/*
- * During early boot, map_domain_page() may be unusable. Use the
- * PMAP to map temporarily a page-table.
- */
-if ( system_state == SYS_STATE_early_boot )
-return pmap_map(mfn);
-
-return map_domain_page(mfn);
-}
-
-static void xen_unmap_table(const lpae_t *table)
-{
-/*
- * During early boot, xen_map_table() will not use map_domain_page()
- * but the PMAP.
- */
-if ( system_state == SYS_STATE_early_boot )
-pmap_unmap(table);
-else
-unmap_domain_page(table);
-}
-
-void dump_pt_walk(paddr_t ttbr, paddr_t addr,
-  unsigned int root_level,
-  unsigned int nr_root_tables)
-{
-static const char *level_strs[4] = { "0TH", "1ST", "2ND", "3RD" };
-const mfn_t root_mfn = maddr_to_mfn(ttbr);
-DECLARE_OFFSETS(offsets, addr);
-lpae_t pte, *mapping;
-unsigned int level, root_table;
-
-#ifdef CONFIG_ARM_32
-BUG_ON(root_level < 1);
-#endif
-BUG_ON(root_level > 3);
-
-if ( nr_root_tables > 1 )
-{
-/*
- * Concatenated root-level tables. The table number will be
- * the offset at the previous level. It is not possible to
- * concatenate a level-0 root.
- */
-BUG_ON(root_level == 0);
-root_table = offsets[root_level - 1];
-printk("Using concatenated root table %u\n", root_table);
-if ( root_table >= nr_root_tables )
-{
-printk("Invalid root table offset\n");
-return;
-}
-}
-else
-root_table = 0;
-
-mapping = xen_map_table(mfn_add(root_mfn, root_table));
-
-for ( level = root_level; ; level++ )
-{
-if ( offsets[level] > XEN_PT_LPAE_ENTRIES )
-break;
-
-pte = mapping[offsets[level]];
-
-pri

[PATCH v8 5/8] xen/arm: Split MMU-specific setup_mm() and related code out

2023-10-22 Thread Henry Wang
setup_mm() is used for Xen to setup memory management subsystem,
such as boot allocator, direct-mapping, xenheap initialization,
frametable and static memory pages, at boot time.

We could inherit some components seamlessly for MPU support, such
as the setup of boot allocator, whilst we need to implement some
components differently for MPU, such as xenheap, etc. Also, there
are some components that is specific to MMU only, for example the
direct-mapping.

Therefore in this commit, we split the MMU-specific setup_mm() and
related code out. Since arm32 and arm64 have completely different
setup_mm() implementation, take the opportunity to split the
arch-specific setup_mm() to arch-specific files, so that we can
avoid #ifdef. Also, make init_pdx(), init_staticmem_pages(), and
populate_boot_allocator() public as these functions are now called
from two different units, and make setup_mm() public for future MPU
implementation.

With above code movement, mark setup_directmap_mappings() as static
because the only caller of this function is now in the same file
with it. Drop the original setup_directmap_mappings() declaration
and move the in-code comment on top of the declaration on top of
the function implementation.

Signed-off-by: Henry Wang 
Signed-off-by: Penny Zheng 
Signed-off-by: Wei Chen 
Acked-by: Julien Grall 
---
v8:
- Reword the commit message about making init_pdx() & co public.
- Add Julien's Acked-by tag.
v7:
- No change.
v6:
- Rework the original patch:
  [v5,10/13] xen/arm: mmu: move MMU-specific setup_mm to mmu/setup.c
---
 xen/arch/arm/arm32/mmu/mm.c   | 278 -
 xen/arch/arm/arm64/mmu/mm.c   |  51 -
 xen/arch/arm/include/asm/mmu/mm.h |   6 -
 xen/arch/arm/include/asm/setup.h  |   5 +
 xen/arch/arm/setup.c  | 324 +-
 5 files changed, 331 insertions(+), 333 deletions(-)

diff --git a/xen/arch/arm/arm32/mmu/mm.c b/xen/arch/arm/arm32/mmu/mm.c
index 647baf4a81..94d6cab49c 100644
--- a/xen/arch/arm/arm32/mmu/mm.c
+++ b/xen/arch/arm/arm32/mmu/mm.c
@@ -1,14 +1,21 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
 #include 
+#include 
+#include 
+#include 
+#include 
 #include 
 
+static unsigned long opt_xenheap_megabytes __initdata;
+integer_param("xenheap_megabytes", opt_xenheap_megabytes);
+
 /*
- * Set up the direct-mapped xenheap:
- * up to 1GB of contiguous, always-mapped memory.
+ * Set up the direct-mapped xenheap: up to 1GB of contiguous,
+ * always-mapped memory. Base must be 32MB aligned and size a multiple of 32MB.
  */
-void __init setup_directmap_mappings(unsigned long base_mfn,
- unsigned long nr_mfns)
+static void __init setup_directmap_mappings(unsigned long base_mfn,
+unsigned long nr_mfns)
 {
 int rc;
 
@@ -21,6 +28,269 @@ void __init setup_directmap_mappings(unsigned long base_mfn,
 directmap_virt_end = XENHEAP_VIRT_START + nr_mfns * PAGE_SIZE;
 }
 
+/*
+ * Returns the end address of the highest region in the range s..e
+ * with required size and alignment that does not conflict with the
+ * modules from first_mod to nr_modules.
+ *
+ * For non-recursive callers first_mod should normally be 0 (all
+ * modules and Xen itself) or 1 (all modules but not Xen).
+ */
+static paddr_t __init consider_modules(paddr_t s, paddr_t e,
+   uint32_t size, paddr_t align,
+   int first_mod)
+{
+const struct bootmodules *mi = &bootinfo.modules;
+int i;
+int nr;
+
+s = (s+align-1) & ~(align-1);
+e = e & ~(align-1);
+
+if ( s > e ||  e - s < size )
+return 0;
+
+/* First check the boot modules */
+for ( i = first_mod; i < mi->nr_mods; i++ )
+{
+paddr_t mod_s = mi->module[i].start;
+paddr_t mod_e = mod_s + mi->module[i].size;
+
+if ( s < mod_e && mod_s < e )
+{
+mod_e = consider_modules(mod_e, e, size, align, i+1);
+if ( mod_e )
+return mod_e;
+
+return consider_modules(s, mod_s, size, align, i+1);
+}
+}
+
+/* Now check any fdt reserved areas. */
+
+nr = fdt_num_mem_rsv(device_tree_flattened);
+
+for ( ; i < mi->nr_mods + nr; i++ )
+{
+paddr_t mod_s, mod_e;
+
+if ( fdt_get_mem_rsv_paddr(device_tree_flattened,
+   i - mi->nr_mods,
+   &mod_s, &mod_e ) < 0 )
+/* If we can't read it, pretend it doesn't exist... */
+continue;
+
+/* fdt_get_mem_rsv_paddr returns length */
+mod_e += mod_s;
+
+if ( s < mod_e && mod_s < e )
+{
+mod_e = consider_modules(mod_e, e, size, align, i+1);
+if ( mod_e )
+return mod_e;
+
+return consider_modules(s, mod_s, size, align, i+1);
+}
+}
+
+/*
+ * i is the current bootmodule we are evaluating, acro

[PATCH v8 2/8] xen/arm: Split MMU system SMP MM bringup code to mmu/smpboot.c

2023-10-22 Thread Henry Wang
Move the code related to secondary page table initialization, clear
boot page tables and the global variable definitions of these boot
page tables from arch/arm/mm.c to arch/arm/mmu/smpboot.c

Since arm32 global variable cpu0_pgtable will be used by both
arch/arm/mm.c and arch/arm/mmu/smpboot.c, to avoid exporting this
variable, change the variable usage in arch/arm/mmu/smpboot.c to
per_cpu(xen_pgtable, 0).

To avoid exposing global variable phys_offset, use virt_to_maddr()
to calculate init_ttbr for arm64.

Take the opportunity to fix the in-code comment coding styles when
possible.

Signed-off-by: Henry Wang 
Signed-off-by: Penny Zheng 
Reviewed-by: Julien Grall 
---
v8:
- Drop the unnecessary cast in virt_to_maddr((uintptr_t) xen_pgtable);
- Add Julien's Reviewed-by tag.
v7:
- Do not export cpu0_pgtable, replace the variable usage in
  arch/arm/mmu/smpboot.c to per_cpu(xen_pgtable, 0).
- Also move global variable init_ttbr to arch/arm/mmu/smpboot.c.
- Use virt_to_maddr() instead of phys_offset to calculate init_ttbr
  in arm64 implementation of init_secondary_pagetables().
v6:
- Rework the original patch "[v5,07/13] xen/arm: Extract MMU-specific
  code", only split the smpboot related code out in this patch.
---
 xen/arch/arm/mm.c  | 104 ---
 xen/arch/arm/mmu/Makefile  |   1 +
 xen/arch/arm/mmu/smpboot.c | 124 +
 3 files changed, 125 insertions(+), 104 deletions(-)
 create mode 100644 xen/arch/arm/mmu/smpboot.c

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index fd02493564..b7eb3a6e08 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -27,39 +27,6 @@
 #undef mfn_to_virt
 #define mfn_to_virt(mfn) __mfn_to_virt(mfn_x(mfn))
 
-/* Static start-of-day pagetables that we use before the allocators
- * are up. These are used by all CPUs during bringup before switching
- * to the CPUs own pagetables.
- *
- * These pagetables have a very simple structure. They include:
- *  - XEN_VIRT_SIZE worth of L3 mappings of xen at XEN_VIRT_START, boot_first
- *and boot_second are used to populate the tables down to boot_third
- *which contains the actual mapping.
- *  - a 1:1 mapping of xen at its current physical address. This uses a
- *section mapping at whichever of boot_{pgtable,first,second}
- *covers that physical address.
- *
- * For the boot CPU these mappings point to the address where Xen was
- * loaded by the bootloader. For secondary CPUs they point to the
- * relocated copy of Xen for the benefit of secondary CPUs.
- *
- * In addition to the above for the boot CPU the device-tree is
- * initially mapped in the boot misc slot. This mapping is not present
- * for secondary CPUs.
- *
- * Finally, if EARLY_PRINTK is enabled then xen_fixmap will be mapped
- * by the CPU once it has moved off the 1:1 mapping.
- */
-DEFINE_BOOT_PAGE_TABLE(boot_pgtable);
-#ifdef CONFIG_ARM_64
-DEFINE_BOOT_PAGE_TABLE(boot_first);
-DEFINE_BOOT_PAGE_TABLE(boot_first_id);
-#endif
-DEFINE_BOOT_PAGE_TABLE(boot_second_id);
-DEFINE_BOOT_PAGE_TABLE(boot_third_id);
-DEFINE_BOOT_PAGE_TABLE(boot_second);
-DEFINE_BOOT_PAGE_TABLES(boot_third, XEN_NR_ENTRIES(2));
-
 /* Main runtime page tables */
 
 /*
@@ -94,9 +61,6 @@ DEFINE_BOOT_PAGE_TABLE(xen_fixmap);
  */
 static DEFINE_PAGE_TABLES(xen_xenmap, XEN_NR_ENTRIES(2));
 
-/* Non-boot CPUs use this to find the correct pagetables. */
-uint64_t init_ttbr;
-
 static paddr_t phys_offset;
 
 /* Limits of the Xen heap */
@@ -284,13 +248,6 @@ static void xen_pt_enforce_wnx(void)
 flush_xen_tlb_local();
 }
 
-/* Clear a translation table and clean & invalidate the cache */
-static void clear_table(void *table)
-{
-clear_page(table);
-clean_and_invalidate_dcache_va_range(table, PAGE_SIZE);
-}
-
 /* Boot-time pagetable setup.
  * Changes here may need matching changes in head.S */
 void __init setup_pagetables(unsigned long boot_phys_offset)
@@ -369,67 +326,6 @@ void __init setup_pagetables(unsigned long 
boot_phys_offset)
 #endif
 }
 
-static void clear_boot_pagetables(void)
-{
-/*
- * Clear the copy of the boot pagetables. Each secondary CPU
- * rebuilds these itself (see head.S).
- */
-clear_table(boot_pgtable);
-#ifdef CONFIG_ARM_64
-clear_table(boot_first);
-clear_table(boot_first_id);
-#endif
-clear_table(boot_second);
-clear_table(boot_third);
-}
-
-#ifdef CONFIG_ARM_64
-int init_secondary_pagetables(int cpu)
-{
-clear_boot_pagetables();
-
-/* Set init_ttbr for this CPU coming up. All CPus share a single setof
- * pagetables, but rewrite it each time for consistency with 32 bit. */
-init_ttbr = (uintptr_t) xen_pgtable + phys_offset;
-clean_dcache(init_ttbr);
-return 0;
-}
-#else
-int init_secondary_pagetables(int cpu)
-{
-lpae_t *first;
-
-first = alloc_xenheap_page(); /* root == first level on 32-bit 3-level 
trie */
-
-if ( !first )
-{
-printk("CPU%u: Unable to allocate the first page-table\n", cpu);
-

[PATCH v8 7/8] xen/arm: Rename init_secondary_pagetables() to prepare_secondary_mm()

2023-10-22 Thread Henry Wang
From: Penny Zheng 

init_secondary_pagetables() is a function in the common code path
of both MMU and future MPU support. Since "page table" is a MMU
specific concept, rename init_secondary_pagetables() to a generic
name prepare_secondary_mm() as the preparation for MPU support.

Reword the in-code comment on top of prepare_secondary_mm() because
this function is now supposed to be MMU/MPU agnostic.

Take the opportunity to fix the incorrect coding style of the in-code
comments.

Signed-off-by: Penny Zheng 
Signed-off-by: Henry Wang 
Reviewed-by: Julien Grall 
---
v8:
- Change the in-code comment on top of prepare_secondary_mm() because
  this function is now supposed to be MMU/MPU agnostic, mention this
  in the commit message.
- Add Julien's Reviewed-by tag.
v7:
- No change.
v6:
- Only rename init_secondary_pagetables() to prepare_secondary_mm().
---
 xen/arch/arm/arm32/head.S | 2 +-
 xen/arch/arm/include/asm/mm.h | 5 ++---
 xen/arch/arm/mmu/smpboot.c| 4 ++--
 xen/arch/arm/smpboot.c| 2 +-
 4 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
index 39218cf15f..c7b2efb8f0 100644
--- a/xen/arch/arm/arm32/head.S
+++ b/xen/arch/arm/arm32/head.S
@@ -257,7 +257,7 @@ GLOBAL(init_secondary)
 secondary_switched:
 /*
  * Non-boot CPUs need to move on to the proper pagetables, which were
- * setup in init_secondary_pagetables.
+ * setup in prepare_secondary_mm.
  *
  * XXX: This is not compliant with the Arm Arm.
  */
diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h
index d23ebc7df6..cbcf3bf147 100644
--- a/xen/arch/arm/include/asm/mm.h
+++ b/xen/arch/arm/include/asm/mm.h
@@ -204,9 +204,8 @@ extern void setup_pagetables(unsigned long 
boot_phys_offset);
 extern void *early_fdt_map(paddr_t fdt_paddr);
 /* Remove early mappings */
 extern void remove_early_mappings(void);
-/* Allocate and initialise pagetables for a secondary CPU. Sets init_ttbr to 
the
- * new page table */
-extern int init_secondary_pagetables(int cpu);
+/* Prepare the memory subystem to bring-up the given secondary CPU */
+extern int prepare_secondary_mm(int cpu);
 /* Map a frame table to cover physical addresses ps through pe */
 extern void setup_frametable_mappings(paddr_t ps, paddr_t pe);
 /* map a physical range in virtual memory */
diff --git a/xen/arch/arm/mmu/smpboot.c b/xen/arch/arm/mmu/smpboot.c
index 8b6a09f843..12f1a5d761 100644
--- a/xen/arch/arm/mmu/smpboot.c
+++ b/xen/arch/arm/mmu/smpboot.c
@@ -67,7 +67,7 @@ static void clear_boot_pagetables(void)
 }
 
 #ifdef CONFIG_ARM_64
-int init_secondary_pagetables(int cpu)
+int prepare_secondary_mm(int cpu)
 {
 clear_boot_pagetables();
 
@@ -80,7 +80,7 @@ int init_secondary_pagetables(int cpu)
 return 0;
 }
 #else
-int init_secondary_pagetables(int cpu)
+int prepare_secondary_mm(int cpu)
 {
 lpae_t *first;
 
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index beb137d06e..ac451e9b3e 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -448,7 +448,7 @@ int __cpu_up(unsigned int cpu)
 
 printk("Bringing up CPU%d\n", cpu);
 
-rc = init_secondary_pagetables(cpu);
+rc = prepare_secondary_mm(cpu);
 if ( rc < 0 )
 return rc;
 
-- 
2.25.1




[PATCH v8 3/8] xen/arm: Fold mmu_init_secondary_cpu() to head.S

2023-10-22 Thread Henry Wang
Currently mmu_init_secondary_cpu() only enforces the page table
should not contain mapping that are both Writable and eXecutables
after boot. To ease the arch/arm/mm.c split work, fold this function
to head.S.

For arm32, introduce an assembly macro pt_enforce_wxn. The macro is
called before secondary CPUs jumping into the C world.

For arm64, set the SCTLR_Axx_ELx_WXN flag right when the MMU is
enabled. This would avoid the extra TLB flush and SCTLR dance.

Signed-off-by: Henry Wang 
Co-authored-by: Julien Grall 
Signed-off-by: Julien Grall 
---
v8:
- Change the setting of SCTLR_Axx_ELx_WXN for arm64 to set the
  flag right when the MMU is enabled.
v7:
- No change.
v6:
- New patch.
---
 xen/arch/arm/arm32/head.S | 20 
 xen/arch/arm/arm64/mmu/head.S | 18 +++---
 xen/arch/arm/include/asm/mm.h |  2 --
 xen/arch/arm/mm.c |  6 --
 xen/arch/arm/smpboot.c|  2 --
 5 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
index 33b038e7e0..39218cf15f 100644
--- a/xen/arch/arm/arm32/head.S
+++ b/xen/arch/arm/arm32/head.S
@@ -83,6 +83,25 @@
 isb
 .endm
 
+/*
+ * Enforce Xen page-tables do not contain mapping that are both
+ * Writable and eXecutables.
+ *
+ * This should be called on each secondary CPU.
+ */
+.macro pt_enforce_wxn tmp
+mrc   CP32(\tmp, HSCTLR)
+orr   \tmp, \tmp, #SCTLR_Axx_ELx_WXN
+dsb
+mcr   CP32(\tmp, HSCTLR)
+/*
+ * The TLBs may cache SCTLR_EL2.WXN. So ensure it is synchronized
+ * before flushing the TLBs.
+ */
+isb
+flush_xen_tlb_local \tmp
+.endm
+
 /*
  * Common register usage in this file:
  *   r0  -
@@ -254,6 +273,7 @@ secondary_switched:
 /* Use a virtual address to access the UART. */
 mov_w r11, EARLY_UART_VIRTUAL_ADDRESS
 #endif
+pt_enforce_wxn r0
 PRINT("- Ready -\r\n")
 /* Jump to C world */
 mov_w r2, start_secondary
diff --git a/xen/arch/arm/arm64/mmu/head.S b/xen/arch/arm/arm64/mmu/head.S
index 88075ef083..df06cefbbe 100644
--- a/xen/arch/arm/arm64/mmu/head.S
+++ b/xen/arch/arm/arm64/mmu/head.S
@@ -264,10 +264,11 @@ ENDPROC(create_page_tables)
  * Inputs:
  *   x0 : Physical address of the page tables.
  *
- * Clobbers x0 - x4
+ * Clobbers x0 - x6
  */
 enable_mmu:
 mov   x4, x0
+mov   x5, x1
 PRINT("- Turning on paging -\r\n")
 
 /*
@@ -283,6 +284,7 @@ enable_mmu:
 mrs   x0, SCTLR_EL2
 orr   x0, x0, #SCTLR_Axx_ELx_M  /* Enable MMU */
 orr   x0, x0, #SCTLR_Axx_ELx_C  /* Enable D-cache */
+orr   x0, x0, x5/* Enable extra flags */
 dsb   sy /* Flush PTE writes and finish reads */
 msr   SCTLR_EL2, x0  /* now paging is enabled */
 isb  /* Now, flush the icache */
@@ -297,16 +299,17 @@ ENDPROC(enable_mmu)
  * Inputs:
  *   lr : Virtual address to return to.
  *
- * Clobbers x0 - x5
+ * Clobbers x0 - x6
  */
 ENTRY(enable_secondary_cpu_mm)
-mov   x5, lr
+mov   x6, lr
 
 load_paddr x0, init_ttbr
 ldr   x0, [x0]
 
+mov   x1, #SCTLR_Axx_ELx_WXN/* Enable WxN from the start */
 blenable_mmu
-mov   lr, x5
+mov   lr, x6
 
 /* Return to the virtual address requested by the caller. */
 ret
@@ -320,14 +323,15 @@ ENDPROC(enable_secondary_cpu_mm)
  * Inputs:
  *   lr : Virtual address to return to.
  *
- * Clobbers x0 - x5
+ * Clobbers x0 - x6
  */
 ENTRY(enable_boot_cpu_mm)
-mov   x5, lr
+mov   x6, lr
 
 blcreate_page_tables
 load_paddr x0, boot_pgtable
 
+mov   x1, #0/* No extra SCTLR flags */
 blenable_mmu
 
 /*
@@ -337,7 +341,7 @@ ENTRY(enable_boot_cpu_mm)
 ldr   x0, =1f
 brx0
 1:
-mov   lr, x5
+mov   lr, x6
 /*
  * The 1:1 map may clash with other parts of the Xen virtual memory
  * layout. As it is not used anymore, remove it completely to
diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h
index d25e59f828..163d22ecd3 100644
--- a/xen/arch/arm/include/asm/mm.h
+++ b/xen/arch/arm/include/asm/mm.h
@@ -214,8 +214,6 @@ extern void remove_early_mappings(void);
 /* Allocate and initialise pagetables for a secondary CPU. Sets init_ttbr to 
the
  * new page table */
 extern int init_secondary_pagetables(int cpu);
-/* Switch secondary CPUS to its own pagetables and finalise MMU setup */
-extern void mmu_init_secondary_cpu(void);
 /*
  * For Arm32, set up the direct-mapped xenheap: up to 1GB of contiguous,
  * always-mapped memory. Base must be 32MB aligned and size a multiple of 32MB.
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index b7eb3a6e08..923a90925c 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -326,12 +326,6 @@ void __init se

[PATCH v8 6/8] xen/arm: Fold pmap and fixmap into MMU system

2023-10-22 Thread Henry Wang
fixmap and pmap are MMU-specific features, so fold them to the
MMU system. Do the folding for pmap by moving the HAS_PMAP Kconfig
selection under MMU. Since none of the definitions in asm/fixmap.h
actually makes sense for the MPU, so do the folding for fixmap by
limiting the inclusion of asm/fixmap.h for MPU code when necessary.
To guarantee that, moving the implementation of copy_from_paddr()
from kernel.c to mmu/setup.c, so that inclusion of asm/fixmap.h in
the kernel.c can be dropped.

Take the opportunity to add a missing space before and after '-' in
"s = paddr & (PAGE_SIZE-1);" of copy_from_paddr().

Signed-off-by: Henry Wang 
Signed-off-by: Penny Zheng 
Signed-off-by: Wei Chen 
Reviewed-by: Julien Grall 
---
v8:
- Add a missing space before/after '-' in "s = paddr & (PAGE_SIZE-1);"
  of copy_from_paddr(), mention this change in commit message.
- Add Julien's Reviewed-by tag.
v7:
- No change.
v6:
- Rework original patch:
  [v5,08/13] xen/arm: Fold pmap and fixmap into MMU system
  and fold in the original patch:
  [v5,12/13] xen/arm: mmu: relocate copy_from_paddr() to setup.c
---
 xen/arch/arm/Kconfig |  2 +-
 xen/arch/arm/kernel.c| 28 
 xen/arch/arm/mmu/setup.c | 27 +++
 3 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index 2939db429b..7b5b0c0c05 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -14,7 +14,6 @@ config ARM
select HAS_ALTERNATIVE
select HAS_DEVICE_TREE
select HAS_PASSTHROUGH
-   select HAS_PMAP
select HAS_UBSAN
select IOMMU_FORCE_PT_SHARE
 
@@ -60,6 +59,7 @@ config PADDR_BITS
 
 config MMU
def_bool y
+   select HAS_PMAP
 
 source "arch/Kconfig"
 
diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
index 508c54824d..bc3e5bd6f9 100644
--- a/xen/arch/arm/kernel.c
+++ b/xen/arch/arm/kernel.c
@@ -16,7 +16,6 @@
 #include 
 
 #include 
-#include 
 #include 
 #include 
 
@@ -41,33 +40,6 @@ struct minimal_dtb_header {
 
 #define DTB_MAGIC 0xd00dfeedU
 
-/**
- * copy_from_paddr - copy data from a physical address
- * @dst: destination virtual address
- * @paddr: source physical address
- * @len: length to copy
- */
-void __init copy_from_paddr(void *dst, paddr_t paddr, unsigned long len)
-{
-void *src = (void *)FIXMAP_ADDR(FIXMAP_MISC);
-
-while (len) {
-unsigned long l, s;
-
-s = paddr & (PAGE_SIZE-1);
-l = min(PAGE_SIZE - s, len);
-
-set_fixmap(FIXMAP_MISC, maddr_to_mfn(paddr), PAGE_HYPERVISOR_WC);
-memcpy(dst, src + s, l);
-clean_dcache_va_range(dst, l);
-clear_fixmap(FIXMAP_MISC);
-
-paddr += l;
-dst += l;
-len -= l;
-}
-}
-
 static void __init place_modules(struct kernel_info *info,
  paddr_t kernbase, paddr_t kernend)
 {
diff --git a/xen/arch/arm/mmu/setup.c b/xen/arch/arm/mmu/setup.c
index c2df976ab2..a5a9b538ff 100644
--- a/xen/arch/arm/mmu/setup.c
+++ b/xen/arch/arm/mmu/setup.c
@@ -339,6 +339,33 @@ void free_init_memory(void)
 printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10);
 }
 
+/**
+ * copy_from_paddr - copy data from a physical address
+ * @dst: destination virtual address
+ * @paddr: source physical address
+ * @len: length to copy
+ */
+void __init copy_from_paddr(void *dst, paddr_t paddr, unsigned long len)
+{
+void *src = (void *)FIXMAP_ADDR(FIXMAP_MISC);
+
+while (len) {
+unsigned long l, s;
+
+s = paddr & (PAGE_SIZE - 1);
+l = min(PAGE_SIZE - s, len);
+
+set_fixmap(FIXMAP_MISC, maddr_to_mfn(paddr), PAGE_HYPERVISOR_WC);
+memcpy(dst, src + s, l);
+clean_dcache_va_range(dst, l);
+clear_fixmap(FIXMAP_MISC);
+
+paddr += l;
+dst += l;
+len -= l;
+}
+}
+
 /*
  * Local variables:
  * mode: C
-- 
2.25.1




[PATCH v8 4/8] xen/arm: Extract MMU-specific MM code

2023-10-22 Thread Henry Wang
Currently, most of the code is in arm/mm.{c,h} and arm/arm64/mm.c
is MMU-specific. To make the MM code extendable, this commit extracts
the MMU-specific MM code.

Extract the boot CPU MM bringup code from arm/mm.c to mmu/setup.c.
While moving, mark pte_of_xenaddr() as __init to make clear that
this helper is only intended to be used during early boot.

Move arm/arm64/mm.c to arm/arm64/mmu/mm.c. Since the function
setup_directmap_mappings() has different implementations between
arm32 and arm64, move their arch-specific implementation to
arch-specific arm{32,64}/mmu/mm.c instead using #ifdef again.

For header files, move MMU-related function declarations in
asm/mm.h, declaration of global variable init_ttbr and the
declaration of dump_pt_walk() in asm/page.h to asm/mmu/mm.h

Also modify the build system (Makefiles in this case) to pick above
mentioned code changes.

Take the opportunity to fix the in-code comment coding styles when
possible, and drop the unnecessary #include headers in the original
arm/mm.c.

Signed-off-by: Henry Wang 
Signed-off-by: Penny Zheng 
Acked-by: Julien Grall 
---
v8:
- Add Julien's Acked-by tag.
v7:
- Move pte_of_xenaddr() to mmu/setup.c and mark it as __init.
- Also move the declaration of init_ttbr to asm/mmu/mm.h.
v6:
- Rework the original patch
  "[v5,07/13] xen/arm: Extract MMU-specific code"
---
 xen/arch/arm/arm32/Makefile   |   1 +
 xen/arch/arm/arm32/mmu/Makefile   |   1 +
 xen/arch/arm/arm32/mmu/mm.c   |  31 +++
 xen/arch/arm/arm64/Makefile   |   1 -
 xen/arch/arm/arm64/mmu/Makefile   |   1 +
 xen/arch/arm/arm64/{ => mmu}/mm.c |  37 +++
 xen/arch/arm/include/asm/mm.h |  25 +-
 xen/arch/arm/include/asm/mmu/mm.h |  50 
 xen/arch/arm/include/asm/page.h   |  15 --
 xen/arch/arm/mm.c | 385 --
 xen/arch/arm/mmu/Makefile |   1 +
 xen/arch/arm/mmu/setup.c  | 349 +++
 12 files changed, 477 insertions(+), 420 deletions(-)
 create mode 100644 xen/arch/arm/arm32/mmu/Makefile
 create mode 100644 xen/arch/arm/arm32/mmu/mm.c
 rename xen/arch/arm/arm64/{ => mmu}/mm.c (75%)
 create mode 100644 xen/arch/arm/include/asm/mmu/mm.h
 create mode 100644 xen/arch/arm/mmu/setup.c

diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile
index 520fb42054..40a2b4803f 100644
--- a/xen/arch/arm/arm32/Makefile
+++ b/xen/arch/arm/arm32/Makefile
@@ -1,4 +1,5 @@
 obj-y += lib/
+obj-$(CONFIG_MMU) += mmu/
 
 obj-$(CONFIG_EARLY_PRINTK) += debug.o
 obj-y += domctl.o
diff --git a/xen/arch/arm/arm32/mmu/Makefile b/xen/arch/arm/arm32/mmu/Makefile
new file mode 100644
index 00..b18cec4836
--- /dev/null
+++ b/xen/arch/arm/arm32/mmu/Makefile
@@ -0,0 +1 @@
+obj-y += mm.o
diff --git a/xen/arch/arm/arm32/mmu/mm.c b/xen/arch/arm/arm32/mmu/mm.c
new file mode 100644
index 00..647baf4a81
--- /dev/null
+++ b/xen/arch/arm/arm32/mmu/mm.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include 
+#include 
+
+/*
+ * Set up the direct-mapped xenheap:
+ * up to 1GB of contiguous, always-mapped memory.
+ */
+void __init setup_directmap_mappings(unsigned long base_mfn,
+ unsigned long nr_mfns)
+{
+int rc;
+
+rc = map_pages_to_xen(XENHEAP_VIRT_START, _mfn(base_mfn), nr_mfns,
+  PAGE_HYPERVISOR_RW | _PAGE_BLOCK);
+if ( rc )
+panic("Unable to setup the directmap mappings.\n");
+
+/* Record where the directmap is, for translation routines. */
+directmap_virt_end = XENHEAP_VIRT_START + nr_mfns * PAGE_SIZE;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile
index f89d5fb4fb..72161ff22e 100644
--- a/xen/arch/arm/arm64/Makefile
+++ b/xen/arch/arm/arm64/Makefile
@@ -11,7 +11,6 @@ obj-y += entry.o
 obj-y += head.o
 obj-y += insn.o
 obj-$(CONFIG_LIVEPATCH) += livepatch.o
-obj-y += mm.o
 obj-y += smc.o
 obj-y += smpboot.o
 obj-$(CONFIG_ARM64_SVE) += sve.o sve-asm.o
diff --git a/xen/arch/arm/arm64/mmu/Makefile b/xen/arch/arm/arm64/mmu/Makefile
index 3340058c08..a8a750a3d0 100644
--- a/xen/arch/arm/arm64/mmu/Makefile
+++ b/xen/arch/arm/arm64/mmu/Makefile
@@ -1 +1,2 @@
 obj-y += head.o
+obj-y += mm.o
diff --git a/xen/arch/arm/arm64/mm.c b/xen/arch/arm/arm64/mmu/mm.c
similarity index 75%
rename from xen/arch/arm/arm64/mm.c
rename to xen/arch/arm/arm64/mmu/mm.c
index 78b7c7eb00..36073041ed 100644
--- a/xen/arch/arm/arm64/mm.c
+++ b/xen/arch/arm/arm64/mmu/mm.c
@@ -151,6 +151,43 @@ void __init switch_ttbr(uint64_t ttbr)
 update_identity_mapping(false);
 }
 
+/* Map the region in the directmap area. */
+void __init setup_directmap_mappings(unsigned long base_mfn,
+ unsigned long nr_mfns)
+{
+int rc;
+
+/* First call sets the directmap physical and virtual offset. */
+if ( mfn_eq(directmap_mfn_start, INVALID_MFN) )
+{

[PATCH v8 8/8] xen/arm: mmu: move MMU specific P2M code to mmu/p2m.{c,h}

2023-10-22 Thread Henry Wang
From: Penny Zheng 

Current P2M implementation is designed for MMU system only.
We move the MMU-specific codes into mmu/p2m.c, and only keep generic
codes in p2m.c, like VMID allocator, etc. We also move MMU-specific
definitions and declarations to mmu/p2m.h, such as p2m_tlb_flush_sync().
Also expose previously static functions p2m_vmid_allocator_init(),
p2m_alloc_vmid() for further MPU usage. Since with the code movement
p2m_free_vmid() is now used in two files, also expose p2m_free_vmid().

With the code movement, global variable max_vmid is used in multiple
files instead of a single file (and will be used in MPU P2M
implementation), declare it in the header and remove the "static" of
this variable.

Also, since p2m_invalidate_root() should be MMU only and after the
code movement the only caller of p2m_invalidate_root() outside of
mmu/p2m.c is arch_domain_creation_finished(), creating a new function
named p2m_domain_creation_finished() in mmu/p2m.c for the original
code in arch_domain_creation_finished(), and marking
p2m_invalidate_root() as static.

Take the opportunity to fix the incorrect coding style when possible.
When there is bit shift in macros, take the opportunity to add the
missing 'U' as a compliance of MISRA.

Signed-off-by: Penny Zheng 
Signed-off-by: Wei Chen 
Signed-off-by: Henry Wang 
---
v8:
- Note: The renaming of p2m_flush_vm() is not done due to the
  unclarity of other maintainers' ideas.
- Also move P2M_ROOT_LEVEL, P2M_ROOT_ORDER and P2M_ROOT_PAGES to
  mmu/p2m.h. Move the two functions using p2m->root to mmu/p2m.c.
- Also move the declaration of p2m_clear_root_pages() to mmu/p2m.h.
- Expose p2m_free_vmid() as it is now used by two files.
- Take the opportunity to use 1U and add space before/after <<,
  update the commit message about this.
- Do not export setup_virt_paging_one(), instead, move
  cpu_virt_paging_callback() & co to mmu/p2m.c.
- Create a new function p2m_domain_creation_finished() in mmu/p2m.c
  for the original code in arch_domain_creation_finished(), and mark
  p2m_invalidate_root() as static.
v7:
- No change.
v6:
- Also move relinquish_p2m_mapping() to mmu/p2m.c, make
  __p2m_set_entry() static.
- Also move p2m_clear_root_pages() and p2m_flush_vm() to mmu/p2m.c.
- Don't add #ifdef CONFIG_MMU to the p2m_tlb_flush_sync() in
  p2m_write_unlock(), this need further discussion.
- Correct typo in commit message.
v5:
- No change
v4:
- Rework the patch to drop the unnecessary changes.
- Rework the commit msg a bit.
v3:
- remove MPU stubs
- adapt to the introduction of new directories: mmu/
v2:
- new commit
---
 xen/arch/arm/domain.c  |   11 +-
 xen/arch/arm/include/asm/mmu/p2m.h |   26 +
 xen/arch/arm/include/asm/p2m.h |   32 +-
 xen/arch/arm/mmu/Makefile  |1 +
 xen/arch/arm/mmu/p2m.c | 1834 ++
 xen/arch/arm/p2m.c | 1909 +---
 6 files changed, 1933 insertions(+), 1880 deletions(-)
 create mode 100644 xen/arch/arm/include/asm/mmu/p2m.h
 create mode 100644 xen/arch/arm/mmu/p2m.c

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 28e3aaa5e4..5e7a7f3e7e 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -870,16 +870,7 @@ int arch_domain_soft_reset(struct domain *d)
 
 void arch_domain_creation_finished(struct domain *d)
 {
-/*
- * To avoid flushing the whole guest RAM on the first Set/Way, we
- * invalidate the P2M to track what has been accessed.
- *
- * This is only turned when IOMMU is not used or the page-table are
- * not shared because bit[0] (e.g valid bit) unset will result
- * IOMMU fault that could be not fixed-up.
- */
-if ( !iommu_use_hap_pt(d) )
-p2m_invalidate_root(p2m_get_hostp2m(d));
+p2m_domain_creation_finished(d);
 }
 
 static int is_guest_pv32_psr(uint32_t psr)
diff --git a/xen/arch/arm/include/asm/mmu/p2m.h 
b/xen/arch/arm/include/asm/mmu/p2m.h
new file mode 100644
index 00..58496c0b09
--- /dev/null
+++ b/xen/arch/arm/include/asm/mmu/p2m.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef __ARM_MMU_P2M_H__
+#define __ARM_MMU_P2M_H__
+
+extern unsigned int p2m_root_order;
+extern unsigned int p2m_root_level;
+#define P2M_ROOT_ORDER p2m_root_order
+#define P2M_ROOT_LEVEL p2m_root_level
+#define P2M_ROOT_PAGES(1U << P2M_ROOT_ORDER)
+
+struct p2m_domain;
+void p2m_force_tlb_flush_sync(struct p2m_domain *p2m);
+void p2m_tlb_flush_sync(struct p2m_domain *p2m);
+
+void p2m_clear_root_pages(struct p2m_domain *p2m);
+
+#endif /* __ARM_MMU_P2M_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/include/asm/p2m.h b/xen/arch/arm/include/asm/p2m.h
index 940495d42b..e7428fb8db 100644
--- a/xen/arch/arm/include/asm/p2m.h
+++ b/xen/arch/arm/include/asm/p2m.h
@@ -14,10 +14,19 @@
 /* Holds the bit size of IPAs in p2m tables.  */
 extern unsigned int p2m_

[linux-linus test] 183492: tolerable FAIL - PUSHED

2023-10-22 Thread osstest service owner
flight 183492 linux-linus real [real]
http://logs.test-lab.xenproject.org/osstest/logs/183492/

Failures :-/ but no regressions.

Tests which did not succeed, but are not blocking:
 test-armhf-armhf-libvirt   16 saverestore-support-check fail blocked in 183490
 test-amd64-amd64-xl-qemut-win7-amd64 19 guest-stopfail like 183490
 test-amd64-amd64-xl-qemuu-win7-amd64 19 guest-stopfail like 183490
 test-amd64-amd64-xl-qemuu-ws16-amd64 19 guest-stopfail like 183490
 test-armhf-armhf-libvirt-raw 15 saverestore-support-checkfail  like 183490
 test-amd64-amd64-xl-qemut-ws16-amd64 19 guest-stopfail like 183490
 test-armhf-armhf-libvirt-qcow2 15 saverestore-support-check   fail like 183490
 test-amd64-amd64-qemuu-nested-amd 20 debian-hvm-install/l1/l2 fail like 183490
 test-amd64-amd64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-amd64-amd64-libvirt 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  16 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-armhf-armhf-xl-multivcpu 15 migrate-support-checkfail  never pass
 test-armhf-armhf-xl-multivcpu 16 saverestore-support-checkfail  never pass
 test-armhf-armhf-xl-arndale  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-arndale  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  16 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-qcow2 14 migrate-support-checkfail never pass
 test-amd64-amd64-libvirt-raw 14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 15 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-vhd  14 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-vhd  15 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt-raw 14 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-vhd  14 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-vhd  15 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt 15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-rtds 15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-rtds 16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt-qcow2 14 migrate-support-checkfail never pass

version targeted for testing:
 linuxfe3cfe869d5e0453754cf2b4c75110276b5e8527
baseline version:
 linux1acfd2bd3f0d9dc34ea1871a445c554220945d9f

Last test of basis   183490  2023-10-22 03:30:53 Z0 days
Testing same since   183492  2023-10-22 17:41:44 Z0 days1 attempts


People who touched revisions under test:
  Adrien Thierry 
  Ard Biesheuvel 
  Bo Liu 
  Dmitry Baryshkov 
  Geert Uytterhoeven 
  Jinjie Ruan 
  Kirill A. Shutemov 
  Konrad Dybcio 
  Kuan-Wei Chiu 
  Linus Torvalds 
  Michael Roth 
  Nikolay Borisov 
  Rob Herring 
  Tony Lindgren 
  Varadarajan Narayanan 
  Vinod Koul 
  Yang Yingliang 

jobs:
 build-amd64-xsm  pass
 build-arm64-xsm  pass
 build-i386-xsm   pass
 build-amd64  pass
 build-arm64  pass
 build-armhf  

Re: [PATCH 2/3] CHANGELOG.md: Set 4.18 release date and tag

2023-10-22 Thread Jan Beulich
On 20.10.2023 17:06, Henry Wang wrote:
>> On Oct 20, 2023, at 13:59, Jan Beulich  wrote:
>> On 20.10.2023 03:23, Henry Wang wrote:
 On Oct 20, 2023, at 00:14, Stefano Stabellini  
 wrote:
 On Thu, 19 Oct 2023, Henry Wang wrote:
> Signed-off-by: Henry Wang 
> ---
> CHANGELOG.md | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/CHANGELOG.md b/CHANGELOG.md
> index 47e98f036f..3c83878c9b 100644
> --- a/CHANGELOG.md
> +++ b/CHANGELOG.md
> @@ -4,7 +4,7 @@ Notable changes to Xen will be documented in this file.
>
> The format is based on [Keep a 
> Changelog](https://keepachangelog.com/en/1.0.0/)
>
> -## [unstable 
> UNRELEASED](https://xenbits.xen.org/gitweb/?p=xen.git;a=shortlog;h=staging)
>  - TBD
> +## 
> [4.18.0](https://xenbits.xen.org/gitweb/?p=xen.git;a=shortlog;h=RELEASE-4.18.0)
>  - 2023-10-30

 Should we use xenbits.xenproject.org instead? I think that's the
 official name. In any case:
>>>
>>> Hmmm, good question, but after some deeper look somehow I am more confused 
>>> now.
>>>
>>> So if I click the xen.git link in xenbits.xenproject.org 
>>> , I will be directed to
>>> "http://xenbits.xen.org/gitweb/?p=xen.git;a=summary”, where the http and 
>>> https git URL
>>> are both using "xenbits.xen.org”.
>>>
>>> However, "https://xenbits.xenproject.org/gitweb/?p=xen.git;a=summary” is 
>>> also a valid
>>> link, but the https and http git URL are still both using 
>>> “xenbits.xen.org”, also, all our previous
>>> releases seem to use "xenbits.xen.org".
>>>
>>> Could anyone in this community long enough provide a bit more 
>>> details/clarifications on this?
>>
>> Well, "xenproject" appeared later as a name, with the intention of
>> becoming the "canonical" one. Still it was likely easiest at the time
>> to simply add respective redirects in the web server(s).
> 
> I take above comment as you also prefer the “xenbits.xenproject.org”? Could 
> you please kindly
> confirm that?

Indeed I do.

Jan



Re: [PATCH] xen/sched: fix sched_move_domain()

2023-10-22 Thread Juergen Gross

On 20.10.23 20:03, Andrew Cooper wrote:

On 19/10/2023 12:23 pm, Juergen Gross wrote:

When moving a domain out of a cpupool running with the credit2
scheduler and having multiple run-queues, the following ASSERT() can
be observed:

(XEN) Xen call trace:
(XEN)[] R credit2.c#csched2_unit_remove+0xe3/0xe7
(XEN)[] S sched_move_domain+0x2f3/0x5b1
(XEN)[] S cpupool.c#cpupool_move_domain_locked+0x1d/0x3b
(XEN)[] S cpupool_move_domain+0x24/0x35
(XEN)[] S domain_kill+0xa5/0x116
(XEN)[] S do_domctl+0xe5f/0x1951
(XEN)[] S timer.c#timer_lock+0x69/0x143
(XEN)[] S pv_hypercall+0x44e/0x4a9
(XEN)[] S lstar_enter+0x137/0x140
(XEN)
(XEN)
(XEN) 
(XEN) Panic on CPU 1:
(XEN) Assertion 'svc->rqd == c2rqd(sched_unit_master(unit))' failed at 
common/sched/credit2.c:1159
(XEN) 

This is happening as sched_move_domain() is setting a different cpu
for a scheduling unit without telling the scheduler. When this unit is
removed from the scheduler, the ASSERT() will trigger.

In non-debug builds the result is usually a clobbered pointer, leading
to another crash a short time later.

Fix that by swapping the two involved actions (setting another cpu and
removing the unit from the scheduler).

Cc: Henry Wang 
Fixes: 70fadc41635b ("xen/cpupool: support moving domain between cpupools with 
different granularity")


Link: https://github.com/Dasharo/dasharo-issues/issues/488

And a Reported/Tested-by if the discoverer wishes.


Signed-off-by: Juergen Gross 
---
This fixes a regression introduced in Xen 4.15. The fix is very simple
and it will affect only configurations with multiple cpupools. I think
whether to include it in 4.18 should be decided by the release manager
based on the current state of the release (I think I wouldn't have
added it that late in the release while being the release manager).
---
  xen/common/sched/core.c | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index 12deefa745..e9f7486197 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -738,12 +738,13 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
  new_p = cpumask_first(d->cpupool->cpu_valid);
  for_each_sched_unit ( d, unit )
  {
-spinlock_t *lock = unit_schedule_lock_irq(unit);
+spinlock_t *lock;
+
+sched_remove_unit(old_ops, unit);
  
+lock = unit_schedule_lock_irq(unit);

  sched_set_res(unit, get_sched_res(new_p));
  spin_unlock_irq(lock);
-
-sched_remove_unit(old_ops, unit);


I'm happy to see the T-by, and that you know what's going on here, but I
don't understand the explanation.

The change here is the ordering of sched_remove_unit() with respect to
the lock/get&set/unlock block.


Yes.


remove unit is moderately complicated, but the get&set is just an RCU
pointer assignment.  But as the assertion fires in the latter action, it
must be the get&set causing problems.


Yes. As I wrote, it is because the cpu assignment of the unit is being
changed without telling the specific scheduler (credit2) about it.


And that's because new_p is actually a cpu number, which has the
consequence of causing Credit2's c2rqd() to materialise the wrong
csched2_runqueue_data pointer, and then we're operating on someone
else's data without a suitable lock held.


I haven't looked into the exact details what went wrong further down the
road, but I think it is not only the missing lock, but probably the
fact that depending on the use case different run queues will be addressed
for the same unit, causing inconsistencies.


And it's only by luck that none of the other schedulers tie something to
per-cpu data like this?


I didn't look into the other schedulers.


Other observations.

I think sched_move_domain() would be easier to follow with
s/new_p/new_cpu/ (and similar for unit_p) as "p" is not obviously
processor unless you notice the cpumask_first() calls.


Maybe. I don't have that problem, OTOH I've written that code. :-D


Why do we move a domain back to cpupool0 on domain destroy?  There's
nothing magic about cpupool0 that I'm aware of here.  It seems like
unnecessary complexity.


See commit bac6334b51d9.


Juergen


OpenPGP_0xB0DE9DD628BF132F.asc
Description: OpenPGP public key


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [XEN PATCH v2 00/10] address violations of MISRA C:2012 Directive 4.10

2023-10-22 Thread Jan Beulich
On 21.10.2023 01:26, Stefano Stabellini wrote:
> On Fri, 20 Oct 2023, Jan Beulich wrote:
>> On 19.10.2023 18:19, Stefano Stabellini wrote:
>>> On Thu, 19 Oct 2023, Jan Beulich wrote:
 On 19.10.2023 02:44, Stefano Stabellini wrote:
> On Wed, 18 Oct 2023, Jan Beulich wrote:
>> On 18.10.2023 02:48, Stefano Stabellini wrote:
>>> On Mon, 16 Oct 2023, Jan Beulich wrote:
 On 29.09.2023 00:24, Stefano Stabellini wrote:
> If it is not a MISRA requirement, then I think we should go for the 
> path
> of least resistance and try to make the smallest amount of changes
> overall, which seems to be:

 ... "least resistance" won't gain us much, as hardly any guards don't
 start with an underscore.

> - for xen/include/blah.h, __BLAH_H__
> - for xen/arch/arm/asm/include/blah.h, __ASM_ARM_BLAH_H__
> - for xen/arch/x86/asm/include/blah.h, it is far less consistent, 
> maybe __ASM_X86_BLAH_H__ ?

 There are no headers in xen/include/. For (e.g.) xen/include/xen/ we
 may go with XEN_BLAH_H; whether ASM prefixes are needed I'm not sure;
 we could go with just ARM_BLAH_H and X86_BLAH_H?

 The primary question though is (imo) how to deal with private headers,
 such that the risk of name collisions is as small as possible.
>>>
>>> Looking at concrete examples under xen/include/xen:
>>> xen/include/xen/mm.h __XEN_MM_H__
>>> xen/include/xen/dm.h __XEN_DM_H__
>>> xen/include/xen/hypfs.h __XEN_HYPFS_H__
>>>
>>> So I think we should do for consistency:
>>> xen/include/xen/blah.h __XEN_BLAH_H__
>>>
>>> Even if we know the leading underscore are undesirable, in this case I
>>> would prefer consistency.
>>
>> I'm kind of okay with that. FTAOD - here and below you mean to make this
>> one explicit first exception from the "no new leading underscores" goal,
>> for newly added headers?
>
> Yes. The reason is for consistency with the existing header files.
>
>
>>> On the other hand looking at ARM examples:
>>> xen/arch/arm/include/asm/traps.h __ASM_ARM_TRAPS__
>>> xen/arch/arm/include/asm/time.h __ARM_TIME_H__
>>> xen/arch/arm/include/asm/sysregs.h __ASM_ARM_SYSREGS_H
>>> xen/arch/arm/include/asm/io.h _ASM_IO_H
>>>
>>> And also looking at x86 examples:
>>> xen/arch/x86/include/asm/paging.h _XEN_PAGING_H
>>> xen/arch/x86/include/asm/p2m.h _XEN_ASM_X86_P2M_H
>>> xen/arch/x86/include/asm/io.h _ASM_IO_H
>>>
>>> Thet are very inconsistent.
>>>
>>>
>>> So for ARM and X86 headers I think we are free to pick anything we want,
>>> including your suggested ARM_BLAH_H and X86_BLAH_H. Those are fine by
>>> me.
>>
>> To be honest, I'd prefer a global underlying pattern, i.e. if common
>> headers are "fine" to use leading underscores for guards, arch header
>> should, too.
>
> I am OK with that too. We could go with:
> __ASM_ARM_BLAH_H__
> __ASM_X86_BLAH_H__
>
> I used "ASM" to make it easier to differentiate with the private headers
> below. Also the version without "ASM" would work but it would only
> differ with the private headers in terms of leading underscores. I
> thought that also having "ASM" would help readability and help avoid
> confusion.
>
>
>>> For private headers such as:
>>> xen/arch/arm/vuart.h __ARCH_ARM_VUART_H__
>>> xen/arch/arm/decode.h __ARCH_ARM_DECODE_H_
>>> xen/arch/x86/mm/p2m.h __ARCH_MM_P2M_H__
>>> xen/arch/x86/hvm/viridian/private.h X86_HVM_VIRIDIAN_PRIVATE_H
>>>
>>> More similar but still inconsistent. I would go with ARCH_ARM_BLAH_H and
>>> ARCH_X86_BLAH_H for new headers.
>>
>> I'm afraid I don't like this, as deeper paths would lead to unwieldy
>> guard names. If we continue to use double-underscore prefixed names
>> in common and arch headers, why don't we demand no leading underscores
>> and no path-derived prefixes in private headers? That'll avoid any
>> collisions between the two groups.
>
> OK, so for private headers:
>
> ARM_BLAH_H
> X86_BLAH_H
>
> What that work for you?

 What are the ARM_ and X86_ prefixes supposed to indicate here? Or to ask
 differently, how would you see e.g. common/decompress.h's guard named?
>>>
>>> I meant that:
>>>
>>> xen/arch/arm/blah.h would use ARM_BLAH_H
>>> xen/arch/x86/blah.h would use X86_BLAH_H
>>>
>>> You have a good question on something like xen/common/decompress.h and
>>> xen/common/event_channel.h.  What do you think about:
>>>
>>> COMMON_BLAH_H, so specifically COMMON_DECOMPRESS_H
>>>
>>> otherwise:
>>>
>>> XEN_BLAH_H, so specifically XEN_DECOMPRESS_H
>>>
>>> I prefer COMMON_BLAH_H but I think both versions are OK.
>>
>> IOW you disagree with my earlier "... and no path-derived prefixes",
>> and you prefe

Re: [XEN PATCH][for-4.19 v2] xen: Add SAF deviations for MISRA C:2012 Rule 7.1

2023-10-22 Thread Jan Beulich
On 20.10.2023 16:58, Nicola Vetrini wrote:
> On 20/10/2023 15:24, Jan Beulich wrote:
>> On 20.10.2023 12:33, Nicola Vetrini wrote:
>>> On 20/10/2023 08:38, Jan Beulich wrote:
 On 19.10.2023 18:34, Nicola Vetrini wrote:
> On 19/10/2023 17:57, Jan Beulich wrote:
>> On 19.10.2023 13:04, Nicola Vetrini wrote:
>>> --- a/automation/eclair_analysis/ECLAIR/deviations.ecl
>>> +++ b/automation/eclair_analysis/ECLAIR/deviations.ecl
>>> @@ -85,10 +85,10 @@ conform to the directive."
>>>  # Series 7.
>>>  #
>>>
>>> --doc_begin="Usage of the following constants is safe, since they
>>> are
>>> given as-is
>>> -in the inflate algorithm specification and there is therefore no
>>> risk
>>> of them
>>> -being interpreted as decimal constants."
>>> --config=MC3R1.R7.1,literals={safe,
>>> "^0(007|37|070|213|236|300|321|330|331|332|333|334|335|337|371)$"}
>>> +-doc_begin="Octal constants used as arguments to macro INSTR_ENC 
>>> or
>>> MASK_EXTR
>>> +can be used, because they appear as is in specifications, 
>>> manuals,
>>> and
>>> +algorithm descriptions."
>>> +-config=MC3R1.R7.1,reports+={safe,
>>> "any_area(any_loc(any_exp(macro(^(INSTR_ENC|MASK_EXTR)$"}
>>
>> INSTR_ENC() is a local macro in x86'es AMD SVM code. A macro of the
>> same
>> name could imo be introduced without issues in, say, Arm code. The
>> above
>> would then needlessly suppress findings there, aiui.
>>
>> MASK_EXTR() otoh is a global macro which ise used for various
>> purposes.
>> Excluding checking there is imo going too far, too.
>
> I should have thought about it; I can simply enforce the deviation 
> to
> additionally match
> only a specific file for each of the macros.

 That'll work for INSTR_ENC(), but not for MASK_EXTR().

>>>
>>> Why? What I'm deviating is reports due to octal constants used in
>>> expressions
>>> that contain MASK_EXTR in their expansion if and only if these are
>>> located in the
>>> file svm.h.
>>> No extra octal constant will match all these constraints.
>>
>> New MASK_EXTR() uses can appear at any time, without necessarily
>> matching the justification.
>>
>> Jan
> 
> Sorry, but I don't understand what's your concern exactly. With the 
> improvements I proposed
> (hence a new patch revision) I see the following possible future 
> scenarios:
> 
> 1. an use of MASK_EXTR() in a file other than x86/hvm/svm/emulate.c 
> appears, with no
> use of octal constants in the expansion. This won't be deviated;
> 2. an use of MASK_EXTR() in x86/hvm/svm/emulate.c appears, with no use 
> of octal
> constants in the expansion. This won't be deviated;
> 3. an use of MASK_EXTR() in x86/hvm/svm/emulate.c appears, with octal
> constants in the expansion. This will be deviated;

This is what I'm concerned of: How do you know up front whether such new
uses want deviating?

Jan

> 4. an use of any other macro with an octal constant in its expansion 
> won't be deviated,
> unless the configuration is suitably edited.
> 
> Does this address your concern?