[pve-devel] [RFC manager 9/9] Initial attempt at CPU flag editor for custom models

Stefan Reiter s.reiter at proxmox.com
Thu Oct 28 13:41:50 CEST 2021


Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---

I believe this one is the most outdated, it's original title in my working
branch was "tmp", dating back to more than a year ago ;)

 www/manager6/dc/CPUTypeEdit.js         |   8 ++
 www/manager6/form/VMCPUFlagSelector.js | 125 ++++++++++++++++++++-----
 2 files changed, 108 insertions(+), 25 deletions(-)

diff --git a/www/manager6/dc/CPUTypeEdit.js b/www/manager6/dc/CPUTypeEdit.js
index 3ad527c4..8479c61e 100644
--- a/www/manager6/dc/CPUTypeEdit.js
+++ b/www/manager6/dc/CPUTypeEdit.js
@@ -76,6 +76,14 @@ Ext.define('PVE.dc.CPUTypeEdit', {
 		    name: 'phys-bits',
 		},
 	    ],
+	    columnB: [
+		{
+		    xtype: 'vmcpuflagselector',
+		    fieldLabel: gettext('Extra CPU Flags'),
+		    name: 'flags',
+		    restrictToVMFlags: false,
+		},
+	    ],
 	},
     ],
 });
diff --git a/www/manager6/form/VMCPUFlagSelector.js b/www/manager6/form/VMCPUFlagSelector.js
index a6d17930..69ef2331 100644
--- a/www/manager6/form/VMCPUFlagSelector.js
+++ b/www/manager6/form/VMCPUFlagSelector.js
@@ -6,6 +6,10 @@ Ext.define('PVE.form.VMCPUFlagSelector', {
 	field: 'Ext.form.field.Field',
     },
 
+    config: {
+	restrictToVMFlags: true,
+    },
+
     disableSelection: true,
     columnLines: false,
     selectable: false,
@@ -59,7 +63,7 @@ Ext.define('PVE.form.VMCPUFlagSelector', {
 	    }
 	});
 
-	flags += (flags.length > 0 ? ';' : '') + me.unknownFlags.join(';');
+	flags += (me.unknownFlags.length > 0 ? ';' : '') + me.unknownFlags.join(';');
 
 	return flags;
     },
@@ -70,30 +74,22 @@ Ext.define('PVE.form.VMCPUFlagSelector', {
 
 	me.value = value || '';
 
-	me.unknownFlags = [];
-
-	me.getStore().queryBy(Ext.returnTrue).each(function(rec) {
-	    rec.set('state', '=');
-	});
-
-	var flags = value ? value.split(';') : [];
-	flags.forEach(function(flag) {
-	    var sign = flag.substr(0, 1);
-	    let flagName = flag.substr(1);
-
-	    var rec = store.findRecord('flag', flagName, 0, false, true, true);
-	    if (rec !== null) {
-		rec.set('state', sign);
-	    } else {
-		me.unknownFlags.push(flag);
-	    }
-	});
-	store.reload();
+	// if the store is already reloading it will apply me.value to itself
+	// once it's done, otherwise trigger reload now
+	if (!store.isLoading()) {
+	    store.reload();
+	}
 
 	var res = me.mixins.field.setValue.call(me, value);
 
 	return res;
     },
+
+    isDirty: function() {
+	let me = this;
+	return me.originalValue !== me.getValue();
+    },
+
     columns: [
 	{
 	    dataIndex: 'state',
@@ -165,12 +161,91 @@ Ext.define('PVE.form.VMCPUFlagSelector', {
     ],
 
     initComponent: function() {
-	var me = this;
+	let me = this;
 
-	// static class store, thus gets not recreated, so ensure defaults are set!
-	me.getStore().data.forEach(function(v) {
-	    v.state = '=';
-	});
+	let data = [
+	    { flag: 'md-clear', desc: 'Required to let the guest OS know if MDS is mitigated correctly' },
+	    { flag: 'pcid', desc: 'Meltdown fix cost reduction on Westmere, Sandy-, and IvyBridge Intel CPUs' },
+	    { flag: 'spec-ctrl', desc: 'Allows improved Spectre mitigation with Intel CPUs' },
+	    { flag: 'ssbd', desc: 'Protection for "Speculative Store Bypass" for Intel models' },
+	    { flag: 'ibpb', desc: 'Allows improved Spectre mitigation with AMD CPUs' },
+	    { flag: 'virt-ssbd', desc: 'Basis for "Speculative Store Bypass" protection for AMD models' },
+	    { flag: 'amd-ssbd', desc: 'Improves Spectre mitigation performance with AMD CPUs, best used with "virt-ssbd"' },
+	    { flag: 'amd-no-ssb', desc: 'Notifies guest OS that host is not vulnerable for Spectre on AMD CPUs' },
+	    { flag: 'pdpe1gb', desc: 'Allow guest OS to use 1GB size pages, if host HW supports it' },
+	    { flag: 'hv-tlbflush', desc: 'Improve performance in overcommitted Windows guests. May lead to guest bluescreens on old CPUs.' },
+	    { flag: 'hv-evmcs', desc: 'Improve performance for nested virtualization. Only supported on Intel CPUs.' },
+	    { flag: 'aes', desc: 'Activate AES instruction set for HW acceleration.' },
+	];
+
+	let afterLoadFn = function(store) {
+	    // apply me.value to store after loading is complete
+	    me.unknownFlags = [];
+	    let flags = me.value ? me.value.split(';') : [];
+
+	    flags.forEach(function(flag) {
+		let sign = flag.substr(0, 1);
+		let flagName = flag.substr(1);
+
+		let rec = store.findRecord('flag', flagName);
+		if (rec) {
+		    rec.set('state', sign);
+		    rec.commit();
+		} else {
+		    me.unknownFlags.push(flag);
+		}
+	    });
+
+	    setTimeout(function() { me.getView().refresh(); }, 1);
+	};
+
+	if (me.restrictToVMFlags) {
+	    me.store = Ext.create('Ext.data.Store', {
+		type: 'store',
+		data: data,
+		fields: ['flag', { name: 'state', defaultValue: '=' }, 'desc'],
+		listeners: {
+		    load: function(store, records, success) {
+			if (success) {
+			    afterLoadFn(store);
+			}
+		    },
+		    update: function() {
+			this.commitChanges();
+		    },
+		},
+	    });
+	} else {
+	    me.store = Ext.create('Ext.data.Store', {
+		fields: ['flag', { name: 'state', defaultValue: '=' },
+		    {
+			name: 'desc',
+			calculate: function(rec) {
+			    let vmFlag = data.find(x => x.flag === rec.flag);
+			    return vmFlag ? vmFlag.desc : gettext("auto-detected");
+			},
+		    },
+		],
+		proxy: {
+		    type: 'proxmox',
+		    url: '/api2/json/nodes/localhost/capabilities/qemu/cpu/recognized-flags',
+		},
+		listeners: {
+		    load: function(store, records, success) {
+			if (success) {
+			    afterLoadFn(store);
+			}
+		    },
+		    update: function() {
+			this.commitChanges();
+		    },
+		},
+		autoLoad: true,
+	    });
+	    me.store.onAfter("load", function() {
+		me.checkDirty();
+	    });
+	}
 
 	me.value = me.originalValue = '';
 
-- 
2.30.2






More information about the pve-devel mailing list