mirror of
git://git.proxmox.com/git/qemu-server.git
synced 2025-03-08 04:58:26 +03:00
pci: add conflict tests
best viewed with: git show -w Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
c4e1638148
commit
d7d698f60c
@ -8,122 +8,135 @@ print_pcie_addr
|
||||
print_pcie_root_port
|
||||
);
|
||||
|
||||
my $devices = {
|
||||
piix3 => { bus => 0, addr => 1 },
|
||||
ehci => { bus => 0, addr => 1 }, # instead of piix3 on arm
|
||||
vga => { bus => 0, addr => 2 },
|
||||
balloon0 => { bus => 0, addr => 3 },
|
||||
watchdog => { bus => 0, addr => 4 },
|
||||
scsihw0 => { bus => 0, addr => 5 },
|
||||
'pci.3' => { bus => 0, addr => 5 }, #can also be used for virtio-scsi-single bridge
|
||||
scsihw1 => { bus => 0, addr => 6 },
|
||||
ahci0 => { bus => 0, addr => 7 },
|
||||
qga0 => { bus => 0, addr => 8 },
|
||||
spice => { bus => 0, addr => 9 },
|
||||
virtio0 => { bus => 0, addr => 10 },
|
||||
virtio1 => { bus => 0, addr => 11 },
|
||||
virtio2 => { bus => 0, addr => 12 },
|
||||
virtio3 => { bus => 0, addr => 13 },
|
||||
virtio4 => { bus => 0, addr => 14 },
|
||||
virtio5 => { bus => 0, addr => 15 },
|
||||
hostpci0 => { bus => 0, addr => 16 },
|
||||
hostpci1 => { bus => 0, addr => 17 },
|
||||
net0 => { bus => 0, addr => 18 },
|
||||
net1 => { bus => 0, addr => 19 },
|
||||
net2 => { bus => 0, addr => 20 },
|
||||
net3 => { bus => 0, addr => 21 },
|
||||
net4 => { bus => 0, addr => 22 },
|
||||
net5 => { bus => 0, addr => 23 },
|
||||
vga1 => { bus => 0, addr => 24 },
|
||||
vga2 => { bus => 0, addr => 25 },
|
||||
vga3 => { bus => 0, addr => 26 },
|
||||
hostpci2 => { bus => 0, addr => 27 },
|
||||
hostpci3 => { bus => 0, addr => 28 },
|
||||
#addr29 : usb-host (pve-usb.cfg)
|
||||
'pci.1' => { bus => 0, addr => 30 },
|
||||
'pci.2' => { bus => 0, addr => 31 },
|
||||
'net6' => { bus => 1, addr => 1 },
|
||||
'net7' => { bus => 1, addr => 2 },
|
||||
'net8' => { bus => 1, addr => 3 },
|
||||
'net9' => { bus => 1, addr => 4 },
|
||||
'net10' => { bus => 1, addr => 5 },
|
||||
'net11' => { bus => 1, addr => 6 },
|
||||
'net12' => { bus => 1, addr => 7 },
|
||||
'net13' => { bus => 1, addr => 8 },
|
||||
'net14' => { bus => 1, addr => 9 },
|
||||
'net15' => { bus => 1, addr => 10 },
|
||||
'net16' => { bus => 1, addr => 11 },
|
||||
'net17' => { bus => 1, addr => 12 },
|
||||
'net18' => { bus => 1, addr => 13 },
|
||||
'net19' => { bus => 1, addr => 14 },
|
||||
'net20' => { bus => 1, addr => 15 },
|
||||
'net21' => { bus => 1, addr => 16 },
|
||||
'net22' => { bus => 1, addr => 17 },
|
||||
'net23' => { bus => 1, addr => 18 },
|
||||
'net24' => { bus => 1, addr => 19 },
|
||||
'net25' => { bus => 1, addr => 20 },
|
||||
'net26' => { bus => 1, addr => 21 },
|
||||
'net27' => { bus => 1, addr => 22 },
|
||||
'net28' => { bus => 1, addr => 23 },
|
||||
'net29' => { bus => 1, addr => 24 },
|
||||
'net30' => { bus => 1, addr => 25 },
|
||||
'net31' => { bus => 1, addr => 26 },
|
||||
'xhci' => { bus => 1, addr => 27 },
|
||||
'virtio6' => { bus => 2, addr => 1 },
|
||||
'virtio7' => { bus => 2, addr => 2 },
|
||||
'virtio8' => { bus => 2, addr => 3 },
|
||||
'virtio9' => { bus => 2, addr => 4 },
|
||||
'virtio10' => { bus => 2, addr => 5 },
|
||||
'virtio11' => { bus => 2, addr => 6 },
|
||||
'virtio12' => { bus => 2, addr => 7 },
|
||||
'virtio13' => { bus => 2, addr => 8 },
|
||||
'virtio14' => { bus => 2, addr => 9 },
|
||||
'virtio15' => { bus => 2, addr => 10 },
|
||||
'ivshmem' => { bus => 2, addr => 11 },
|
||||
'audio0' => { bus => 2, addr => 12 },
|
||||
hostpci4 => { bus => 2, addr => 13 },
|
||||
hostpci5 => { bus => 2, addr => 14 },
|
||||
hostpci6 => { bus => 2, addr => 15 },
|
||||
hostpci7 => { bus => 2, addr => 16 },
|
||||
hostpci8 => { bus => 2, addr => 17 },
|
||||
hostpci9 => { bus => 2, addr => 18 },
|
||||
hostpci10 => { bus => 2, addr => 19 },
|
||||
hostpci11 => { bus => 2, addr => 20 },
|
||||
hostpci12 => { bus => 2, addr => 21 },
|
||||
hostpci13 => { bus => 2, addr => 22 },
|
||||
hostpci14 => { bus => 2, addr => 23 },
|
||||
hostpci15 => { bus => 2, addr => 24 },
|
||||
'virtioscsi0' => { bus => 3, addr => 1 },
|
||||
'virtioscsi1' => { bus => 3, addr => 2 },
|
||||
'virtioscsi2' => { bus => 3, addr => 3 },
|
||||
'virtioscsi3' => { bus => 3, addr => 4 },
|
||||
'virtioscsi4' => { bus => 3, addr => 5 },
|
||||
'virtioscsi5' => { bus => 3, addr => 6 },
|
||||
'virtioscsi6' => { bus => 3, addr => 7 },
|
||||
'virtioscsi7' => { bus => 3, addr => 8 },
|
||||
'virtioscsi8' => { bus => 3, addr => 9 },
|
||||
'virtioscsi9' => { bus => 3, addr => 10 },
|
||||
'virtioscsi10' => { bus => 3, addr => 11 },
|
||||
'virtioscsi11' => { bus => 3, addr => 12 },
|
||||
'virtioscsi12' => { bus => 3, addr => 13 },
|
||||
'virtioscsi13' => { bus => 3, addr => 14 },
|
||||
'virtioscsi14' => { bus => 3, addr => 15 },
|
||||
'virtioscsi15' => { bus => 3, addr => 16 },
|
||||
'virtioscsi16' => { bus => 3, addr => 17 },
|
||||
'virtioscsi17' => { bus => 3, addr => 18 },
|
||||
'virtioscsi18' => { bus => 3, addr => 19 },
|
||||
'virtioscsi19' => { bus => 3, addr => 20 },
|
||||
'virtioscsi20' => { bus => 3, addr => 21 },
|
||||
'virtioscsi21' => { bus => 3, addr => 22 },
|
||||
'virtioscsi22' => { bus => 3, addr => 23 },
|
||||
'virtioscsi23' => { bus => 3, addr => 24 },
|
||||
'virtioscsi24' => { bus => 3, addr => 25 },
|
||||
'virtioscsi25' => { bus => 3, addr => 26 },
|
||||
'virtioscsi26' => { bus => 3, addr => 27 },
|
||||
'virtioscsi27' => { bus => 3, addr => 28 },
|
||||
'virtioscsi28' => { bus => 3, addr => 29 },
|
||||
'virtioscsi29' => { bus => 3, addr => 30 },
|
||||
'virtioscsi30' => { bus => 3, addr => 31 },
|
||||
my $pci_addr_map;
|
||||
sub get_pci_addr_map {
|
||||
$pci_addr_map = {
|
||||
piix3 => { bus => 0, addr => 1, conflict_ok => qw(ehci) },
|
||||
ehci => { bus => 0, addr => 1, conflict_ok => qw(piix3) }, # instead of piix3 on arm
|
||||
vga => { bus => 0, addr => 2 },
|
||||
balloon0 => { bus => 0, addr => 3 },
|
||||
watchdog => { bus => 0, addr => 4 },
|
||||
scsihw0 => { bus => 0, addr => 5, conflict_ok => qw(pci.3) },
|
||||
'pci.3' => { bus => 0, addr => 5, conflict_ok => qw(scsihw0) }, # also used for virtio-scsi-single bridge
|
||||
scsihw1 => { bus => 0, addr => 6 },
|
||||
ahci0 => { bus => 0, addr => 7 },
|
||||
qga0 => { bus => 0, addr => 8 },
|
||||
spice => { bus => 0, addr => 9 },
|
||||
virtio0 => { bus => 0, addr => 10 },
|
||||
virtio1 => { bus => 0, addr => 11 },
|
||||
virtio2 => { bus => 0, addr => 12 },
|
||||
virtio3 => { bus => 0, addr => 13 },
|
||||
virtio4 => { bus => 0, addr => 14 },
|
||||
virtio5 => { bus => 0, addr => 15 },
|
||||
hostpci0 => { bus => 0, addr => 16 },
|
||||
hostpci1 => { bus => 0, addr => 17 },
|
||||
net0 => { bus => 0, addr => 18 },
|
||||
net1 => { bus => 0, addr => 19 },
|
||||
net2 => { bus => 0, addr => 20 },
|
||||
net3 => { bus => 0, addr => 21 },
|
||||
net4 => { bus => 0, addr => 22 },
|
||||
net5 => { bus => 0, addr => 23 },
|
||||
vga1 => { bus => 0, addr => 24 },
|
||||
vga2 => { bus => 0, addr => 25 },
|
||||
vga3 => { bus => 0, addr => 26 },
|
||||
hostpci2 => { bus => 0, addr => 27 },
|
||||
hostpci3 => { bus => 0, addr => 28 },
|
||||
#addr29 : usb-host (pve-usb.cfg)
|
||||
'pci.1' => { bus => 0, addr => 30 },
|
||||
'pci.2' => { bus => 0, addr => 31 },
|
||||
'net6' => { bus => 1, addr => 1 },
|
||||
'net7' => { bus => 1, addr => 2 },
|
||||
'net8' => { bus => 1, addr => 3 },
|
||||
'net9' => { bus => 1, addr => 4 },
|
||||
'net10' => { bus => 1, addr => 5 },
|
||||
'net11' => { bus => 1, addr => 6 },
|
||||
'net12' => { bus => 1, addr => 7 },
|
||||
'net13' => { bus => 1, addr => 8 },
|
||||
'net14' => { bus => 1, addr => 9 },
|
||||
'net15' => { bus => 1, addr => 10 },
|
||||
'net16' => { bus => 1, addr => 11 },
|
||||
'net17' => { bus => 1, addr => 12 },
|
||||
'net18' => { bus => 1, addr => 13 },
|
||||
'net19' => { bus => 1, addr => 14 },
|
||||
'net20' => { bus => 1, addr => 15 },
|
||||
'net21' => { bus => 1, addr => 16 },
|
||||
'net22' => { bus => 1, addr => 17 },
|
||||
'net23' => { bus => 1, addr => 18 },
|
||||
'net24' => { bus => 1, addr => 19 },
|
||||
'net25' => { bus => 1, addr => 20 },
|
||||
'net26' => { bus => 1, addr => 21 },
|
||||
'net27' => { bus => 1, addr => 22 },
|
||||
'net28' => { bus => 1, addr => 23 },
|
||||
'net29' => { bus => 1, addr => 24 },
|
||||
'net30' => { bus => 1, addr => 25 },
|
||||
'net31' => { bus => 1, addr => 26 },
|
||||
'xhci' => { bus => 1, addr => 27 },
|
||||
'virtio6' => { bus => 2, addr => 1 },
|
||||
'virtio7' => { bus => 2, addr => 2 },
|
||||
'virtio8' => { bus => 2, addr => 3 },
|
||||
'virtio9' => { bus => 2, addr => 4 },
|
||||
'virtio10' => { bus => 2, addr => 5 },
|
||||
'virtio11' => { bus => 2, addr => 6 },
|
||||
'virtio12' => { bus => 2, addr => 7 },
|
||||
'virtio13' => { bus => 2, addr => 8 },
|
||||
'virtio14' => { bus => 2, addr => 9 },
|
||||
'virtio15' => { bus => 2, addr => 10 },
|
||||
'ivshmem' => { bus => 2, addr => 11 },
|
||||
'audio0' => { bus => 2, addr => 12 },
|
||||
hostpci4 => { bus => 2, addr => 13 },
|
||||
hostpci5 => { bus => 2, addr => 14 },
|
||||
hostpci6 => { bus => 2, addr => 15 },
|
||||
hostpci7 => { bus => 2, addr => 16 },
|
||||
hostpci8 => { bus => 2, addr => 17 },
|
||||
hostpci9 => { bus => 2, addr => 18 },
|
||||
hostpci10 => { bus => 2, addr => 19 },
|
||||
hostpci11 => { bus => 2, addr => 20 },
|
||||
hostpci12 => { bus => 2, addr => 21 },
|
||||
hostpci13 => { bus => 2, addr => 22 },
|
||||
hostpci14 => { bus => 2, addr => 23 },
|
||||
hostpci15 => { bus => 2, addr => 24 },
|
||||
'virtioscsi0' => { bus => 3, addr => 1 },
|
||||
'virtioscsi1' => { bus => 3, addr => 2 },
|
||||
'virtioscsi2' => { bus => 3, addr => 3 },
|
||||
'virtioscsi3' => { bus => 3, addr => 4 },
|
||||
'virtioscsi4' => { bus => 3, addr => 5 },
|
||||
'virtioscsi5' => { bus => 3, addr => 6 },
|
||||
'virtioscsi6' => { bus => 3, addr => 7 },
|
||||
'virtioscsi7' => { bus => 3, addr => 8 },
|
||||
'virtioscsi8' => { bus => 3, addr => 9 },
|
||||
'virtioscsi9' => { bus => 3, addr => 10 },
|
||||
'virtioscsi10' => { bus => 3, addr => 11 },
|
||||
'virtioscsi11' => { bus => 3, addr => 12 },
|
||||
'virtioscsi12' => { bus => 3, addr => 13 },
|
||||
'virtioscsi13' => { bus => 3, addr => 14 },
|
||||
'virtioscsi14' => { bus => 3, addr => 15 },
|
||||
'virtioscsi15' => { bus => 3, addr => 16 },
|
||||
'virtioscsi16' => { bus => 3, addr => 17 },
|
||||
'virtioscsi17' => { bus => 3, addr => 18 },
|
||||
'virtioscsi18' => { bus => 3, addr => 19 },
|
||||
'virtioscsi19' => { bus => 3, addr => 20 },
|
||||
'virtioscsi20' => { bus => 3, addr => 21 },
|
||||
'virtioscsi21' => { bus => 3, addr => 22 },
|
||||
'virtioscsi22' => { bus => 3, addr => 23 },
|
||||
'virtioscsi23' => { bus => 3, addr => 24 },
|
||||
'virtioscsi24' => { bus => 3, addr => 25 },
|
||||
'virtioscsi25' => { bus => 3, addr => 26 },
|
||||
'virtioscsi26' => { bus => 3, addr => 27 },
|
||||
'virtioscsi27' => { bus => 3, addr => 28 },
|
||||
'virtioscsi28' => { bus => 3, addr => 29 },
|
||||
'virtioscsi29' => { bus => 3, addr => 30 },
|
||||
'virtioscsi30' => { bus => 3, addr => 31 },
|
||||
} if !defined($pci_addr_map);
|
||||
return $pci_addr_map;
|
||||
}
|
||||
|
||||
my $get_addr_mapping_from_id = sub {
|
||||
my ($map, $id) = @_;
|
||||
|
||||
my $d = $map->{$id};
|
||||
return undef if !defined($d) || !defined($d->{bus}) || !defined($d->{addr});
|
||||
|
||||
return { bus => $d->{bus}, addr => sprintf("0x%x", $d->{addr}) };
|
||||
};
|
||||
|
||||
sub print_pci_addr {
|
||||
@ -131,30 +144,25 @@ sub print_pci_addr {
|
||||
|
||||
my $res = '';
|
||||
|
||||
# We use the same bus slots on all hardware, so we need to check special
|
||||
# cases here:
|
||||
# using same bus slots on all HW, so we need to check special cases here:
|
||||
my $busname = 'pci';
|
||||
if ($arch eq 'aarch64' && $machine =~ /^virt/) {
|
||||
die "aarch64/virt cannot use IDE devices\n"
|
||||
if $id =~ /^ide/;
|
||||
die "aarch64/virt cannot use IDE devices\n" if $id =~ /^ide/;
|
||||
$busname = 'pcie';
|
||||
}
|
||||
|
||||
if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
|
||||
my $addr = sprintf("0x%x", $devices->{$id}->{addr});
|
||||
my $bus = $devices->{$id}->{bus};
|
||||
$res = ",bus=$busname.$bus,addr=$addr";
|
||||
$bridges->{$bus} = 1 if $bridges;
|
||||
my $map = get_pci_addr_map();
|
||||
if (my $d = $get_addr_mapping_from_id->($map, $id)) {
|
||||
$res = ",bus=$busname.$d->{bus},addr=$d->{addr}";
|
||||
$bridges->{$d->{bus}} = 1 if $bridges;
|
||||
}
|
||||
return $res;
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub print_pcie_addr {
|
||||
my ($id) = @_;
|
||||
|
||||
my $res = '';
|
||||
my $devices = {
|
||||
my $pcie_addr_map;
|
||||
sub get_pcie_addr_map {
|
||||
$pcie_addr_map = {
|
||||
vga => { bus => 'pcie.0', addr => 1 },
|
||||
hostpci0 => { bus => "ich9-pcie-port-1", addr => 0 },
|
||||
hostpci1 => { bus => "ich9-pcie-port-2", addr => 0 },
|
||||
@ -190,15 +198,22 @@ sub print_pcie_addr {
|
||||
hostpci13bus0 => { bus => "pcie.0", addr => 22 },
|
||||
hostpci14bus0 => { bus => "pcie.0", addr => 23 },
|
||||
hostpci15bus0 => { bus => "pcie.0", addr => 24 },
|
||||
};
|
||||
} if !defined($pcie_addr_map);
|
||||
|
||||
if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {
|
||||
my $addr = sprintf("0x%x", $devices->{$id}->{addr});
|
||||
my $bus = $devices->{$id}->{bus};
|
||||
$res = ",bus=$bus,addr=$addr";
|
||||
return $pcie_addr_map;
|
||||
}
|
||||
|
||||
sub print_pcie_addr {
|
||||
my ($id) = @_;
|
||||
|
||||
my $res = '';
|
||||
|
||||
my $map = get_pcie_addr_map($id);
|
||||
if (my $d = $get_addr_mapping_from_id->($map, $id)) {
|
||||
$res = ",bus=$d->{bus},addr=$d->{addr}";
|
||||
}
|
||||
return $res;
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
# Generates the device strings for additional pcie root ports. The first 4 pcie
|
||||
|
@ -1,6 +1,6 @@
|
||||
all: test
|
||||
|
||||
test: test_snapshot test_ovf test_cfg_to_cmd
|
||||
test: test_snapshot test_ovf test_cfg_to_cmd test_pci_addr_conflicts
|
||||
|
||||
test_snapshot: run_snapshot_tests.pl
|
||||
./run_snapshot_tests.pl
|
||||
@ -11,3 +11,6 @@ test_ovf: run_ovf_tests.pl
|
||||
|
||||
test_cfg_to_cmd: run_config2command_tests.pl cfg2cmd/*.conf
|
||||
perl -I../ ./run_config2command_tests.pl
|
||||
|
||||
test_pci_addr_conflicts: run_pci_addr_checks.pl
|
||||
./run_pci_addr_checks.pl
|
||||
|
58
test/run_pci_addr_checks.pl
Executable file
58
test/run_pci_addr_checks.pl
Executable file
@ -0,0 +1,58 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use experimental 'smartmatch';
|
||||
|
||||
use lib qw(..);
|
||||
|
||||
use Test::More;
|
||||
|
||||
use PVE::QemuServer::PCI;
|
||||
|
||||
print "testing PCI(e) address conflicts\n";
|
||||
|
||||
# exec tests
|
||||
|
||||
#FIXME: make cross PCI <-> PCIe check sense at all??
|
||||
my $addr_map = {};
|
||||
my ($fail, $ignored) = (0, 0);
|
||||
sub check_conflict {
|
||||
my ($id, $what) = @_;
|
||||
|
||||
my ($bus, $addr) = $what->@{qw(bus addr)};
|
||||
my $full_addr = "$bus:$addr";
|
||||
|
||||
if (defined(my $conflict = $addr_map->{$full_addr})) {
|
||||
if (my @ignores = $what->{conflict_ok}) {
|
||||
if ($conflict ~~ @ignores) {
|
||||
note("OK: ignore conflict for '$full_addr' between '$id' and '$conflict'");
|
||||
$ignored++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
note("ERR: conflict for '$full_addr' between '$id' and '$conflict'");
|
||||
$fail++;
|
||||
} else {
|
||||
$addr_map->{$full_addr} = $id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $pci_map = PVE::QemuServer::PCI::get_pci_addr_map();
|
||||
while (my ($id, $what) = each %$pci_map) {
|
||||
check_conflict($id, $what);
|
||||
}
|
||||
|
||||
my $pcie_map = PVE::QemuServer::PCI::get_pcie_addr_map();
|
||||
while (my ($id, $what) = each %$pcie_map) {
|
||||
check_conflict($id, $what);
|
||||
}
|
||||
|
||||
if ($fail) {
|
||||
fail("PCI(e) address conflict check, ignored: $ignored, conflicts: $fail");
|
||||
} else {
|
||||
pass("PCI(e) address conflict check, ignored: $ignored");
|
||||
}
|
||||
|
||||
done_testing();
|
Loading…
x
Reference in New Issue
Block a user