[pve-devel] [PATCH qemu-server] Properly identify the CPU architecture of 32-bit VMs

Filip Schauer f.schauer at proxmox.com
Mon Dec 11 15:12:56 CET 2023


Add an i386 CPU architecture which is used when a 32 bit CPU type is
detected.

This now prevents starting a 32-bit VM using a 64-bit OVMF BIOS. Instead
it throws the error, "no OVMF images known for architecture 'i386'",
triggered in get_ovmf_file. This behaviour is intended since we do not
support 32 bit OVMF images.

Signed-off-by: Filip Schauer <f.schauer at proxmox.com>
---
 PVE/QemuServer.pm           |  8 +++++---
 PVE/QemuServer/CPUConfig.pm | 28 ++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 2063e66..54590df 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -52,7 +52,7 @@ use PVE::QemuConfig;
 use PVE::QemuServer::Helpers qw(config_aware_timeout min_version windows_version);
 use PVE::QemuServer::Cloudinit;
 use PVE::QemuServer::CGroup;
-use PVE::QemuServer::CPUConfig qw(print_cpu_device get_cpu_options);
+use PVE::QemuServer::CPUConfig qw(print_cpu_device get_cpu_options cpu_type_to_arch);
 use PVE::QemuServer::Drive qw(is_valid_drivename drive_is_cloudinit drive_is_cdrom drive_is_read_only parse_drive print_drive);
 use PVE::QemuServer::Machine;
 use PVE::QemuServer::Memory qw(get_current_memory);
@@ -649,7 +649,7 @@ EODESCR
 	description => "Virtual processor architecture. Defaults to the host.",
 	optional => 1,
 	type => 'string',
-	enum => [qw(x86_64 aarch64)],
+	enum => [qw(x86_64 i386 aarch64)],
     },
     smbios1 => {
 	description => "Specify SMBIOS type 1 fields.",
@@ -3293,11 +3293,12 @@ sub is_native($) {
 
 sub get_vm_arch {
     my ($conf) = @_;
-    return $conf->{arch} // get_host_arch();
+    return $conf->{arch} // cpu_type_to_arch($conf->{cpu}) // get_host_arch();
 }
 
 my $default_machines = {
     x86_64 => 'pc',
+    i386 => 'pc',
     aarch64 => 'virt',
 };
 
@@ -3390,6 +3391,7 @@ sub get_ovmf_files($$$) {
 
 my $Arch2Qemu = {
     aarch64 => '/usr/bin/qemu-system-aarch64',
+    i386 => '/usr/bin/qemu-system-i386',
     x86_64 => '/usr/bin/qemu-system-x86_64',
 };
 sub get_command_for_arch($) {
diff --git a/PVE/QemuServer/CPUConfig.pm b/PVE/QemuServer/CPUConfig.pm
index 750d3b6..cc71298 100644
--- a/PVE/QemuServer/CPUConfig.pm
+++ b/PVE/QemuServer/CPUConfig.pm
@@ -3,6 +3,8 @@ package PVE::QemuServer::CPUConfig;
 use strict;
 use warnings;
 
+use List::Util qw(first);
+
 use PVE::JSONSchema;
 use PVE::Cluster qw(cfs_register_file cfs_read_file);
 use PVE::QemuServer::Helpers qw(min_version);
@@ -12,6 +14,7 @@ use base qw(PVE::SectionConfig Exporter);
 our @EXPORT_OK = qw(
 print_cpu_device
 get_cpu_options
+cpu_type_to_arch
 );
 
 # under certain race-conditions, this module might be loaded before pve-cluster
@@ -57,6 +60,17 @@ my $depreacated_cpu_map = {
     'Icelake-Client-noTSX' => 'Icelake-Server-noTSX',
 };
 
+my @cpu_32bit_list = (
+    '486',
+    'pentium',
+    'pentium2',
+    'pentium3',
+    'coreduo',
+    'athlon',
+    'kvm32',
+    'qemu32',
+);
+
 my $cpu_vendor_list = {
     # Intel CPUs
     486 => 'GenuineIntel',
@@ -646,6 +660,20 @@ sub get_pve_cpu_flags {
     return $pve_flags;
 }
 
+sub cpu_type_to_arch {
+    my ($cputype) = @_;
+
+    if ($cputype) {
+	if (first {$_ eq $cputype} @cpu_32bit_list) {
+	    return 'i386';
+	} elsif ($cpu_vendor_list->{$cputype}) {
+	    return 'x86_64';
+	}
+    }
+
+    return undef;
+}
+
 sub get_hyperv_enlightenments {
     my ($winversion, $machine_version, $bios, $gpu_passthrough, $hv_vendor_id) = @_;
 
-- 
2.39.2





More information about the pve-devel mailing list