From 8c30e7e60d4352c4a98c6ba3f90d602d7500c1df Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:07 +0900 Subject: [PATCH 01/18] kconfig: qconf: reformat the intro message The introduction message displayed by 'Help -> Introduction' does not look nice due to excessive new lines. Reformat the message. Signed-off-by: Masahiro Yamada Tested-by: Randy Dunlap --- scripts/kconfig/qconf.cc | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 8ce624a3b54b..cf33e436190e 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1836,17 +1836,24 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) void ConfigMainWindow::showIntro(void) { - static const QString str = "Welcome to the qconf graphical configuration tool.\n\n" - "For each option, a blank box indicates the feature is disabled, a check\n" - "indicates it is enabled, and a dot indicates that it is to be compiled\n" - "as a module. Clicking on the box will cycle through the three states.\n\n" - "If you do not see an option (e.g., a device driver) that you believe\n" - "should be present, try turning on Show All Options under the Options menu.\n" - "Although there is no cross reference yet to help you figure out what other\n" - "options must be enabled to support the option you are interested in, you can\n" - "still view the help of a grayed-out option.\n\n" - "Toggling Show Debug Info under the Options menu will show the dependencies,\n" - "which you can then match by examining other options.\n\n"; + static const QString str = + "Welcome to the qconf graphical configuration tool.\n" + "\n" + "For each option, a blank box indicates the feature is " + "disabled, a check indicates it is enabled, and a dot " + "indicates that it is to be compiled as a module. Clicking on " + "the box will cycle through the three states.\n" + "\n" + "If you do not see an option (e.g., a device driver) that you " + "believe should be present, try turning on Show All Options " + "under the Options menu. Although there is no cross reference " + "yet to help you figure out what other options must be enabled " + "to support the option you are interested in, you can still " + "view the help of a grayed-out option.\n" + "\n" + "Toggling Show Debug Info under the Options menu will show the " + "dependencies, which you can then match by examining other " + "options.\n"; QMessageBox::information(this, "qconf", str); } From 1fb752416f3fb64bfe44d94b7dd646799676b523 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:08 +0900 Subject: [PATCH 02/18] kconfig: qconf: update the intro message to match to the current code I do not think "Although there is no cross reference yet ..." is valid any longer. The cross reference is supported via hyperlinks enabled by the "show Debug Info" option. Update the message. Signed-off-by: Masahiro Yamada Tested-by: Randy Dunlap --- scripts/kconfig/qconf.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index cf33e436190e..ae47693f80bf 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1846,10 +1846,10 @@ void ConfigMainWindow::showIntro(void) "\n" "If you do not see an option (e.g., a device driver) that you " "believe should be present, try turning on Show All Options " - "under the Options menu. Although there is no cross reference " - "yet to help you figure out what other options must be enabled " - "to support the option you are interested in, you can still " - "view the help of a grayed-out option.\n" + "under the Options menu. Enabling Show Debug Info will help you" + "figure out what other options must be enabled to support the " + "option you are interested in, and hyperlinks will navigate to " + "them.\n" "\n" "Toggling Show Debug Info under the Options menu will show the " "dependencies, which you can then match by examining other " From 6a143041532e7df4bd243f4994d46112bd7137ca Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:09 +0900 Subject: [PATCH 03/18] kconfig: qconf: remove unused ConfigItem::okRename() Commit 76538660fb08 ("Port xconfig to Qt5 - Remove custom ListView classes.") removed the original implementation, where ConfigItem::okRename() overrode Q3ListViewItem::okRename(). Commit 59e564408f88 ("Port xconfig to Qt5 - Put back some of the old implementation.") restored the empty stub, but it seems useless. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 8 -------- scripts/kconfig/qconf.h | 1 - 2 files changed, 9 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index ae47693f80bf..bf6c9187daf5 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -82,14 +82,6 @@ QIcon ConfigItem::choiceNoIcon; QIcon ConfigItem::menuIcon; QIcon ConfigItem::menubackIcon; -/* - * set the new data - * TODO check the value - */ -void ConfigItem::okRename(int col) -{ -} - /* * update the displayed of a menu entry */ diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index f97376a8123f..d41670f322b3 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -131,7 +131,6 @@ class ConfigItem : public QTreeWidgetItem { } ~ConfigItem(void); void init(void); - void okRename(int col); void updateMenu(void); void testUpdateMenu(bool v); ConfigList* listView() const From f9b918fae678eacdeaad821db57a107fba6fe3a1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:10 +0900 Subject: [PATCH 04/18] kconfig: qconf: move ConfigView::updateList(All) to ConfigList class ConfigView::updateList() iterates over all views, and then calls updateList() against for its ConfigList instance. This means there is no point to implement it in the ConfigView class. Move and rename as follows: ConfigView::updateList() -> ConfigList::updateListForAll() ConfigView::updateListAll() -> ConfigList::updateListAllForAll() I used QList to contain all ConfigList instances. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 70 +++++++++++++++++++--------------------- scripts/kconfig/qconf.h | 11 +++---- 2 files changed, 39 insertions(+), 42 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index bf6c9187daf5..7cab996c3617 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -274,7 +274,7 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e) case Qt::Key_Return: case Qt::Key_Enter: sym_set_string_value(item->menu->sym, text().toLatin1()); - parent()->updateList(); + ConfigList::updateListForAll(); break; default: Parent::keyPressEvent(e); @@ -315,9 +315,16 @@ ConfigList::ConfigList(ConfigView* p, const char *name) showColumn(promptColIdx); + allLists.append(this); + reinit(); } +ConfigList::~ConfigList() +{ + allLists.removeOne(this); +} + bool ConfigList::menuSkip(struct menu *menu) { if (optMode == normalOpt && menu_is_visible(menu)) @@ -454,6 +461,28 @@ update: resizeColumnToContents(0); } +void ConfigList::updateListForAll() +{ + QListIterator it(allLists); + + while (it.hasNext()) { + ConfigList *list = it.next(); + + list->updateList(); + } +} + +void ConfigList::updateListAllForAll() +{ + QListIterator it(allLists); + + while (it.hasNext()) { + ConfigList *list = it.next(); + + list->updateList(); + } +} + void ConfigList::setValue(ConfigItem* item, tristate val) { struct symbol* sym; @@ -474,7 +503,7 @@ void ConfigList::setValue(ConfigItem* item, tristate val) return; if (oldval == no && item->menu->list) item->setExpanded(true); - parent()->updateList(); + ConfigList::updateListForAll(); break; } } @@ -508,7 +537,7 @@ void ConfigList::changeValue(ConfigItem* item) item->setExpanded(true); } if (oldexpr != newexpr) - parent()->updateList(); + ConfigList::updateListForAll(); break; case S_INT: case S_HEX: @@ -904,7 +933,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) e->accept(); } -ConfigView*ConfigView::viewList; +QList ConfigList::allLists; QAction *ConfigList::showNormalAction; QAction *ConfigList::showAllAction; QAction *ConfigList::showPromptAction; @@ -921,21 +950,6 @@ ConfigView::ConfigView(QWidget* parent, const char *name) lineEdit = new ConfigLineEdit(this); lineEdit->hide(); verticalLayout->addWidget(lineEdit); - - this->nextView = viewList; - viewList = this; -} - -ConfigView::~ConfigView(void) -{ - ConfigView** vp; - - for (vp = &viewList; *vp; vp = &(*vp)->nextView) { - if (*vp == this) { - *vp = nextView; - break; - } - } } void ConfigView::setShowName(bool b) @@ -976,22 +990,6 @@ void ConfigList::setAllOpen(bool open) } } -void ConfigView::updateList() -{ - ConfigView* v; - - for (v = viewList; v; v = v->nextView) - v->list->updateList(); -} - -void ConfigView::updateListAll(void) -{ - ConfigView* v; - - for (v = viewList; v; v = v->nextView) - v->list->updateListAll(); -} - ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) : Parent(parent), sym(0), _menu(0) { @@ -1605,7 +1603,7 @@ void ConfigMainWindow::loadConfig(void) free(configname); configname = xstrdup(name); - ConfigView::updateListAll(); + ConfigList::updateListAllForAll(); } bool ConfigMainWindow::saveConfig(void) diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index d41670f322b3..818e00617ae3 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -44,6 +44,7 @@ class ConfigList : public QTreeWidget { typedef class QTreeWidget Parent; public: ConfigList(ConfigView* p, const char *name = 0); + ~ConfigList(); void reinit(void); ConfigItem* findConfigItem(struct menu *); ConfigView* parent(void) const @@ -108,6 +109,10 @@ public slots: QPalette inactivedColorGroup; QMenu* headerPopup; + static QList allLists; + static void updateListForAll(); + static void updateListAllForAll(); + static QAction *showNormalAction, *showAllAction, *showPromptAction; }; @@ -188,9 +193,6 @@ class ConfigView : public QWidget { typedef class QWidget Parent; public: ConfigView(QWidget* parent, const char *name = 0); - ~ConfigView(void); - static void updateList(); - static void updateListAll(void); bool showName(void) const { return list->showName; } bool showRange(void) const { return list->showRange; } @@ -206,9 +208,6 @@ public slots: public: ConfigList* list; ConfigLineEdit* lineEdit; - - static ConfigView* viewList; - ConfigView* nextView; }; class ConfigInfoView : public QTextBrowser { From 669a1ee46a0e2ccad769ceca70b08ee57772be94 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:11 +0900 Subject: [PATCH 05/18] kconfig: qconf: show data column all the time The next commit will allow users to edit "int", "hex", "string" menus in-place from the data column. The data column should be always displayed. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 29 +---------------------------- scripts/kconfig/qconf.h | 5 +---- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 7cab996c3617..3ba064af905c 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -288,7 +288,7 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e) ConfigList::ConfigList(ConfigView* p, const char *name) : Parent(p), updateAll(false), - showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt), + showName(false), showRange(false), mode(singleMode), optMode(normalOpt), rootEntry(0), headerPopup(0) { setObjectName(name); @@ -307,7 +307,6 @@ ConfigList::ConfigList(ConfigView* p, const char *name) configSettings->beginGroup(name); showName = configSettings->value("/showName", false).toBool(); showRange = configSettings->value("/showRange", false).toBool(); - showData = configSettings->value("/showData", false).toBool(); optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt(); configSettings->endGroup(); connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); @@ -338,7 +337,6 @@ bool ConfigList::menuSkip(struct menu *menu) void ConfigList::reinit(void) { - hideColumn(dataColIdx); hideColumn(yesColIdx); hideColumn(modColIdx); hideColumn(noColIdx); @@ -351,8 +349,6 @@ void ConfigList::reinit(void) showColumn(modColIdx); showColumn(yesColIdx); } - if (showData) - showColumn(dataColIdx); updateListAll(); } @@ -375,7 +371,6 @@ void ConfigList::saveSettings(void) configSettings->beginGroup(objectName()); configSettings->setValue("/showName", showName); configSettings->setValue("/showRange", showRange); - configSettings->setValue("/showData", showData); configSettings->setValue("/optionMode", (int)optMode); configSettings->endGroup(); } @@ -918,15 +913,6 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) action, SLOT(setChecked(bool))); action->setChecked(showRange); headerPopup->addAction(action); - - action = new QAction("Show Data", this); - action->setCheckable(true); - connect(action, SIGNAL(toggled(bool)), - parent(), SLOT(setShowData(bool))); - connect(parent(), SIGNAL(showDataChanged(bool)), - action, SLOT(setChecked(bool))); - action->setChecked(showData); - headerPopup->addAction(action); } headerPopup->exec(e->globalPos()); @@ -970,15 +956,6 @@ void ConfigView::setShowRange(bool b) } } -void ConfigView::setShowData(bool b) -{ - if (list->showData != b) { - list->showData = b; - list->reinit(); - emit showDataChanged(b); - } -} - void ConfigList::setAllOpen(bool open) { QTreeWidgetItemIterator it(this); @@ -1475,9 +1452,6 @@ ConfigMainWindow::ConfigMainWindow(void) QAction *showRangeAction = new QAction("Show Range", this); showRangeAction->setCheckable(true); connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); - QAction *showDataAction = new QAction("Show Data", this); - showDataAction->setCheckable(true); - connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); QActionGroup *optGroup = new QActionGroup(this); optGroup->setExclusive(true); @@ -1530,7 +1504,6 @@ ConfigMainWindow::ConfigMainWindow(void) menu = menuBar()->addMenu("&Option"); menu->addAction(showNameAction); menu->addAction(showRangeAction); - menu->addAction(showDataAction); menu->addSeparator(); menu->addActions(optGroup->actions()); menu->addSeparator(); diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index 818e00617ae3..d01a6c620dbb 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -101,7 +101,7 @@ public slots: bool updateAll; - bool showName, showRange, showData; + bool showName, showRange; enum listMode mode; enum optionMode optMode; struct menu *rootEntry; @@ -196,15 +196,12 @@ class ConfigView : public QWidget { bool showName(void) const { return list->showName; } bool showRange(void) const { return list->showRange; } - bool showData(void) const { return list->showData; } public slots: void setShowName(bool); void setShowRange(bool); - void setShowData(bool); signals: void showNameChanged(bool); void showRangeChanged(bool); - void showDataChanged(bool); public: ConfigList* list; ConfigLineEdit* lineEdit; From 37162a68bf517b6f870d63bbbcc65a81f99bd968 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:12 +0900 Subject: [PATCH 06/18] kconfig: qconf: allow to edit "int", "hex", "string" menus in-place Previously, when you double-clicked the "int", "hex", or "string" menus, a line-edit gadget showed up to allow you to input the value, which looked clumsy. Also, it was buggy; the editor opened even if the config option was not editable. For example, just try to double-click CC_VERSION_TEXT, which has no prompt. This commit sub-classes QStyleItemDelegate to allow users to edit "int", "hex", "string" menus in-place. Just double-click (or press the F2 key) in the data column. Then, an editor widget is placed on top of the item view. The two methods are overridden: createEditor - process only when the data column is being accessed and the menu is visible. Otherwise, return nullptr to disallow editing. setModelData - take the new data from the editor, and set it to the addressed symbol. If it was successful, update all the list windows. Otherwise, (the reason for the failure is possibly the input data was out of range), set the old value back to the editor. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 93 ++++++++++++++++++++++++++++++++-------- scripts/kconfig/qconf.h | 15 +++++++ 2 files changed, 91 insertions(+), 17 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 3ba064af905c..af8d5cc1b24b 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -180,15 +180,7 @@ void ConfigItem::updateMenu(void) case S_INT: case S_HEX: case S_STRING: - const char* data; - - data = sym_get_string_value(sym); - - setText(dataColIdx, data); - if (type == S_STRING) - prompt = QString("%1: %2").arg(prompt).arg(data); - else - prompt = QString("(%2) %1").arg(prompt).arg(data); + setText(dataColIdx, sym_get_string_value(sym)); break; } if (!sym_has_value(sym) && visible) @@ -229,6 +221,17 @@ void ConfigItem::init(void) if (list->mode != fullMode) setExpanded(true); sym_calc_value(menu->sym); + + if (menu->sym) { + enum symbol_type type = menu->sym->type; + + // Allow to edit "int", "hex", and "string" in-place in + // the data column. Unfortunately, you cannot specify + // the flags per column. Set ItemIsEditable for all + // columns here, and check the column in createEditor(). + if (type == S_INT || type == S_HEX || type == S_STRING) + setFlags(flags() | Qt::ItemIsEditable); + } } updateMenu(); } @@ -249,6 +252,61 @@ ConfigItem::~ConfigItem(void) } } +QWidget *ConfigItemDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + ConfigItem *item; + + // Only the data column is editable + if (index.column() != dataColIdx) + return nullptr; + + // You cannot edit invisible menus + item = static_cast(index.internalPointer()); + if (!item || !item->menu || !menu_is_visible(item->menu)) + return nullptr; + + return QStyledItemDelegate::createEditor(parent, option, index); +} + +void ConfigItemDelegate::setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const +{ + QLineEdit *lineEdit; + ConfigItem *item; + struct symbol *sym; + bool success; + + lineEdit = qobject_cast(editor); + // If this is not a QLineEdit, use the parent's default. + // (does this happen?) + if (!lineEdit) + goto parent; + + item = static_cast(index.internalPointer()); + if (!item || !item->menu) + goto parent; + + sym = item->menu->sym; + if (!sym) + goto parent; + + success = sym_set_string_value(sym, lineEdit->text().toUtf8().data()); + if (success) { + ConfigList::updateListForAll(); + } else { + QMessageBox::information(editor, "qconf", + "Cannot set the data (maybe due to out of range).\n" + "Setting the old value."); + lineEdit->setText(sym_get_string_value(sym)); + } + +parent: + QStyledItemDelegate::setModelData(editor, model, index); +} + ConfigLineEdit::ConfigLineEdit(ConfigView* parent) : Parent(parent) { @@ -314,6 +372,8 @@ ConfigList::ConfigList(ConfigView* p, const char *name) showColumn(promptColIdx); + setItemDelegate(new ConfigItemDelegate(this)); + allLists.append(this); reinit(); @@ -534,10 +594,7 @@ void ConfigList::changeValue(ConfigItem* item) if (oldexpr != newexpr) ConfigList::updateListForAll(); break; - case S_INT: - case S_HEX: - case S_STRING: - parent()->lineEdit->show(item); + default: break; } } @@ -1802,10 +1859,12 @@ void ConfigMainWindow::showIntro(void) static const QString str = "Welcome to the qconf graphical configuration tool.\n" "\n" - "For each option, a blank box indicates the feature is " - "disabled, a check indicates it is enabled, and a dot " - "indicates that it is to be compiled as a module. Clicking on " - "the box will cycle through the three states.\n" + "For bool and tristate options, a blank box indicates the " + "feature is disabled, a check indicates it is enabled, and a " + "dot indicates that it is to be compiled as a module. Clicking " + "on the box will cycle through the three states. For int, hex, " + "and string options, double-clicking or pressing F2 on the " + "Value cell will allow you to edit the value.\n" "\n" "If you do not see an option (e.g., a device driver) that you " "believe should be present, try turning on Show All Options " diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index d01a6c620dbb..b02acf2464ec 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -172,6 +173,20 @@ class ConfigItem : public QTreeWidgetItem { static QIcon menuIcon, menubackIcon; }; +class ConfigItemDelegate : public QStyledItemDelegate +{ +private: + struct menu *menu; +public: + ConfigItemDelegate(QObject *parent = nullptr) + : QStyledItemDelegate(parent) {} + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const override; +}; + class ConfigLineEdit : public QLineEdit { Q_OBJECT typedef class QLineEdit Parent; From f3eea294e93facc78ffcf3881f88ea02732283a9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:13 +0900 Subject: [PATCH 07/18] kconfig: qconf: remove ConfigLineEdit class Now that "int", "hex", "string" menus are edited in-place, this class is no longer needed. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 39 --------------------------------------- scripts/kconfig/qconf.h | 18 ------------------ 2 files changed, 57 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index af8d5cc1b24b..461681aa5b19 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -307,42 +307,6 @@ parent: QStyledItemDelegate::setModelData(editor, model, index); } -ConfigLineEdit::ConfigLineEdit(ConfigView* parent) - : Parent(parent) -{ - connect(this, SIGNAL(editingFinished()), SLOT(hide())); -} - -void ConfigLineEdit::show(ConfigItem* i) -{ - item = i; - if (sym_get_string_value(item->menu->sym)) - setText(sym_get_string_value(item->menu->sym)); - else - setText(QString()); - Parent::show(); - setFocus(); -} - -void ConfigLineEdit::keyPressEvent(QKeyEvent* e) -{ - switch (e->key()) { - case Qt::Key_Escape: - break; - case Qt::Key_Return: - case Qt::Key_Enter: - sym_set_string_value(item->menu->sym, text().toLatin1()); - ConfigList::updateListForAll(); - break; - default: - Parent::keyPressEvent(e); - return; - } - e->accept(); - parent()->list->setFocus(); - hide(); -} - ConfigList::ConfigList(ConfigView* p, const char *name) : Parent(p), updateAll(false), @@ -990,9 +954,6 @@ ConfigView::ConfigView(QWidget* parent, const char *name) list = new ConfigList(this); verticalLayout->addWidget(list); - lineEdit = new ConfigLineEdit(this); - lineEdit->hide(); - verticalLayout->addWidget(lineEdit); } void ConfigView::setShowName(bool b) diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index b02acf2464ec..a3ee91565d49 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -20,7 +20,6 @@ class ConfigView; class ConfigList; class ConfigItem; -class ConfigLineEdit; class ConfigMainWindow; class ConfigSettings : public QSettings { @@ -187,22 +186,6 @@ class ConfigItemDelegate : public QStyledItemDelegate const QModelIndex &index) const override; }; -class ConfigLineEdit : public QLineEdit { - Q_OBJECT - typedef class QLineEdit Parent; -public: - ConfigLineEdit(ConfigView* parent); - ConfigView* parent(void) const - { - return (ConfigView*)Parent::parent(); - } - void show(ConfigItem *i); - void keyPressEvent(QKeyEvent *e); - -public: - ConfigItem *item; -}; - class ConfigView : public QWidget { Q_OBJECT typedef class QWidget Parent; @@ -219,7 +202,6 @@ public slots: void showRangeChanged(bool); public: ConfigList* list; - ConfigLineEdit* lineEdit; }; class ConfigInfoView : public QTextBrowser { From 7930dd91a01fe9c0ff7664c7f0bdf38fba9047bc Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:14 +0900 Subject: [PATCH 08/18] kconfig: qconf: move setShowName/Range() to ConfigList from ConfigView ConfigView::setShowName/Range() only get access to the 'list' member. Move them to the more relevant ConfigList class. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 53 +++++++++++++++++++++------------------- scripts/kconfig/qconf.h | 12 +++------ 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 461681aa5b19..5f3e5e145a99 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -920,8 +920,8 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) action = new QAction("Show Name", this); action->setCheckable(true); connect(action, SIGNAL(toggled(bool)), - parent(), SLOT(setShowName(bool))); - connect(parent(), SIGNAL(showNameChanged(bool)), + SLOT(setShowName(bool))); + connect(this, SIGNAL(showNameChanged(bool)), action, SLOT(setChecked(bool))); action->setChecked(showName); headerPopup->addAction(action); @@ -929,8 +929,8 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) action = new QAction("Show Range", this); action->setCheckable(true); connect(action, SIGNAL(toggled(bool)), - parent(), SLOT(setShowRange(bool))); - connect(parent(), SIGNAL(showRangeChanged(bool)), + SLOT(setShowRange(bool))); + connect(this, SIGNAL(showRangeChanged(bool)), action, SLOT(setChecked(bool))); action->setChecked(showRange); headerPopup->addAction(action); @@ -940,6 +940,26 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) e->accept(); } +void ConfigList::setShowName(bool on) +{ + if (showName == on) + return; + + showName = on; + reinit(); + emit showNameChanged(on); +} + +void ConfigList::setShowRange(bool on) +{ + if (showRange == on) + return; + + showRange = on; + reinit(); + emit showRangeChanged(on); +} + QList ConfigList::allLists; QAction *ConfigList::showNormalAction; QAction *ConfigList::showAllAction; @@ -956,24 +976,6 @@ ConfigView::ConfigView(QWidget* parent, const char *name) verticalLayout->addWidget(list); } -void ConfigView::setShowName(bool b) -{ - if (list->showName != b) { - list->showName = b; - list->reinit(); - emit showNameChanged(b); - } -} - -void ConfigView::setShowRange(bool b) -{ - if (list->showRange != b) { - list->showRange = b; - list->reinit(); - emit showRangeChanged(b); - } -} - void ConfigList::setAllOpen(bool open) { QTreeWidgetItemIterator it(this); @@ -1465,11 +1467,12 @@ ConfigMainWindow::ConfigMainWindow(void) QAction *showNameAction = new QAction("Show Name", this); showNameAction->setCheckable(true); - connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); - showNameAction->setChecked(configView->showName()); + connect(showNameAction, SIGNAL(toggled(bool)), configList, SLOT(setShowName(bool))); + showNameAction->setChecked(configList->showName); + QAction *showRangeAction = new QAction("Show Range", this); showRangeAction->setCheckable(true); - connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); + connect(showRangeAction, SIGNAL(toggled(bool)), configList, SLOT(setShowRange(bool))); QActionGroup *optGroup = new QActionGroup(this); optGroup->setExclusive(true); diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index a3ee91565d49..843725584bfa 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -76,6 +76,8 @@ public slots: void updateSelection(void); void saveSettings(void); void setOptionMode(QAction *action); + void setShowName(bool on); + void setShowRange(bool on); signals: void menuChanged(struct menu *menu); @@ -83,6 +85,8 @@ public slots: void itemSelected(struct menu *menu); void parentSelected(void); void gotFocus(struct menu *); + void showNameChanged(bool on); + void showRangeChanged(bool on); public: void updateListAll(void) @@ -192,14 +196,6 @@ class ConfigView : public QWidget { public: ConfigView(QWidget* parent, const char *name = 0); - bool showName(void) const { return list->showName; } - bool showRange(void) const { return list->showRange; } -public slots: - void setShowName(bool); - void setShowRange(bool); -signals: - void showNameChanged(bool); - void showRangeChanged(bool); public: ConfigList* list; }; From 62ed165651cc71cb1b6d39ced74e47c2b26a55a5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:15 +0900 Subject: [PATCH 09/18] kconfig: qconf: remove ConfigView class Now that ConfigView only contains ConfigList, we can remove ConfigView and just use ConfigList. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 43 ++++++++++++++-------------------------- scripts/kconfig/qconf.h | 21 ++------------------ 2 files changed, 17 insertions(+), 47 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 5f3e5e145a99..4ece85ae7dfa 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -307,8 +307,8 @@ parent: QStyledItemDelegate::setModelData(editor, model, index); } -ConfigList::ConfigList(ConfigView* p, const char *name) - : Parent(p), +ConfigList::ConfigList(QWidget *parent, const char *name) + : QTreeWidget(parent), updateAll(false), showName(false), showRange(false), mode(singleMode), optMode(normalOpt), rootEntry(0), headerPopup(0) @@ -965,17 +965,6 @@ QAction *ConfigList::showNormalAction; QAction *ConfigList::showAllAction; QAction *ConfigList::showPromptAction; -ConfigView::ConfigView(QWidget* parent, const char *name) - : Parent(parent) -{ - setObjectName(name); - QVBoxLayout *verticalLayout = new QVBoxLayout(this); - verticalLayout->setContentsMargins(0, 0, 0, 0); - - list = new ConfigList(this); - verticalLayout->addWidget(list); -} - void ConfigList::setAllOpen(bool open) { QTreeWidgetItemIterator it(this); @@ -1302,12 +1291,12 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent) split = new QSplitter(this); split->setOrientation(Qt::Vertical); - list = new ConfigView(split, "search"); - list->list->mode = listMode; + list = new ConfigList(split, "search"); + list->mode = listMode; info = new ConfigInfoView(split, "search"); - connect(list->list, SIGNAL(menuChanged(struct menu *)), + connect(list, SIGNAL(menuChanged(struct menu *)), info, SLOT(setInfo(struct menu *))); - connect(list->list, SIGNAL(menuChanged(struct menu *)), + connect(list, SIGNAL(menuChanged(struct menu *)), parent, SLOT(setMenuLink(struct menu *))); layout1->addWidget(split); @@ -1351,7 +1340,7 @@ void ConfigSearchWindow::search(void) ConfigItem *lastItem = NULL; free(result); - list->list->clear(); + list->clear(); info->clear(); result = sym_re_search(editField->text().toLatin1()); @@ -1359,7 +1348,7 @@ void ConfigSearchWindow::search(void) return; for (p = result; *p; p++) { for_all_prompts((*p), prop) - lastItem = new ConfigItem(list->list, lastItem, prop->menu, + lastItem = new ConfigItem(list, lastItem, prop->menu, menu_is_visible(prop->menu)); } } @@ -1407,23 +1396,21 @@ ConfigMainWindow::ConfigMainWindow(void) split1->setOrientation(Qt::Horizontal); split1->setChildrenCollapsible(false); - menuView = new ConfigView(widget, "menu"); - menuList = menuView->list; + menuList = new ConfigList(widget, "menu"); split2 = new QSplitter(widget); split2->setChildrenCollapsible(false); split2->setOrientation(Qt::Vertical); // create config tree - configView = new ConfigView(widget, "config"); - configList = configView->list; + configList = new ConfigList(widget, "config"); helpText = new ConfigInfoView(widget, "help"); layout->addWidget(split2); split2->addWidget(split1); - split1->addWidget(configView); - split1->addWidget(menuView); + split1->addWidget(configList); + split1->addWidget(menuList); split2->addWidget(helpText); setTabOrder(configList, helpText); @@ -1732,7 +1719,7 @@ void ConfigMainWindow::showSingleView(void) backAction->setEnabled(true); - menuView->hide(); + menuList->hide(); menuList->setRootMenu(0); configList->mode = singleMode; if (configList->rootEntry == &rootmenu) @@ -1763,7 +1750,7 @@ void ConfigMainWindow::showSplitView(void) menuList->mode = symbolMode; menuList->setRootMenu(&rootmenu); menuList->setAllOpen(true); - menuView->show(); + menuList->show(); menuList->setFocus(); } @@ -1778,7 +1765,7 @@ void ConfigMainWindow::showFullView(void) backAction->setEnabled(false); - menuView->hide(); + menuList->hide(); menuList->setRootMenu(0); configList->mode = fullMode; if (configList->rootEntry == &rootmenu) diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index 843725584bfa..1289fdaa7d82 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -17,7 +17,6 @@ #include "expr.h" -class ConfigView; class ConfigList; class ConfigItem; class ConfigMainWindow; @@ -43,14 +42,10 @@ class ConfigList : public QTreeWidget { Q_OBJECT typedef class QTreeWidget Parent; public: - ConfigList(ConfigView* p, const char *name = 0); + ConfigList(QWidget *parent, const char *name = 0); ~ConfigList(); void reinit(void); ConfigItem* findConfigItem(struct menu *); - ConfigView* parent(void) const - { - return (ConfigView*)Parent::parent(); - } void setSelected(QTreeWidgetItem *item, bool enable) { for (int i = 0; i < selectedItems().size(); i++) selectedItems().at(i)->setSelected(false); @@ -190,16 +185,6 @@ class ConfigItemDelegate : public QStyledItemDelegate const QModelIndex &index) const override; }; -class ConfigView : public QWidget { - Q_OBJECT - typedef class QWidget Parent; -public: - ConfigView(QWidget* parent, const char *name = 0); - -public: - ConfigList* list; -}; - class ConfigInfoView : public QTextBrowser { Q_OBJECT typedef class QTextBrowser Parent; @@ -245,7 +230,7 @@ public slots: QLineEdit* editField; QPushButton* searchButton; QSplitter* split; - ConfigView* list; + ConfigList *list; ConfigInfoView* info; struct symbol **result; @@ -280,9 +265,7 @@ public slots: void closeEvent(QCloseEvent *e); ConfigSearchWindow *searchWindow; - ConfigView *menuView; ConfigList *menuList; - ConfigView *configView; ConfigList *configList; ConfigInfoView *helpText; QAction *backAction; From a0fce283386d76f3e77f4f45b7ec6f0084510baa Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:16 +0900 Subject: [PATCH 10/18] kconfig: qconf: remove Y, M, N columns There are so many ways to toggle bool / tristate options. I do not know how useful these columns are. Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 59 ++-------------------------------------- scripts/kconfig/qconf.h | 6 ++-- 2 files changed, 4 insertions(+), 61 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 4ece85ae7dfa..21871b7f5f8a 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -139,9 +139,6 @@ void ConfigItem::updateMenu(void) if (!sym_is_changeable(sym) && list->optMode == normalOpt) { setIcon(promptColIdx, QIcon()); - setText(noColIdx, QString()); - setText(modColIdx, QString()); - setText(yesColIdx, QString()); break; } expr = sym_get_tristate_value(sym); @@ -151,12 +148,10 @@ void ConfigItem::updateMenu(void) setIcon(promptColIdx, choiceYesIcon); else setIcon(promptColIdx, symbolYesIcon); - setText(yesColIdx, "Y"); ch = 'Y'; break; case mod: setIcon(promptColIdx, symbolModIcon); - setText(modColIdx, "M"); ch = 'M'; break; default: @@ -164,16 +159,9 @@ void ConfigItem::updateMenu(void) setIcon(promptColIdx, choiceNoIcon); else setIcon(promptColIdx, symbolNoIcon); - setText(noColIdx, "N"); ch = 'N'; break; } - if (expr != no) - setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0); - if (expr != mod) - setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0); - if (expr != yes) - setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0); setText(dataColIdx, QChar(ch)); break; @@ -310,7 +298,7 @@ parent: ConfigList::ConfigList(QWidget *parent, const char *name) : QTreeWidget(parent), updateAll(false), - showName(false), showRange(false), mode(singleMode), optMode(normalOpt), + showName(false), mode(singleMode), optMode(normalOpt), rootEntry(0), headerPopup(0) { setObjectName(name); @@ -320,7 +308,7 @@ ConfigList::ConfigList(QWidget *parent, const char *name) setVerticalScrollMode(ScrollPerPixel); setHorizontalScrollMode(ScrollPerPixel); - setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value"); + setHeaderLabels(QStringList() << "Option" << "Name" << "Value"); connect(this, SIGNAL(itemSelectionChanged(void)), SLOT(updateSelection(void))); @@ -328,7 +316,6 @@ ConfigList::ConfigList(QWidget *parent, const char *name) if (name) { configSettings->beginGroup(name); showName = configSettings->value("/showName", false).toBool(); - showRange = configSettings->value("/showRange", false).toBool(); optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt(); configSettings->endGroup(); connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); @@ -361,18 +348,10 @@ bool ConfigList::menuSkip(struct menu *menu) void ConfigList::reinit(void) { - hideColumn(yesColIdx); - hideColumn(modColIdx); - hideColumn(noColIdx); hideColumn(nameColIdx); if (showName) showColumn(nameColIdx); - if (showRange) { - showColumn(noColIdx); - showColumn(modColIdx); - showColumn(yesColIdx); - } updateListAll(); } @@ -394,7 +373,6 @@ void ConfigList::saveSettings(void) if (!objectName().isEmpty()) { configSettings->beginGroup(objectName()); configSettings->setValue("/showName", showName); - configSettings->setValue("/showRange", showRange); configSettings->setValue("/optionMode", (int)optMode); configSettings->endGroup(); } @@ -841,15 +819,6 @@ void ConfigList::mouseReleaseEvent(QMouseEvent* e) } } break; - case noColIdx: - setValue(item, no); - break; - case modColIdx: - setValue(item, mod); - break; - case yesColIdx: - setValue(item, yes); - break; case dataColIdx: changeValue(item); break; @@ -925,15 +894,6 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) action, SLOT(setChecked(bool))); action->setChecked(showName); headerPopup->addAction(action); - - action = new QAction("Show Range", this); - action->setCheckable(true); - connect(action, SIGNAL(toggled(bool)), - SLOT(setShowRange(bool))); - connect(this, SIGNAL(showRangeChanged(bool)), - action, SLOT(setChecked(bool))); - action->setChecked(showRange); - headerPopup->addAction(action); } headerPopup->exec(e->globalPos()); @@ -950,16 +910,6 @@ void ConfigList::setShowName(bool on) emit showNameChanged(on); } -void ConfigList::setShowRange(bool on) -{ - if (showRange == on) - return; - - showRange = on; - reinit(); - emit showRangeChanged(on); -} - QList ConfigList::allLists; QAction *ConfigList::showNormalAction; QAction *ConfigList::showAllAction; @@ -1457,10 +1407,6 @@ ConfigMainWindow::ConfigMainWindow(void) connect(showNameAction, SIGNAL(toggled(bool)), configList, SLOT(setShowName(bool))); showNameAction->setChecked(configList->showName); - QAction *showRangeAction = new QAction("Show Range", this); - showRangeAction->setCheckable(true); - connect(showRangeAction, SIGNAL(toggled(bool)), configList, SLOT(setShowRange(bool))); - QActionGroup *optGroup = new QActionGroup(this); optGroup->setExclusive(true); connect(optGroup, SIGNAL(triggered(QAction*)), configList, @@ -1511,7 +1457,6 @@ ConfigMainWindow::ConfigMainWindow(void) // create options menu menu = menuBar()->addMenu("&Option"); menu->addAction(showNameAction); - menu->addAction(showRangeAction); menu->addSeparator(); menu->addActions(optGroup->actions()); menu->addSeparator(); diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index 1289fdaa7d82..78b0a1dfcd53 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -29,7 +29,7 @@ class ConfigSettings : public QSettings { }; enum colIdx { - promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx + promptColIdx, nameColIdx, dataColIdx }; enum listMode { singleMode, menuMode, symbolMode, fullMode, listMode @@ -72,7 +72,6 @@ public slots: void saveSettings(void); void setOptionMode(QAction *action); void setShowName(bool on); - void setShowRange(bool on); signals: void menuChanged(struct menu *menu); @@ -81,7 +80,6 @@ public slots: void parentSelected(void); void gotFocus(struct menu *); void showNameChanged(bool on); - void showRangeChanged(bool on); public: void updateListAll(void) @@ -100,7 +98,7 @@ public slots: bool updateAll; - bool showName, showRange; + bool showName; enum listMode mode; enum optionMode optMode; struct menu *rootEntry; From f9a825a7f65a1c94858667934c4ed59bc548dd1f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 29 Aug 2020 17:14:17 +0900 Subject: [PATCH 11/18] kconfig: qconf: create QApplication after option checks 'scripts/kconfig/qconf -h' just calls usage() and exits, with QApplication unused. There is no need to construct QApplication so early. Do it after the parse stage. Signed-off-by: Masahiro Yamada Tested-by: Randy Dunlap --- scripts/kconfig/qconf.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 21871b7f5f8a..f7eb093614f2 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1851,7 +1851,6 @@ int main(int ac, char** av) const char *name; progname = av[0]; - configApp = new QApplication(ac, av); if (ac > 1 && av[1][0] == '-') { switch (av[1][1]) { case 's': @@ -1872,6 +1871,8 @@ int main(int ac, char** av) conf_read(NULL); //zconfdump(stdout); + configApp = new QApplication(ac, av); + configSettings = new ConfigSettings(); configSettings->beginGroup("/kconfig/qconf"); v = new ConfigMainWindow(); From 4b7a6ce71e033666d6f5a577deb7f1f5126ed889 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 13 Oct 2020 22:24:30 -0700 Subject: [PATCH 12/18] arm64: reject prctl(PR_PAC_RESET_KEYS) on compat tasks It doesn't make sense to issue prctl(PR_PAC_RESET_KEYS) on a compat task because the 32-bit instruction set does not offer PAuth instructions. For consistency with other 64-bit only prctls such as {SET,GET}_TAGGED_ADDR_CTRL, reject the prctl on compat tasks. Although this is a userspace-visible change, maybe it isn't too late to make this change given that the hardware isn't available yet and it's very unlikely that anyone has 32-bit software that actually depends on this succeeding. Signed-off-by: Peter Collingbourne Link: https://linux-review.googlesource.com/id/Ie885a1ff84ab498cc9f62d6451e9f2cfd4b1d06a Link: https://lore.kernel.org/r/20201014052430.11630-1-pcc@google.com [will: Do the same for the SVE prctl()s] Signed-off-by: Will Deacon --- arch/arm64/kernel/fpsimd.c | 4 ++-- arch/arm64/kernel/pointer_auth.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index a6d688c10745..062b21f30f94 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -678,7 +678,7 @@ int sve_set_current_vl(unsigned long arg) vl = arg & PR_SVE_VL_LEN_MASK; flags = arg & ~vl; - if (!system_supports_sve()) + if (!system_supports_sve() || is_compat_task()) return -EINVAL; ret = sve_set_vector_length(current, vl, flags); @@ -691,7 +691,7 @@ int sve_set_current_vl(unsigned long arg) /* PR_SVE_GET_VL */ int sve_get_current_vl(void) { - if (!system_supports_sve()) + if (!system_supports_sve() || is_compat_task()) return -EINVAL; return sve_prctl_status(0); diff --git a/arch/arm64/kernel/pointer_auth.c b/arch/arm64/kernel/pointer_auth.c index 1e77736a4f66..adb955fd9bdd 100644 --- a/arch/arm64/kernel/pointer_auth.c +++ b/arch/arm64/kernel/pointer_auth.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include #include @@ -17,6 +18,9 @@ int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg) if (!system_supports_address_auth() && !system_supports_generic_auth()) return -EINVAL; + if (is_compat_thread(task_thread_info(tsk))) + return -EINVAL; + if (!arg) { ptrauth_keys_init_user(keys); return 0; From 7bc1a0f9e1765830e945669c99c59c35cf9bca82 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 8 Oct 2020 17:35:59 +0200 Subject: [PATCH 13/18] arm64: mm: use single quantity to represent the PA to VA translation On arm64, the global variable memstart_addr represents the physical address of PAGE_OFFSET, and so physical to virtual translations or vice versa used to come down to simple additions or subtractions involving the values of PAGE_OFFSET and memstart_addr. When support for 52-bit virtual addressing was introduced, we had to deal with PAGE_OFFSET potentially being outside of the region that can be covered by the virtual range (as the 52-bit VA capable build needs to be able to run on systems that are only 48-bit VA capable), and for this reason, another translation was introduced, and recorded in the global variable physvirt_offset. However, if we go back to the original definition of memstart_addr, i.e., the physical address of PAGE_OFFSET, it turns out that there is no need for two separate translations: instead, we can simply subtract the size of the unaddressable VA space from memstart_addr to make the available physical memory appear in the 48-bit addressable VA region. This simplifies things, but also fixes a bug on KASLR builds, which may update memstart_addr later on in arm64_memblock_init(), but fails to update vmemmap and physvirt_offset accordingly. Fixes: 5383cc6efed1 ("arm64: mm: Introduce vabits_actual") Signed-off-by: Ard Biesheuvel Reviewed-by: Steve Capper Link: https://lore.kernel.org/r/20201008153602.9467-2-ardb@kernel.org Signed-off-by: Will Deacon --- arch/arm64/include/asm/memory.h | 5 ++--- arch/arm64/include/asm/pgtable.h | 4 ++-- arch/arm64/mm/init.c | 30 ++++++++++-------------------- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 43640d797455..cd61239bae8c 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -169,7 +169,6 @@ extern u64 vabits_actual; #define PAGE_END (_PAGE_END(vabits_actual)) -extern s64 physvirt_offset; extern s64 memstart_addr; /* PHYS_OFFSET - the physical address of the start of memory. */ #define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; }) @@ -245,7 +244,7 @@ static inline const void *__tag_set(const void *addr, u8 tag) */ #define __is_lm_address(addr) (!(((u64)addr) & BIT(vabits_actual - 1))) -#define __lm_to_phys(addr) (((addr) + physvirt_offset)) +#define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET) #define __kimg_to_phys(addr) ((addr) - kimage_voffset) #define __virt_to_phys_nodebug(x) ({ \ @@ -263,7 +262,7 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x); #define __phys_addr_symbol(x) __pa_symbol_nodebug(x) #endif /* CONFIG_DEBUG_VIRTUAL */ -#define __phys_to_virt(x) ((unsigned long)((x) - physvirt_offset)) +#define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET) #define __phys_to_kimg(x) ((unsigned long)((x) + kimage_voffset)) /* diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index a11bf52e0c38..4ff12a7adcfd 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -24,6 +24,8 @@ #define VMALLOC_START (MODULES_END) #define VMALLOC_END (- PUD_SIZE - VMEMMAP_SIZE - SZ_64K) +#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)) + #define FIRST_USER_ADDRESS 0UL #ifndef __ASSEMBLY__ @@ -34,8 +36,6 @@ #include #include -extern struct page *vmemmap; - #ifdef CONFIG_TRANSPARENT_HUGEPAGE #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 481d22c32a2e..324f0e0894f6 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -54,12 +54,6 @@ s64 memstart_addr __ro_after_init = -1; EXPORT_SYMBOL(memstart_addr); -s64 physvirt_offset __ro_after_init; -EXPORT_SYMBOL(physvirt_offset); - -struct page *vmemmap __ro_after_init; -EXPORT_SYMBOL(vmemmap); - /* * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of * memory as some devices, namely the Raspberry Pi 4, have peripherals with @@ -290,20 +284,6 @@ void __init arm64_memblock_init(void) memstart_addr = round_down(memblock_start_of_DRAM(), ARM64_MEMSTART_ALIGN); - physvirt_offset = PHYS_OFFSET - PAGE_OFFSET; - - vmemmap = ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)); - - /* - * If we are running with a 52-bit kernel VA config on a system that - * does not support it, we have to offset our vmemmap and physvirt_offset - * s.t. we avoid the 52-bit portion of the direct linear map - */ - if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) { - vmemmap += (_PAGE_OFFSET(48) - _PAGE_OFFSET(52)) >> PAGE_SHIFT; - physvirt_offset = PHYS_OFFSET - _PAGE_OFFSET(48); - } - /* * Remove the memory that we will not be able to cover with the * linear mapping. Take care not to clip the kernel which may be @@ -318,6 +298,16 @@ void __init arm64_memblock_init(void) memblock_remove(0, memstart_addr); } + /* + * If we are running with a 52-bit kernel VA config on a system that + * does not support it, we have to place the available physical + * memory in the 48-bit addressable part of the linear region, i.e., + * we have to move it upward. Since memstart_addr represents the + * physical address of PAGE_OFFSET, we have to *subtract* from it. + */ + if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) + memstart_addr -= _PAGE_OFFSET(48) - _PAGE_OFFSET(52); + /* * Apply the memory limit if it was set. Since the kernel may be loaded * high up in memory, add back the kernel region that must be accessible From 45544eee96065cf183fbb937fe1f45a172b06f4e Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Wed, 14 Oct 2020 00:53:07 +0000 Subject: [PATCH 14/18] arm64: mremap speedup - Enable HAVE_MOVE_PMD HAVE_MOVE_PMD enables remapping pages at the PMD level if both the source and destination addresses are PMD-aligned. HAVE_MOVE_PMD is already enabled on x86. The original patch [1] that introduced this config did not enable it on arm64 at the time because of performance issues with flushing the TLB on every PMD move. These issues have since been addressed in more recent releases with improvements to the arm64 TLB invalidation and core mmu_gather code as Will Deacon mentioned in [2]. >From the data below, it can be inferred that there is approximately 8x improvement in performance when HAVE_MOVE_PMD is enabled on arm64. --------- Test Results ---------- The following results were obtained on an arm64 device running a 5.4 kernel, by remapping a PMD-aligned, 1GB sized region to a PMD-aligned destination. The results from 10 iterations of the test are given below. All times are in nanoseconds. Control HAVE_MOVE_PMD 9220833 1247761 9002552 1219896 9254115 1094792 8725885 1227760 9308646 1043698 9001667 1101771 8793385 1159896 8774636 1143594 9553125 1025833 9374010 1078125 9100885.4 1134312.6 <-- Mean Time in nanoseconds Total mremap time for a 1GB sized PMD-aligned region drops from ~9.1 milliseconds to ~1.1 milliseconds. (~8x speedup). [1] https://lore.kernel.org/r/20181108181201.88826-3-joelaf@google.com [2] https://www.mail-archive.com/linuxppc-dev@lists.ozlabs.org/msg140837.html Signed-off-by: Kalesh Singh Acked-by: Kirill A. Shutemov Cc: Catalin Marinas Cc: Will Deacon Cc: Andrew Morton Link: https://lore.kernel.org/r/20201014005320.2233162-3-kaleshsingh@google.com Link: https://lore.kernel.org/kvmarm/20181029102840.GC13965@arm.com/ Signed-off-by: Will Deacon --- arch/arm64/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 43091f439e4e..02e1a868d570 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -122,6 +122,7 @@ config ARM64 select GENERIC_VDSO_TIME_NS select HANDLE_DOMAIN_IRQ select HARDIRQS_SW_RESEND + select HAVE_MOVE_PMD select HAVE_PCI select HAVE_ACPI_APEI if (ACPI && EFI) select HAVE_ALIGNED_STRUCT_PAGE if SLUB From 7bdf468a5b40bbf1776e17eb1313d145d3e3ce28 Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Fri, 16 Oct 2020 17:26:37 -0700 Subject: [PATCH 15/18] arm64: Fix a broken copyright header in gen_vdso_offsets.sh I was going to copy this but I didn't want to chase around the build system stuff so I did it a different way. Signed-off-by: Palmer Dabbelt Link: https://lore.kernel.org/r/20201017002637.503579-1-palmer@dabbelt.com Signed-off-by: Will Deacon --- arch/arm64/kernel/vdso/gen_vdso_offsets.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/vdso/gen_vdso_offsets.sh b/arch/arm64/kernel/vdso/gen_vdso_offsets.sh index 0664acaf61ff..8b806eacd0a6 100755 --- a/arch/arm64/kernel/vdso/gen_vdso_offsets.sh +++ b/arch/arm64/kernel/vdso/gen_vdso_offsets.sh @@ -8,7 +8,7 @@ # Doing this inside the Makefile will break the $(filter-out) function, # causing Kbuild to rebuild the vdso-offsets header file every time. # -# Author: Will Deacon # LC_ALL=C From 3b92fa7485eba16b05166fddf38ab42f2ff6ab95 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Fri, 16 Oct 2020 10:53:39 -0700 Subject: [PATCH 16/18] arm64: link with -z norelro regardless of CONFIG_RELOCATABLE With CONFIG_EXPERT=y, CONFIG_KASAN=y, CONFIG_RANDOMIZE_BASE=n, CONFIG_RELOCATABLE=n, we observe the following failure when trying to link the kernel image with LD=ld.lld: error: section: .exit.data is not contiguous with other relro sections ld.lld defaults to -z relro while ld.bfd defaults to -z norelro. This was previously fixed, but only for CONFIG_RELOCATABLE=y. Fixes: 3bbd3db86470 ("arm64: relocatable: fix inconsistencies in linker script and options") Signed-off-by: Nick Desaulniers Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20201016175339.2429280-1-ndesaulniers@google.com Signed-off-by: Will Deacon --- arch/arm64/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 0fd4c1be4f64..1245274dacf9 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -10,13 +10,13 @@ # # Copyright (C) 1995-2001 by Russell King -LDFLAGS_vmlinux :=--no-undefined -X +LDFLAGS_vmlinux :=--no-undefined -X -z norelro ifeq ($(CONFIG_RELOCATABLE), y) # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour # for relative relocs, since this leads to better Image compression # with the relocation offsets always being zero. -LDFLAGS_vmlinux += -shared -Bsymbolic -z notext -z norelro \ +LDFLAGS_vmlinux += -shared -Bsymbolic -z notext \ $(call ld-option, --no-apply-dynamic-relocs) endif From ea8f8c99a28199f6e067581b8626d192b07750f2 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 20 Oct 2020 16:01:57 +0100 Subject: [PATCH 17/18] arm64: spectre-v2: Favour CPU-specific mitigation at EL2 Spectre-v2 can be mitigated on Falkor CPUs either by calling into firmware or by issuing a magic, CPU-specific sequence of branches. Although the latter is faster, the size of the code sequence means that it cannot be used in the EL2 vectors, and so there is a need for both mitigations to co-exist in order to achieve optimal performance. Change the mitigation selection logic for Spectre-v2 so that the CPU-specific mitigation is used only when the firmware mitigation is also available, rather than when a firmware mitigation is unavailable. Cc: Marc Zyngier Signed-off-by: Will Deacon --- arch/arm64/kernel/proton-pack.c | 36 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index 68b710f1b43f..5029ef14fb27 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -67,7 +67,8 @@ ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, * - Mitigated in hardware and advertised by ID_AA64PFR0_EL1.CSV2. * - Mitigated in hardware and listed in our "safe list". * - Mitigated in software by firmware. - * - Mitigated in software by a CPU-specific dance in the kernel. + * - Mitigated in software by a CPU-specific dance in the kernel and a + * firmware call at EL2. * - Vulnerable. * * It's not unlikely for different CPUs in a big.LITTLE system to fall into @@ -259,6 +260,16 @@ static void qcom_link_stack_sanitisation(void) : "=&r" (tmp)); } +static bp_hardening_cb_t spectre_v2_get_sw_mitigation_cb(void) +{ + u32 midr = read_cpuid_id(); + if (((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR) && + ((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR_V1)) + return NULL; + + return qcom_link_stack_sanitisation; +} + static enum mitigation_state spectre_v2_enable_fw_mitigation(void) { bp_hardening_cb_t cb; @@ -284,26 +295,15 @@ static enum mitigation_state spectre_v2_enable_fw_mitigation(void) return SPECTRE_VULNERABLE; } + /* + * Prefer a CPU-specific workaround if it exists. Note that we + * still rely on firmware for the mitigation at EL2. + */ + cb = spectre_v2_get_sw_mitigation_cb() ?: cb; install_bp_hardening_cb(cb); return SPECTRE_MITIGATED; } -static enum mitigation_state spectre_v2_enable_sw_mitigation(void) -{ - u32 midr; - - if (spectre_v2_mitigations_off()) - return SPECTRE_VULNERABLE; - - midr = read_cpuid_id(); - if (((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR) && - ((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR_V1)) - return SPECTRE_VULNERABLE; - - install_bp_hardening_cb(qcom_link_stack_sanitisation); - return SPECTRE_MITIGATED; -} - void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused) { enum mitigation_state state; @@ -313,8 +313,6 @@ void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused) state = spectre_v2_get_cpu_hw_mitigation_state(); if (state == SPECTRE_VULNERABLE) state = spectre_v2_enable_fw_mitigation(); - if (state == SPECTRE_VULNERABLE) - state = spectre_v2_enable_sw_mitigation(); update_mitigation_state(&spectre_v2_state, state); } From 66dd3474702aa98d5844367e1577cdad78ef7c65 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 20 Oct 2020 14:45:44 -0700 Subject: [PATCH 18/18] arm64: proton-pack: Update comment to reflect new function name The function detect_harden_bp_fw() is gone after commit d4647f0a2ad7 ("arm64: Rewrite Spectre-v2 mitigation code"). Update this comment to reflect the new state of affairs. Fixes: d4647f0a2ad7 ("arm64: Rewrite Spectre-v2 mitigation code") Signed-off-by: Stephen Boyd Cc: Marc Zyngier Link: https://lore.kernel.org/r/20201020214544.3206838-3-swboyd@chromium.org Signed-off-by: Will Deacon --- arch/arm64/kernel/proton-pack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index 5029ef14fb27..25f3c80b5ffe 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -205,8 +205,8 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn) __SMCCC_WORKAROUND_1_SMC_SZ; /* - * detect_harden_bp_fw() passes NULL for the hyp_vecs start/end if - * we're a guest. Skip the hyp-vectors work. + * Vinz Clortho takes the hyp_vecs start/end "keys" at + * the door when we're a guest. Skip the hyp-vectors work. */ if (!is_hyp_mode_available()) { __this_cpu_write(bp_hardening_data.fn, fn);