mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-08-04 16:38:16 +00:00
Hostpci rework v4
Signed-off-by: Derumier Alexandre <aderumier@odiso.com>
This commit is contained in:
parent
0d29ab3bd2
commit
040b06b73e
@ -287,22 +287,6 @@ EODESC
|
|||||||
typetext => '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
|
typetext => '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
|
||||||
description => "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the guest will be restarted (or execute the action specified)",
|
description => "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the guest will be restarted (or execute the action specified)",
|
||||||
},
|
},
|
||||||
hostpci => {
|
|
||||||
optional => 1,
|
|
||||||
type => 'string', format => 'pve-qm-hostpci',
|
|
||||||
typetext => "HOSTPCIDEVICE { , HOSTPCIDEVICE }",
|
|
||||||
description => <<EODESCR,
|
|
||||||
Map host pci devices. HOSTPCIDEVICE syntax is:
|
|
||||||
|
|
||||||
'bus:dev.func' (hexadecimal numbers)
|
|
||||||
|
|
||||||
You can us the 'lspci' command to list existing pci devices.
|
|
||||||
|
|
||||||
Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
|
|
||||||
|
|
||||||
Experimental: user reported problems with this option.
|
|
||||||
EODESCR
|
|
||||||
},
|
|
||||||
serial => {
|
serial => {
|
||||||
optional => 1,
|
optional => 1,
|
||||||
type => 'string', format => 'pve-qm-serial',
|
type => 'string', format => 'pve-qm-serial',
|
||||||
@ -406,6 +390,7 @@ my $MAX_VIRTIO_DISKS = 6;
|
|||||||
my $MAX_USB_DEVICES = 5;
|
my $MAX_USB_DEVICES = 5;
|
||||||
my $MAX_NETS = 6;
|
my $MAX_NETS = 6;
|
||||||
my $MAX_UNUSED_DISKS = 8;
|
my $MAX_UNUSED_DISKS = 8;
|
||||||
|
my $MAX_HOSTPCI_DEVICES = 2;
|
||||||
|
|
||||||
my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
|
my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
|
||||||
'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
|
'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
|
||||||
@ -489,6 +474,27 @@ EODESCR
|
|||||||
};
|
};
|
||||||
PVE::JSONSchema::register_standard_option("pve-qm-usb", $usbdesc);
|
PVE::JSONSchema::register_standard_option("pve-qm-usb", $usbdesc);
|
||||||
|
|
||||||
|
my $hostpcidesc = {
|
||||||
|
optional => 1,
|
||||||
|
type => 'string', format => 'pve-qm-hostpci',
|
||||||
|
typetext => "HOSTPCIDEVICE",
|
||||||
|
description => <<EODESCR,
|
||||||
|
Map host pci devices. HOSTPCIDEVICE syntax is:
|
||||||
|
|
||||||
|
'bus:dev.func' (hexadecimal numbers)
|
||||||
|
|
||||||
|
You can us the 'lspci' command to list existing pci devices.
|
||||||
|
|
||||||
|
Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
|
||||||
|
|
||||||
|
Experimental: user reported problems with this option.
|
||||||
|
EODESCR
|
||||||
|
};
|
||||||
|
PVE::JSONSchema::register_standard_option("pve-qm-hostpci", $hostpcidesc);
|
||||||
|
|
||||||
|
for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
|
||||||
|
$confdesc->{"hostpci$i"} = $hostpcidesc;
|
||||||
|
}
|
||||||
|
|
||||||
for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
|
for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
|
||||||
$drivename_hash->{"ide$i"} = 1;
|
$drivename_hash->{"ide$i"} = 1;
|
||||||
@ -921,6 +927,22 @@ sub drive_is_cdrom {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub parse_hostpci {
|
||||||
|
my ($value) = @_;
|
||||||
|
|
||||||
|
return undef if !$value;
|
||||||
|
|
||||||
|
my $res = {};
|
||||||
|
|
||||||
|
if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
|
||||||
|
$res->{pciid} = $value;
|
||||||
|
} else {
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
# netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
|
# netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
|
||||||
sub parse_net {
|
sub parse_net {
|
||||||
my ($data) = @_;
|
my ($data) = @_;
|
||||||
@ -1028,15 +1050,12 @@ PVE::JSONSchema::register_format('pve-qm-hostpci', \&verify_hostpci);
|
|||||||
sub verify_hostpci {
|
sub verify_hostpci {
|
||||||
my ($value, $noerr) = @_;
|
my ($value, $noerr) = @_;
|
||||||
|
|
||||||
my @dl = split (/,/, $value);
|
return $value if parse_hostpci($value);
|
||||||
foreach my $v (@dl) {
|
|
||||||
if ($v !~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/i) {
|
|
||||||
return undef if $noerr;
|
return undef if $noerr;
|
||||||
|
|
||||||
die "unable to parse pci id\n";
|
die "unable to parse pci id\n";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVE::JSONSchema::register_format('pve-qm-watchdog', \&verify_watchdog);
|
PVE::JSONSchema::register_format('pve-qm-watchdog', \&verify_watchdog);
|
||||||
sub verify_watchdog {
|
sub verify_watchdog {
|
||||||
@ -1205,6 +1224,15 @@ sub cfs_config_path {
|
|||||||
return "nodes/$node/qemu-server/$vmid.conf";
|
return "nodes/$node/qemu-server/$vmid.conf";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub check_iommu_support{
|
||||||
|
#fixme : need to check IOMMU support
|
||||||
|
#http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
|
||||||
|
|
||||||
|
my $iommu=1;
|
||||||
|
return $iommu;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sub config_file {
|
sub config_file {
|
||||||
my ($vmid, $node) = @_;
|
my ($vmid, $node) = @_;
|
||||||
|
|
||||||
@ -1960,11 +1988,10 @@ sub config_to_command {
|
|||||||
push @$cmd, '-device', 'usb-tablet,bus=ehci.0,port=6' if $tablet;
|
push @$cmd, '-device', 'usb-tablet,bus=ehci.0,port=6' if $tablet;
|
||||||
|
|
||||||
# host pci devices
|
# host pci devices
|
||||||
if (my $pcidl = $conf->{hostpci}) {
|
for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
|
||||||
my @dl = split (/,/, $pcidl);
|
my $d = parse_hostpci($conf->{"hostpci$i"});
|
||||||
foreach my $dev (@dl) {
|
next if !$d;
|
||||||
push @$cmd, '-device', "pci-assign,host=$dev" if $dev;
|
push @$cmd, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# usb devices
|
# usb devices
|
||||||
@ -2277,15 +2304,14 @@ sub vm_start {
|
|||||||
|
|
||||||
my ($cmd, $vollist) = config_to_command ($storecfg, $vmid, $conf, $defaults, $migrate_uri);
|
my ($cmd, $vollist) = config_to_command ($storecfg, $vmid, $conf, $defaults, $migrate_uri);
|
||||||
# host pci devices
|
# host pci devices
|
||||||
if (my $pcidl = $conf->{hostpci}) {
|
for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
|
||||||
my @dl = split (/,/, $pcidl);
|
my $d = parse_hostpci($conf->{"hostpci$i"});
|
||||||
foreach my $dev (@dl) {
|
next if !$d;
|
||||||
$dev = lc($dev);
|
my $info = pci_device_info("0000:$d->{pciid}");
|
||||||
my $info = pci_device_info("0000:$dev");
|
die "IOMMU not present\n" if !check_iommu_support();
|
||||||
die "no pci device info for device '$dev'\n" if !$info;
|
die "no pci device info for device '$d->{pciid}'\n" if !$info;
|
||||||
die "can't unbind pci device '$dev'\n" if !pci_dev_bind_to_stub($info);
|
die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub($info);
|
||||||
die "can't reset pci device '$dev'\n" if !pci_dev_reset($info);
|
die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset($info);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PVE::Storage::activate_volumes($storecfg, $vollist);
|
PVE::Storage::activate_volumes($storecfg, $vollist);
|
||||||
|
Loading…
Reference in New Issue
Block a user