summaryrefslogtreecommitdiff
path: root/drivers/resctrl/mpam_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/resctrl/mpam_internal.h')
-rw-r--r--drivers/resctrl/mpam_internal.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/resctrl/mpam_internal.h b/drivers/resctrl/mpam_internal.h
index 768a58a3ab27..97f02cf92d7a 100644
--- a/drivers/resctrl/mpam_internal.h
+++ b/drivers/resctrl/mpam_internal.h
@@ -10,6 +10,7 @@
#include <linux/llist.h>
#include <linux/mutex.h>
#include <linux/srcu.h>
+#include <linux/spinlock.h>
#include <linux/types.h>
#define MPAM_MSC_MAX_NUM_RIS 16
@@ -65,12 +66,52 @@ struct mpam_msc {
*/
struct mutex part_sel_lock;
+ /*
+ * mon_sel_lock protects access to the MSC hardware registers that are
+ * affected by MPAMCFG_MON_SEL, and the mbwu_state.
+ * Access to mon_sel is needed from both process and interrupt contexts,
+ * but is complicated by firmware-backed platforms that can't make any
+ * access unless they can sleep.
+ * Always use the mpam_mon_sel_lock() helpers.
+ * Accesses to mon_sel need to be able to fail if they occur in the wrong
+ * context.
+ * If needed, take msc->probe_lock first.
+ */
+ raw_spinlock_t _mon_sel_lock;
+ unsigned long _mon_sel_flags;
+
void __iomem *mapped_hwpage;
size_t mapped_hwpage_sz;
struct mpam_garbage garbage;
};
+/* Returning false here means accesses to mon_sel must fail and report an error. */
+static inline bool __must_check mpam_mon_sel_lock(struct mpam_msc *msc)
+{
+ /* Locking will require updating to support a firmware backed interface */
+ if (WARN_ON_ONCE(msc->iface != MPAM_IFACE_MMIO))
+ return false;
+
+ raw_spin_lock_irqsave(&msc->_mon_sel_lock, msc->_mon_sel_flags);
+ return true;
+}
+
+static inline void mpam_mon_sel_unlock(struct mpam_msc *msc)
+{
+ raw_spin_unlock_irqrestore(&msc->_mon_sel_lock, msc->_mon_sel_flags);
+}
+
+static inline void mpam_mon_sel_lock_held(struct mpam_msc *msc)
+{
+ lockdep_assert_held_once(&msc->_mon_sel_lock);
+}
+
+static inline void mpam_mon_sel_lock_init(struct mpam_msc *msc)
+{
+ raw_spin_lock_init(&msc->_mon_sel_lock);
+}
+
struct mpam_class {
/* mpam_components in this class */
struct list_head components;