[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