lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri,  3 May 2019 11:44:51 +0300
From:   Alexander Shishkin <alexander.shishkin@...ux.intel.com>
To:     Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc:     linux-kernel@...r.kernel.org,
        Alexander Shishkin <alexander.shishkin@...ux.intel.com>
Subject: [GIT PULL 18/22] intel_th: msu: Add current window tracking

Now that we have a way to switch between MSC buffer windows, add code to
track the current window. The hardware register NWSA that contains the
address of the next window is unfortunately not always usable, and since
the driver has full control of the window switching, there is no reason
not to keep this on the software side.

Signed-off-by: Alexander Shishkin <alexander.shishkin@...ux.intel.com>
---
 drivers/hwtracing/intel_th/msu.c | 79 ++++++++++++++++++++------------
 1 file changed, 49 insertions(+), 30 deletions(-)

diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c
index 089fd1f90a9f..2916de5651aa 100644
--- a/drivers/hwtracing/intel_th/msu.c
+++ b/drivers/hwtracing/intel_th/msu.c
@@ -77,6 +77,7 @@ struct msc_iter {
  * @thdev:		intel_th_device pointer
  * @win_list:		list of windows in multiblock mode
  * @single_sgt:		single mode buffer
+ * @cur_win:		current window
  * @nr_pages:		total number of pages allocated for this buffer
  * @single_sz:		amount of data in single mode
  * @single_wrap:	single mode wrap occurred
@@ -99,6 +100,7 @@ struct msc {
 
 	struct list_head	win_list;
 	struct sg_table		single_sgt;
+	struct msc_window	*cur_win;
 	unsigned long		nr_pages;
 	unsigned long		single_sz;
 	unsigned int		single_wrap : 1;
@@ -159,6 +161,31 @@ msc_win_bpfn(struct msc_window *win, unsigned int block)
 	return msc_win_baddr(win, block) >> PAGE_SHIFT;
 }
 
+/**
+ * msc_is_last_win() - check if a window is the last one for a given MSC
+ * @win:	window
+ * Return:	true if @win is the last window in MSC's multiblock buffer
+ */
+static inline bool msc_is_last_win(struct msc_window *win)
+{
+	return win->entry.next == &win->msc->win_list;
+}
+
+/**
+ * msc_next_window() - return next window in the multiblock buffer
+ * @win:	current window
+ *
+ * Return:	window following the current one
+ */
+static struct msc_window *msc_next_window(struct msc_window *win)
+{
+	if (msc_is_last_win(win))
+		return list_first_entry(&win->msc->win_list, struct msc_window,
+					entry);
+
+	return list_next_entry(win, entry);
+}
+
 /**
  * msc_oldest_window() - locate the window with oldest data
  * @msc:	MSC device
@@ -170,9 +197,7 @@ msc_win_bpfn(struct msc_window *win, unsigned int block)
  */
 static struct msc_window *msc_oldest_window(struct msc *msc)
 {
-	struct msc_window *win;
-	u32 reg = ioread32(msc->reg_base + REG_MSU_MSC0NWSA);
-	unsigned long win_addr = (unsigned long)reg << PAGE_SHIFT;
+	struct msc_window *win, *next = msc_next_window(msc->cur_win);
 	unsigned int found = 0;
 
 	if (list_empty(&msc->win_list))
@@ -184,7 +209,7 @@ static struct msc_window *msc_oldest_window(struct msc *msc)
 	 * something like 2, in which case we're good
 	 */
 	list_for_each_entry(win, &msc->win_list, entry) {
-		if (sg_dma_address(win->sgt.sgl) == win_addr)
+		if (win == next)
 			found++;
 
 		/* skip the empty ones */
@@ -227,31 +252,6 @@ static unsigned int msc_win_oldest_block(struct msc_window *win)
 	return 0;
 }
 
-/**
- * msc_is_last_win() - check if a window is the last one for a given MSC
- * @win:	window
- * Return:	true if @win is the last window in MSC's multiblock buffer
- */
-static inline bool msc_is_last_win(struct msc_window *win)
-{
-	return win->entry.next == &win->msc->win_list;
-}
-
-/**
- * msc_next_window() - return next window in the multiblock buffer
- * @win:	current window
- *
- * Return:	window following the current one
- */
-static struct msc_window *msc_next_window(struct msc_window *win)
-{
-	if (msc_is_last_win(win))
-		return list_first_entry(&win->msc->win_list, struct msc_window,
-					entry);
-
-	return list_next_entry(win, entry);
-}
-
 static struct msc_block_desc *msc_iter_bdesc(struct msc_iter *iter)
 {
 	return msc_win_block(iter->win, iter->block);
@@ -830,6 +830,7 @@ static int msc_buffer_win_alloc(struct msc *msc, unsigned int nr_pages)
 	if (list_empty(&msc->win_list)) {
 		msc->base = msc_win_block(win, 0);
 		msc->base_addr = msc_win_baddr(win, 0);
+		msc->cur_win = win;
 	}
 
 	list_add_tail(&win->entry, &msc->win_list);
@@ -1403,6 +1404,24 @@ static int intel_th_msc_init(struct msc *msc)
 	return 0;
 }
 
+static void msc_win_switch(struct msc *msc)
+{
+	struct msc_window *last, *first;
+
+	first = list_first_entry(&msc->win_list, struct msc_window, entry);
+	last = list_last_entry(&msc->win_list, struct msc_window, entry);
+
+	if (msc_is_last_win(msc->cur_win))
+		msc->cur_win = first;
+	else
+		msc->cur_win = list_next_entry(msc->cur_win, entry);
+
+	msc->base = msc_win_block(msc->cur_win, 0);
+	msc->base_addr = msc_win_baddr(msc->cur_win, 0);
+
+	intel_th_trace_switch(msc->thdev);
+}
+
 static irqreturn_t intel_th_msc_interrupt(struct intel_th_device *thdev)
 {
 	struct msc *msc = dev_get_drvdata(&thdev->dev);
@@ -1611,7 +1630,7 @@ win_switch_store(struct device *dev, struct device_attribute *attr,
 	if (msc->mode != MSC_MODE_MULTI)
 		ret = -ENOTSUPP;
 	else
-		ret = intel_th_trace_switch(msc->thdev);
+		msc_win_switch(msc);
 	mutex_unlock(&msc->buf_mutex);
 
 	return ret ? ret : size;
-- 
2.20.1

Powered by blists - more mailing lists