From c4581b9cc558f573713ee0bb1c18bbc98341391c Mon Sep 17 00:00:00 2001 From: Stefan Reiter Date: Tue, 7 Apr 2020 15:56:18 +0200 Subject: [PATCH] Rework get_cpu_options and allow custom CPU models If a cputype is custom (check via prefix), try to load options from the custom CPU model config, and set values accordingly. While at it, extract currently hardcoded values into seperate sub and add reasonings. Since the new flag resolving outputs flags in sorted order for consistency, adapt the test cases to not break. Only the order is changed, not which flags are present. Signed-off-by: Stefan Reiter Reviewed-By: Fabian Ebner Tested-By: Fabian Ebner --- PVE/QemuServer/CPUConfig.pm | 187 +++++++++++++----- test/cfg2cmd/efi-raw-old.conf.cmd | 2 +- test/cfg2cmd/efi-raw.conf.cmd | 2 +- test/cfg2cmd/i440fx-win10-hostpci.conf.cmd | 2 +- test/cfg2cmd/minimal-defaults.conf.cmd | 2 +- test/cfg2cmd/pinned-version.conf.cmd | 2 +- .../q35-linux-hostpci-multifunction.conf.cmd | 2 +- test/cfg2cmd/q35-linux-hostpci.conf.cmd | 2 +- test/cfg2cmd/q35-win10-hostpci.conf.cmd | 2 +- test/cfg2cmd/simple1.conf.cmd | 2 +- test/cfg2cmd/spice-enhancments.conf.cmd | 2 +- test/cfg2cmd/spice-linux-4.1.conf.cmd | 2 +- test/cfg2cmd/spice-usb3.conf.cmd | 2 +- test/cfg2cmd/spice-win.conf.cmd | 2 +- 14 files changed, 152 insertions(+), 61 deletions(-) diff --git a/PVE/QemuServer/CPUConfig.pm b/PVE/QemuServer/CPUConfig.pm index 9fa6af98..af31b2b0 100644 --- a/PVE/QemuServer/CPUConfig.pm +++ b/PVE/QemuServer/CPUConfig.pm @@ -384,99 +384,190 @@ sub print_cpuflag_hash { return $formatted; } +sub parse_cpuflag_list { + my ($re, $reason, $flaglist) = @_; + + my $res = {}; + return $res if !$flaglist; + + foreach my $flag (split(";", $flaglist)) { + if ($flag =~ $re) { + $res->{$2} = { op => $1, reason => $reason }; + } + } + + return $res; +} + # Calculate QEMU's '-cpu' argument from a given VM configuration sub get_cpu_options { my ($conf, $arch, $kvm, $kvm_off, $machine_version, $winversion, $gpu_passthrough) = @_; - my $cpuFlags = []; - my $ostype = $conf->{ostype}; - - my $cpu = $kvm ? "kvm64" : "qemu64"; + my $cputype = $kvm ? "kvm64" : "qemu64"; if ($arch eq 'aarch64') { - $cpu = 'cortex-a57'; + $cputype = 'cortex-a57'; } + + my $cpu = {}; + my $custom_cpu; my $hv_vendor_id; - if (my $cputype = $conf->{cpu}) { - my $cpuconf = PVE::JSONSchema::parse_property_string($cpu_fmt, $cputype) - or die "Cannot parse cpu description: $cputype\n"; - $cpu = $cpuconf->{cputype}; - $kvm_off = 1 if $cpuconf->{hidden}; - $hv_vendor_id = $cpuconf->{'hv-vendor-id'}; + if (my $cpu_prop_str = $conf->{cpu}) { + $cpu = parse_vm_cpu_conf($cpu_prop_str) + or die "Cannot parse cpu description: $cpu_prop_str\n"; - if (defined(my $flags = $cpuconf->{flags})) { - push @$cpuFlags, split(";", $flags); + $cputype = $cpu->{cputype}; + + if (is_custom_model($cputype)) { + $custom_cpu = get_custom_model($cputype); + + $cputype = $custom_cpu->{'reported-model'} // + $cpu_fmt->{'reported-model'}->{default}; + $kvm_off = $custom_cpu->{hidden} + if defined($custom_cpu->{hidden}); + $hv_vendor_id = $custom_cpu->{'hv-vendor-id'}; } + + # VM-specific settings override custom CPU config + $kvm_off = $cpu->{hidden} + if defined($cpu->{hidden}); + $hv_vendor_id = $cpu->{'hv-vendor-id'} + if defined($cpu->{'hv-vendor-id'}); } - push @$cpuFlags , '+lahf_lm' if $cpu eq 'kvm64' && $arch eq 'x86_64'; + my $pve_flags = get_pve_cpu_flags($conf, $kvm, $cputype, $arch, + $machine_version); - push @$cpuFlags , '-x2apic' if $ostype && $ostype eq 'solaris'; + my $hv_flags = get_hyperv_enlightenments($winversion, $machine_version, + $conf->{bios}, $gpu_passthrough, $hv_vendor_id) if $kvm; - push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32'; + my $custom_cputype_flags = parse_cpuflag_list($cpu_flag_any_re, + "set by custom CPU model", $custom_cpu->{flags}); - push @$cpuFlags, '-rdtscp' if $cpu =~ m/^Opteron/; + my $vm_flags = parse_cpuflag_list($cpu_flag_supported_re, + "manually set for VM", $cpu->{flags}); - if (min_version($machine_version, 2, 3) && $arch eq 'x86_64') { + my $pve_forced_flags = {}; + $pve_forced_flags->{'enforce'} = { + reason => "error if requested CPU settings not available", + } if $cputype ne 'host' && $kvm && $arch eq 'x86_64'; + $pve_forced_flags->{'kvm'} = { + value => "off", + reason => "hide KVM virtualization from guest", + } if $kvm_off; - push @$cpuFlags , '+kvm_pv_unhalt' if $kvm; - push @$cpuFlags , '+kvm_pv_eoi' if $kvm; - } - - add_hyperv_enlightenments($cpuFlags, $winversion, $machine_version, $conf->{bios}, $gpu_passthrough, $hv_vendor_id) if $kvm; - - push @$cpuFlags, 'enforce' if $cpu ne 'host' && $kvm && $arch eq 'x86_64'; - - push @$cpuFlags, 'kvm=off' if $kvm_off; - - if (my $cpu_vendor = $cpu_vendor_list->{$cpu}) { - push @$cpuFlags, "vendor=${cpu_vendor}" - if $cpu_vendor ne 'default'; + # $cputype is the "reported-model" for custom types, so we can just look up + # the vendor in the default list + my $cpu_vendor = $cpu_vendor_list->{$cputype}; + if ($cpu_vendor) { + $pve_forced_flags->{'vendor'} = { + value => $cpu_vendor, + } if $cpu_vendor ne 'default'; } elsif ($arch ne 'aarch64') { die "internal error"; # should not happen } - $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags); + my $cpu_str = $cputype; - return ('-cpu', $cpu); + # will be resolved in parameter order + $cpu_str .= resolve_cpu_flags($pve_flags, $hv_flags, $custom_cputype_flags, + $vm_flags, $pve_forced_flags); + + return ('-cpu', $cpu_str); } -sub add_hyperv_enlightenments { - my ($cpuFlags, $winversion, $machine_version, $bios, $gpu_passthrough, $hv_vendor_id) = @_; +# Some hardcoded flags required by certain configurations +sub get_pve_cpu_flags { + my ($conf, $kvm, $cputype, $arch, $machine_version) = @_; + + my $pve_flags = {}; + my $pve_msg = "set by PVE;"; + + $pve_flags->{'lahf_lm'} = { + op => '+', + reason => "$pve_msg to support Windows 8.1+", + } if $cputype eq 'kvm64' && $arch eq 'x86_64'; + + $pve_flags->{'x2apic'} = { + op => '-', + reason => "$pve_msg incompatible with Solaris", + } if $conf->{ostype} && $conf->{ostype} eq 'solaris'; + + $pve_flags->{'sep'} = { + op => '+', + reason => "$pve_msg to support Windows 8+ and improve Windows XP+", + } if $cputype eq 'kvm64' || $cputype eq 'kvm32'; + + $pve_flags->{'rdtscp'} = { + op => '-', + reason => "$pve_msg broken on AMD Opteron", + } if $cputype =~ m/^Opteron/; + + if (min_version($machine_version, 2, 3) && $kvm && $arch eq 'x86_64') { + $pve_flags->{'kvm_pv_unhalt'} = { + op => '+', + reason => "$pve_msg to improve Linux guest spinlock performance", + }; + $pve_flags->{'kvm_pv_eoi'} = { + op => '+', + reason => "$pve_msg to improve Linux guest interrupt performance", + }; + } + + return $pve_flags; +} + +sub get_hyperv_enlightenments { + my ($winversion, $machine_version, $bios, $gpu_passthrough, $hv_vendor_id) = @_; return if $winversion < 6; return if $bios && $bios eq 'ovmf' && $winversion < 8; - if ($gpu_passthrough || defined($hv_vendor_id)) { + my $flags = {}; + my $default_reason = "automatic Hyper-V enlightenment for Windows"; + my $flagfn = sub { + my ($flag, $value, $reason) = @_; + $flags->{$flag} = { + reason => $reason // $default_reason, + value => $value, + } + }; + + my $hv_vendor_set = defined($hv_vendor_id); + if ($gpu_passthrough || $hv_vendor_set) { $hv_vendor_id //= 'proxmox'; - push @$cpuFlags , "hv_vendor_id=$hv_vendor_id"; + $flagfn->('hv_vendor_id', $hv_vendor_id, $hv_vendor_set ? + "custom hv_vendor_id set" : "NVIDIA workaround for GPU passthrough"); } if (min_version($machine_version, 2, 3)) { - push @$cpuFlags , 'hv_spinlocks=0x1fff'; - push @$cpuFlags , 'hv_vapic'; - push @$cpuFlags , 'hv_time'; + $flagfn->('hv_spinlocks', '0x1fff'); + $flagfn->('hv_vapic'); + $flagfn->('hv_time'); } else { - push @$cpuFlags , 'hv_spinlocks=0xffff'; + $flagfn->('hv_spinlocks', '0xffff'); } if (min_version($machine_version, 2, 6)) { - push @$cpuFlags , 'hv_reset'; - push @$cpuFlags , 'hv_vpindex'; - push @$cpuFlags , 'hv_runtime'; + $flagfn->('hv_reset'); + $flagfn->('hv_vpindex'); + $flagfn->('hv_runtime'); } if ($winversion >= 7) { - push @$cpuFlags , 'hv_relaxed'; + my $win7_reason = $default_reason . " 7 and higher"; + $flagfn->('hv_relaxed', undef, $win7_reason); if (min_version($machine_version, 2, 12)) { - push @$cpuFlags , 'hv_synic'; - push @$cpuFlags , 'hv_stimer'; + $flagfn->('hv_synic', undef, $win7_reason); + $flagfn->('hv_stimer', undef, $win7_reason); } if (min_version($machine_version, 3, 1)) { - push @$cpuFlags , 'hv_ipi'; + $flagfn->('hv_ipi', undef, $win7_reason); } } + + return $flags; } sub get_cpu_from_running_vm { diff --git a/test/cfg2cmd/efi-raw-old.conf.cmd b/test/cfg2cmd/efi-raw-old.conf.cmd index 5526a489..666cdb17 100644 --- a/test/cfg2cmd/efi-raw-old.conf.cmd +++ b/test/cfg2cmd/efi-raw-old.conf.cmd @@ -14,7 +14,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 512 \ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ diff --git a/test/cfg2cmd/efi-raw.conf.cmd b/test/cfg2cmd/efi-raw.conf.cmd index a3369327..cb0e984b 100644 --- a/test/cfg2cmd/efi-raw.conf.cmd +++ b/test/cfg2cmd/efi-raw.conf.cmd @@ -14,7 +14,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 512 \ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ diff --git a/test/cfg2cmd/i440fx-win10-hostpci.conf.cmd b/test/cfg2cmd/i440fx-win10-hostpci.conf.cmd index 43741ae9..2fe34a1d 100644 --- a/test/cfg2cmd/i440fx-win10-hostpci.conf.cmd +++ b/test/cfg2cmd/i440fx-win10-hostpci.conf.cmd @@ -15,7 +15,7 @@ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ -no-hpet \ - -cpu 'kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,hv_spinlocks=0x1fff,hv_vapic,hv_time,hv_reset,hv_vpindex,hv_runtime,hv_relaxed,hv_synic,hv_stimer,hv_ipi,enforce' \ + -cpu 'kvm64,enforce,hv_ipi,hv_relaxed,hv_reset,hv_runtime,hv_spinlocks=0x1fff,hv_stimer,hv_synic,hv_time,hv_vapic,hv_vpindex,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep' \ -m 512 \ -object 'memory-backend-ram,id=ram-node0,size=256M' \ -numa 'node,nodeid=0,cpus=0,memdev=ram-node0' \ diff --git a/test/cfg2cmd/minimal-defaults.conf.cmd b/test/cfg2cmd/minimal-defaults.conf.cmd index c499a859..0735f43e 100644 --- a/test/cfg2cmd/minimal-defaults.conf.cmd +++ b/test/cfg2cmd/minimal-defaults.conf.cmd @@ -12,7 +12,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 512 \ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ diff --git a/test/cfg2cmd/pinned-version.conf.cmd b/test/cfg2cmd/pinned-version.conf.cmd index 2fc31fc7..a7d0ae21 100644 --- a/test/cfg2cmd/pinned-version.conf.cmd +++ b/test/cfg2cmd/pinned-version.conf.cmd @@ -12,7 +12,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 1024 \ -readconfig /usr/share/qemu-server/pve-q35.cfg \ -device 'vmgenid,guid=bdd46b98-fefc-11e9-97b4-d72c378e0f96' \ diff --git a/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd b/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd index c766d338..a008939e 100644 --- a/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd +++ b/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd @@ -14,7 +14,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 512 \ -object 'memory-backend-ram,id=ram-node0,size=256M' \ -numa 'node,nodeid=0,cpus=0,memdev=ram-node0' \ diff --git a/test/cfg2cmd/q35-linux-hostpci.conf.cmd b/test/cfg2cmd/q35-linux-hostpci.conf.cmd index 7059b298..7e829ae2 100644 --- a/test/cfg2cmd/q35-linux-hostpci.conf.cmd +++ b/test/cfg2cmd/q35-linux-hostpci.conf.cmd @@ -14,7 +14,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 512 \ -object 'memory-backend-ram,id=ram-node0,size=256M' \ -numa 'node,nodeid=0,cpus=0,memdev=ram-node0' \ diff --git a/test/cfg2cmd/q35-win10-hostpci.conf.cmd b/test/cfg2cmd/q35-win10-hostpci.conf.cmd index 3397324b..133c0863 100644 --- a/test/cfg2cmd/q35-win10-hostpci.conf.cmd +++ b/test/cfg2cmd/q35-win10-hostpci.conf.cmd @@ -15,7 +15,7 @@ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ -no-hpet \ - -cpu 'kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,hv_spinlocks=0x1fff,hv_vapic,hv_time,hv_reset,hv_vpindex,hv_runtime,hv_relaxed,hv_synic,hv_stimer,hv_ipi,enforce' \ + -cpu 'kvm64,enforce,hv_ipi,hv_relaxed,hv_reset,hv_runtime,hv_spinlocks=0x1fff,hv_stimer,hv_synic,hv_time,hv_vapic,hv_vpindex,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep' \ -m 512 \ -object 'memory-backend-ram,id=ram-node0,size=256M' \ -numa 'node,nodeid=0,cpus=0,memdev=ram-node0' \ diff --git a/test/cfg2cmd/simple1.conf.cmd b/test/cfg2cmd/simple1.conf.cmd index b5c06cf4..34850644 100644 --- a/test/cfg2cmd/simple1.conf.cmd +++ b/test/cfg2cmd/simple1.conf.cmd @@ -12,7 +12,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 768 \ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ diff --git a/test/cfg2cmd/spice-enhancments.conf.cmd b/test/cfg2cmd/spice-enhancments.conf.cmd index 2d49b3a2..3951c065 100644 --- a/test/cfg2cmd/spice-enhancments.conf.cmd +++ b/test/cfg2cmd/spice-enhancments.conf.cmd @@ -12,7 +12,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 512 \ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ diff --git a/test/cfg2cmd/spice-linux-4.1.conf.cmd b/test/cfg2cmd/spice-linux-4.1.conf.cmd index 6aa781b9..2748cc99 100644 --- a/test/cfg2cmd/spice-linux-4.1.conf.cmd +++ b/test/cfg2cmd/spice-linux-4.1.conf.cmd @@ -12,7 +12,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 768 \ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ diff --git a/test/cfg2cmd/spice-usb3.conf.cmd b/test/cfg2cmd/spice-usb3.conf.cmd index 627c0777..c5156444 100644 --- a/test/cfg2cmd/spice-usb3.conf.cmd +++ b/test/cfg2cmd/spice-usb3.conf.cmd @@ -12,7 +12,7 @@ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ - -cpu kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,enforce \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 768 \ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ diff --git a/test/cfg2cmd/spice-win.conf.cmd b/test/cfg2cmd/spice-win.conf.cmd index 6f943584..22dfa9d7 100644 --- a/test/cfg2cmd/spice-win.conf.cmd +++ b/test/cfg2cmd/spice-win.conf.cmd @@ -13,7 +13,7 @@ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc unix:/var/run/qemu-server/8006.vnc,password \ -no-hpet \ - -cpu 'kvm64,+lahf_lm,+sep,+kvm_pv_unhalt,+kvm_pv_eoi,hv_spinlocks=0x1fff,hv_vapic,hv_time,hv_reset,hv_vpindex,hv_runtime,hv_relaxed,hv_synic,hv_stimer,hv_ipi,enforce' \ + -cpu 'kvm64,enforce,hv_ipi,hv_relaxed,hv_reset,hv_runtime,hv_spinlocks=0x1fff,hv_stimer,hv_synic,hv_time,hv_vapic,hv_vpindex,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep' \ -m 768 \ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \