Feature: add MAXPHYSADDR option in advanced.

This commit is contained in:
SimonFair
2025-07-04 16:27:27 +01:00
parent c3fbd382aa
commit 2664ad68fc
3 changed files with 68 additions and 4 deletions

View File

@@ -353,11 +353,17 @@ class Libvirt {
}
if (!empty($domain['cpumigrate'])) $cpumigrate = " migratable='".$domain['cpumigrate']."'";
}
$cpupmemlmt ='';
if ($domain['cpupmemlmt'] != "None") {
if ($domain['cpumode'] == 'host-passthrough') $cpupmemlmt = "<maxphysaddr mode='passthrough' limit='{$domain['cpupmemlmt']}'/>";
else $cpupmemlmt = "<maxphysaddr mode='emulate' bits='{$domain['cpupmemlmt']}'/>";
}
#<cpu mode='custom' match='exact' check='partial'>
#<model fallback='allow'>Skylake-Client-noTSX-IBRS</model>
$cpustr = "<cpu $cpumode $cpumigrate>
<topology sockets='1' cores='{$intCores}' threads='{$intThreads}'/>
$cpucache
$cpupmemlmt
$cpufeatures
</cpu>
<vcpu placement='static'>{$vcpus}</vcpu>
@@ -2033,6 +2039,25 @@ class Libvirt {
return $var;
}
function domain_get_cpu_pmem_limit($domain) {
$cpu_mode = $this->get_xpath($domain, '//domain/cpu/@mode', false);
if (!$cpu_mode) return null;
$cpu_mode = $cpu_mode[0];
if ($cpu_mode === 'host-passthrough') {
// In passthrough mode, limit is a bit count (e.g., limit="39")
$limit = $this->get_xpath($domain, '//domain/cpu/maxphysaddr/@limit', false);
return $limit ? intval($limit[0]) : "None";
} elseif ($cpu_mode === 'custom') {
// In custom mode, bits defines the max physical address width
$bits = $this->get_xpath($domain, '//domain/cpu/maxphysaddr/@bits', false);
return $bits ? intval($bits[0]) : "None";
}
return "None"; // no limit found or not enforced
}
# <cpu mode='custom' match='exact' check='partial'>
# <model fallback='allow'>Skylake-Client-noTSX-IBRS</model>

View File

@@ -1002,7 +1002,7 @@ class Array2XML {
if (empty($arrMatch['name'])) {
// Device name is blank, attempt to lookup usb details
exec("lsusb -d ".$arrMatch['id']." -v 2>/dev/null | grep -Po '^\s+(iManufacturer|iProduct)\s+[1-9]+ \K[^\\n]+'", $arrAltName);
exec("lsusb -d ".$arrMatch['id']." -v 2>/dev/null | grep -Po '^\s+(iManufacturer|iProduct)\s+[1-9]+ \K[^\\n]+'", $arrAltName); #PHPS
$arrMatch['name'] = trim(implode(' ', (array)$arrAltName));
if (empty($arrMatch['name'])) {
@@ -1405,6 +1405,7 @@ class Array2XML {
'maxmem' => $lv->domain_get_memory($res),
'password' => '', //TODO?
'cpumode' => $lv->domain_get_cpu_type($res),
'cpupmemlmt' => $lv->domain_get_cpu_pmem_limit($res),
'cpumigrate' => $lv->domain_get_cpu_migrate($res),
'vcpus' => $dom['nrVirtCpu'],
'vcpu' => $lv->domain_get_vcpu_pins($res),
@@ -1506,7 +1507,7 @@ class Array2XML {
// remove existing auto-generated settings
unset($old['cputune']['vcpupin'],$old['devices']['video'],$old['devices']['disk'],$old['devices']['interface'],$old['devices']['filesystem'],$old['cpu']['@attributes'],$old['os']['boot'],$old['os']['loader'],$old['os']['nvram']);
// Remove old CPU cache and features
unset($old['cpu']['cache'], $old['cpu']['feature']);
unset($old['cpu']['cache'], $old['cpu']['feature'], $old['cpu']['maxphysaddr']);
unset($old['features']['hyperv'],$old['devices']['channel']);
// set namespace
$new['metadata']['vmtemplate']['@attributes']['xmlns'] = 'unraid';
@@ -1803,7 +1804,7 @@ class Array2XML {
}
$cmdstr = "rsync -ahPIXS --out-format=%f --info=flist0,misc0,stats0,name1,progress2 '$repsrc' '$reptgt'";
$error = execCommand_nchan_clone($cmdstr,$target,$refcmd);
$error = execCommand_nchan_clone($cmdstr,$target,$refcmd); #PHPS
if (!$error) { write("addLog\0".htmlspecialchars("Image copied failed.")); return( false); }
}
}
@@ -1895,7 +1896,7 @@ class Array2XML {
$file = $disk["file"];
if ($disk['device'] == "hdc" ) $primarypath = dirname(transpose_user_path($file));
$output = array();
exec("qemu-img info --backing-chain -U '$file' | grep image:",$output);
exec("qemu-img info --backing-chain -U '$file' | grep image:",$output); #PHPS
foreach($output as $key => $line) {
$line=str_replace("image: ","",$line);
$output[$key] = $line;

View File

@@ -133,6 +133,7 @@ $arrConfigDefaults = [
]
];
$hdrXML = "<?xml version='1.0' encoding='UTF-8'?>\n"; // XML encoding declaration
$debug = false;
// Merge in any default values from the VM template
if ($arrAllTemplates[$strSelectedTemplate] && $arrAllTemplates[$strSelectedTemplate]['overrides']) {
@@ -256,6 +257,12 @@ if (isset($_POST['updatevm'])) {
if ($error = create_vdisk($_POST) === false) {
$arrExistingConfig = custom::createArray('domain',$strXML);
$arrUpdatedConfig = custom::createArray('domain',$lv->config_to_xml($_POST));
if ($debug) {
file_put_contents("/tmp/vmdebug_exist",$strXML);
file_put_contents("/tmp/vmdebug_new",$lv->config_to_xml($_POST));
file_put_contents("/tmp/vmdebug_arrayN",json_encode($arrUpdatedConfig,JSON_PRETTY_PRINT));
file_put_contents("/tmp/vmdebug_arrayE",json_encode($arrExistingConfig,JSON_PRETTY_PRINT));
}
array_update_recursive($arrExistingConfig, $arrUpdatedConfig);
$arrConfig = array_replace_recursive($arrExistingConfig, $arrUpdatedConfig);
$xml = custom::createXML('domain',$arrConfig)->saveXML();
@@ -1903,6 +1910,37 @@ foreach ($arrConfig['evdev'] as $i => $arrEvdev) {
</p>
</blockquote>
</div>
<table>
</tr>
<tr class="advanced">
<td><span class="advanced">_(Physical Address Bit Limit)_ </span></td>
<td>
<span class="width"><select id="cpupmemlmt" name="domain[cpupmemlmt]" class="cpupmem">
<?
echo mk_option($arrConfig['domain']['cpupmemlmt'], 'None', 'None');
echo mk_option($arrConfig['domain']['cpupmemlmt'], '32', '32-bit (4 GB)');
echo mk_option($arrConfig['domain']['cpupmemlmt'], '36', '36-bit (64 GB)');
echo mk_option($arrConfig['domain']['cpupmemlmt'], '39', '39-bit (512 GB)');
echo mk_option($arrConfig['domain']['cpupmemlmt'], '42', '42-bit (4 TB)');
echo mk_option($arrConfig['domain']['cpupmemlmt'], '48', '48-bit (256 TB)');
?>
</td>
</tr>
</table>
<div class="advanced">
<blockquote class="inline_help">
<p>
<b>Physical Address Bit Limit</b><br>
Sets limit on the physical address space.
<br>
Some guest systems or GPUs passed through might not work properly if mapped to high physical addresses (especially GPUs with 32-bit BARs). Using maxphysaddr=36 or maxphysaddr=39 limits the physical memory below 64 GB or 512 GB, avoiding such issues.
<br>
<br>bits=32 Addressable Memory 4 GB Use Case: Force 32-bit PCI compatibility
<br>bits=36 Addressable Memory 64 GB Use Case: Compatibility with older devices / 32-bit BARs
<br>bits=39 Addressable Memory 512 GB Use Case: Safe for most modern guests
<br>bits=48 Addressable Memory 256 TB Use Case: Full addressing, default on modern CPUs
</p>
</div>
<?}?>
<?}?>