* [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm
@ 2018-09-16 12:02 Jarkko Sakkinen
2018-09-16 12:46 ` Greg KH
2018-09-17 9:30 ` Greg KH
0 siblings, 2 replies; 7+ messages in thread
From: Jarkko Sakkinen @ 2018-09-16 12:02 UTC (permalink / raw)
To: stable; +Cc: Tomas Winkler, Jarkko Sakkinen
From: Tomas Winkler <tomas.winkler@intel.com>
commit 627448e85c766587f6fdde1ea3886d6615081c77 upstream
Fix tpm ptt initialization error:
tpm tpm0: A TPM error (378) occurred get tpm pcr allocation.
We cannot use go_idle cmd_ready commands via runtime_pm handles
as with the introduction of localities this is no longer an optional
feature, while runtime pm can be not enabled.
Though cmd_ready/go_idle provides a power saving, it's also a part of
TPM2 protocol and should be called explicitly.
This patch exposes cmd_read/go_idle via tpm class ops and removes
runtime pm support as it is not used by any driver.
When calling from nested context always use both flags:
TPM_TRANSMIT_UNLOCKED and TPM_TRANSMIT_RAW. Both are needed to resolve
tpm spaces and locality request recursive calls to tpm_transmit().
TPM_TRANSMIT_RAW should never be used standalone as it will fail
on double locking. While TPM_TRANSMIT_UNLOCKED standalone should be
called from non-recursive locked contexts.
New wrappers are added tpm_cmd_ready() and tpm_go_idle() to
streamline tpm_try_transmit code.
tpm_crb no longer needs own power saving functions and can drop using
tpm_pm_suspend/resume.
This patch cannot be really separated from the locality fix.
Fixes: 888d867df441 (tpm: cmd_ready command can be issued only after granting locality)
Cc: stable@vger.kernel.org
Fixes: 888d867df441 (tpm: cmd_ready command can be issued only after granting locality)
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
drivers/char/tpm/tpm-interface.c | 50 ++++++++++++---
drivers/char/tpm/tpm.h | 12 +++-
drivers/char/tpm/tpm2-space.c | 16 +++--
drivers/char/tpm/tpm_crb.c | 101 +++++++++----------------------
include/linux/tpm.h | 2 +
5 files changed, 90 insertions(+), 91 deletions(-)
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 86b526b7d990..a2070ab86c82 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -369,10 +369,13 @@ static int tpm_validate_command(struct tpm_chip *chip,
return -EINVAL;
}
-static int tpm_request_locality(struct tpm_chip *chip)
+static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags)
{
int rc;
+ if (flags & TPM_TRANSMIT_RAW)
+ return 0;
+
if (!chip->ops->request_locality)
return 0;
@@ -385,10 +388,13 @@ static int tpm_request_locality(struct tpm_chip *chip)
return 0;
}
-static void tpm_relinquish_locality(struct tpm_chip *chip)
+static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags)
{
int rc;
+ if (flags & TPM_TRANSMIT_RAW)
+ return;
+
if (!chip->ops->relinquish_locality)
return;
@@ -399,6 +405,28 @@ static void tpm_relinquish_locality(struct tpm_chip *chip)
chip->locality = -1;
}
+static int tpm_cmd_ready(struct tpm_chip *chip, unsigned int flags)
+{
+ if (flags & TPM_TRANSMIT_RAW)
+ return 0;
+
+ if (!chip->ops->cmd_ready)
+ return 0;
+
+ return chip->ops->cmd_ready(chip);
+}
+
+static int tpm_go_idle(struct tpm_chip *chip, unsigned int flags)
+{
+ if (flags & TPM_TRANSMIT_RAW)
+ return 0;
+
+ if (!chip->ops->go_idle)
+ return 0;
+
+ return chip->ops->go_idle(chip);
+}
+
static ssize_t tpm_try_transmit(struct tpm_chip *chip,
struct tpm_space *space,
u8 *buf, size_t bufsiz,
@@ -449,14 +477,15 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,
/* Store the decision as chip->locality will be changed. */
need_locality = chip->locality == -1;
- if (!(flags & TPM_TRANSMIT_RAW) && need_locality) {
- rc = tpm_request_locality(chip);
+ if (need_locality) {
+ rc = tpm_request_locality(chip, flags);
if (rc < 0)
goto out_no_locality;
}
- if (chip->dev.parent)
- pm_runtime_get_sync(chip->dev.parent);
+ rc = tpm_cmd_ready(chip, flags);
+ if (rc)
+ goto out;
rc = tpm2_prepare_space(chip, space, ordinal, buf);
if (rc)
@@ -516,13 +545,16 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,
}
rc = tpm2_commit_space(chip, space, ordinal, buf, &len);
+ if (rc)
+ dev_err(&chip->dev, "tpm2_commit_space: error %d\n", rc);
out:
- if (chip->dev.parent)
- pm_runtime_put_sync(chip->dev.parent);
+ rc = tpm_go_idle(chip, flags);
+ if (rc)
+ goto out;
if (need_locality)
- tpm_relinquish_locality(chip);
+ tpm_relinquish_locality(chip, flags);
out_no_locality:
if (chip->ops->clk_enable != NULL)
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index b83b30a3eea5..4bb9b4aa9b49 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -511,9 +511,17 @@ extern const struct file_operations tpm_fops;
extern const struct file_operations tpmrm_fops;
extern struct idr dev_nums_idr;
+/**
+ * enum tpm_transmit_flags
+ *
+ * @TPM_TRANSMIT_UNLOCKED: used to lock sequence of tpm_transmit calls.
+ * @TPM_TRANSMIT_RAW: prevent recursive calls into setup steps
+ * (go idle, locality,..). Always use with UNLOCKED
+ * as it will fail on double locking.
+ */
enum tpm_transmit_flags {
- TPM_TRANSMIT_UNLOCKED = BIT(0),
- TPM_TRANSMIT_RAW = BIT(1),
+ TPM_TRANSMIT_UNLOCKED = BIT(0),
+ TPM_TRANSMIT_RAW = BIT(1),
};
ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index d26ea7513226..dabb2ae4e779 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -39,7 +39,8 @@ static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
if (space->session_tbl[i])
tpm2_flush_context_cmd(chip, space->session_tbl[i],
- TPM_TRANSMIT_UNLOCKED);
+ TPM_TRANSMIT_UNLOCKED |
+ TPM_TRANSMIT_RAW);
}
}
@@ -84,7 +85,7 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
tpm_buf_append(&tbuf, &buf[*offset], body_size);
rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 4,
- TPM_TRANSMIT_UNLOCKED, NULL);
+ TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW, NULL);
if (rc < 0) {
dev_warn(&chip->dev, "%s: failed with a system error %d\n",
__func__, rc);
@@ -133,7 +134,7 @@ static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
tpm_buf_append_u32(&tbuf, handle);
rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 0,
- TPM_TRANSMIT_UNLOCKED, NULL);
+ TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW, NULL);
if (rc < 0) {
dev_warn(&chip->dev, "%s: failed with a system error %d\n",
__func__, rc);
@@ -170,7 +171,8 @@ static void tpm2_flush_space(struct tpm_chip *chip)
for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
if (space->context_tbl[i] && ~space->context_tbl[i])
tpm2_flush_context_cmd(chip, space->context_tbl[i],
- TPM_TRANSMIT_UNLOCKED);
+ TPM_TRANSMIT_UNLOCKED |
+ TPM_TRANSMIT_RAW);
tpm2_flush_sessions(chip, space);
}
@@ -377,7 +379,8 @@ static int tpm2_map_response_header(struct tpm_chip *chip, u32 cc, u8 *rsp,
return 0;
out_no_slots:
- tpm2_flush_context_cmd(chip, phandle, TPM_TRANSMIT_UNLOCKED);
+ tpm2_flush_context_cmd(chip, phandle,
+ TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW);
dev_warn(&chip->dev, "%s: out of slots for 0x%08X\n", __func__,
phandle);
return -ENOMEM;
@@ -465,7 +468,8 @@ static int tpm2_save_space(struct tpm_chip *chip)
return rc;
tpm2_flush_context_cmd(chip, space->context_tbl[i],
- TPM_TRANSMIT_UNLOCKED);
+ TPM_TRANSMIT_UNLOCKED |
+ TPM_TRANSMIT_RAW);
space->context_tbl[i] = ~0;
}
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index bb756ad7897e..5c7ce5aaaf6f 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -137,7 +137,7 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
}
/**
- * crb_go_idle - request tpm crb device to go the idle state
+ * __crb_go_idle - request tpm crb device to go the idle state
*
* @dev: crb device
* @priv: crb private data
@@ -151,7 +151,7 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
*
* Return: 0 always
*/
-static int crb_go_idle(struct device *dev, struct crb_priv *priv)
+static int __crb_go_idle(struct device *dev, struct crb_priv *priv)
{
if ((priv->flags & CRB_FL_ACPI_START) ||
(priv->flags & CRB_FL_CRB_SMC_START))
@@ -166,11 +166,20 @@ static int crb_go_idle(struct device *dev, struct crb_priv *priv)
dev_warn(dev, "goIdle timed out\n");
return -ETIME;
}
+
return 0;
}
+static int crb_go_idle(struct tpm_chip *chip)
+{
+ struct device *dev = &chip->dev;
+ struct crb_priv *priv = dev_get_drvdata(dev);
+
+ return __crb_go_idle(dev, priv);
+}
+
/**
- * crb_cmd_ready - request tpm crb device to enter ready state
+ * __crb_cmd_ready - request tpm crb device to enter ready state
*
* @dev: crb device
* @priv: crb private data
@@ -183,7 +192,7 @@ static int crb_go_idle(struct device *dev, struct crb_priv *priv)
*
* Return: 0 on success -ETIME on timeout;
*/
-static int crb_cmd_ready(struct device *dev, struct crb_priv *priv)
+static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv)
{
if ((priv->flags & CRB_FL_ACPI_START) ||
(priv->flags & CRB_FL_CRB_SMC_START))
@@ -201,6 +210,14 @@ static int crb_cmd_ready(struct device *dev, struct crb_priv *priv)
return 0;
}
+static int crb_cmd_ready(struct tpm_chip *chip)
+{
+ struct device *dev = &chip->dev;
+ struct crb_priv *priv = dev_get_drvdata(dev);
+
+ return __crb_cmd_ready(dev, priv);
+}
+
static int __crb_request_locality(struct device *dev,
struct crb_priv *priv, int loc)
{
@@ -393,6 +410,8 @@ static const struct tpm_class_ops tpm_crb = {
.send = crb_send,
.cancel = crb_cancel,
.req_canceled = crb_req_canceled,
+ .go_idle = crb_go_idle,
+ .cmd_ready = crb_cmd_ready,
.request_locality = crb_request_locality,
.relinquish_locality = crb_relinquish_locality,
.req_complete_mask = CRB_DRV_STS_COMPLETE,
@@ -508,7 +527,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
* PTT HW bug w/a: wake up the device to access
* possibly not retained registers.
*/
- ret = crb_cmd_ready(dev, priv);
+ ret = __crb_cmd_ready(dev, priv);
if (ret)
return ret;
@@ -553,7 +572,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
if (!ret)
priv->cmd_size = cmd_size;
- crb_go_idle(dev, priv);
+ __crb_go_idle(dev, priv);
__crb_relinquish_locality(dev, priv, 0);
@@ -624,32 +643,7 @@ static int crb_acpi_add(struct acpi_device *device)
chip->acpi_dev_handle = device->handle;
chip->flags = TPM_CHIP_FLAG_TPM2;
- rc = __crb_request_locality(dev, priv, 0);
- if (rc)
- return rc;
-
- rc = crb_cmd_ready(dev, priv);
- if (rc)
- goto out;
-
- pm_runtime_get_noresume(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
-
- rc = tpm_chip_register(chip);
- if (rc) {
- crb_go_idle(dev, priv);
- pm_runtime_put_noidle(dev);
- pm_runtime_disable(dev);
- goto out;
- }
-
- pm_runtime_put_sync(dev);
-
-out:
- __crb_relinquish_locality(dev, priv, 0);
-
- return rc;
+ return tpm_chip_register(chip);
}
static int crb_acpi_remove(struct acpi_device *device)
@@ -659,52 +653,11 @@ static int crb_acpi_remove(struct acpi_device *device)
tpm_chip_unregister(chip);
- pm_runtime_disable(dev);
-
return 0;
}
-static int __maybe_unused crb_pm_runtime_suspend(struct device *dev)
-{
- struct tpm_chip *chip = dev_get_drvdata(dev);
- struct crb_priv *priv = dev_get_drvdata(&chip->dev);
-
- return crb_go_idle(dev, priv);
-}
-
-static int __maybe_unused crb_pm_runtime_resume(struct device *dev)
-{
- struct tpm_chip *chip = dev_get_drvdata(dev);
- struct crb_priv *priv = dev_get_drvdata(&chip->dev);
-
- return crb_cmd_ready(dev, priv);
-}
-
-static int __maybe_unused crb_pm_suspend(struct device *dev)
-{
- int ret;
-
- ret = tpm_pm_suspend(dev);
- if (ret)
- return ret;
-
- return crb_pm_runtime_suspend(dev);
-}
-
-static int __maybe_unused crb_pm_resume(struct device *dev)
-{
- int ret;
-
- ret = crb_pm_runtime_resume(dev);
- if (ret)
- return ret;
-
- return tpm_pm_resume(dev);
-}
-
static const struct dev_pm_ops crb_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(crb_pm_suspend, crb_pm_resume)
- SET_RUNTIME_PM_OPS(crb_pm_runtime_suspend, crb_pm_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(tpm_pm_suspend, tpm_pm_resume)
};
static const struct acpi_device_id crb_device_ids[] = {
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 2a6c3d96b31f..7f7b29f86c59 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -48,6 +48,8 @@ struct tpm_class_ops {
u8 (*status) (struct tpm_chip *chip);
bool (*update_timeouts)(struct tpm_chip *chip,
unsigned long *timeout_cap);
+ int (*go_idle)(struct tpm_chip *chip);
+ int (*cmd_ready)(struct tpm_chip *chip);
int (*request_locality)(struct tpm_chip *chip, int loc);
int (*relinquish_locality)(struct tpm_chip *chip, int loc);
void (*clk_enable)(struct tpm_chip *chip, bool value);
--
2.17.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm
2018-09-16 12:02 [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm Jarkko Sakkinen
@ 2018-09-16 12:46 ` Greg KH
2018-09-17 0:55 ` Sasha Levin
2018-09-17 9:30 ` Greg KH
1 sibling, 1 reply; 7+ messages in thread
From: Greg KH @ 2018-09-16 12:46 UTC (permalink / raw)
To: Jarkko Sakkinen; +Cc: stable, Tomas Winkler
On Sun, Sep 16, 2018 at 03:02:27PM +0300, Jarkko Sakkinen wrote:
> From: Tomas Winkler <tomas.winkler@intel.com>
>
> commit 627448e85c766587f6fdde1ea3886d6615081c77 upstream
Are you sure? That commit is not in Linus's tree :(
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm
2018-09-16 12:46 ` Greg KH
@ 2018-09-17 0:55 ` Sasha Levin
2018-09-17 4:47 ` Greg KH
2018-09-17 7:21 ` Winkler, Tomas
0 siblings, 2 replies; 7+ messages in thread
From: Sasha Levin @ 2018-09-17 0:55 UTC (permalink / raw)
To: Greg KH; +Cc: Jarkko Sakkinen, stable@vger.kernel.org, Tomas Winkler
On Sun, Sep 16, 2018 at 02:46:42PM +0200, Greg KH wrote:
>On Sun, Sep 16, 2018 at 03:02:27PM +0300, Jarkko Sakkinen wrote:
>> From: Tomas Winkler <tomas.winkler@intel.com>
>>
>> commit 627448e85c766587f6fdde1ea3886d6615081c77 upstream
>
>Are you sure? That commit is not in Linus's tree :(
Are you sure? I see it went in during the 4.19 merge window.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm
2018-09-17 0:55 ` Sasha Levin
@ 2018-09-17 4:47 ` Greg KH
2018-09-17 21:14 ` Jarkko Sakkinen
2018-09-17 7:21 ` Winkler, Tomas
1 sibling, 1 reply; 7+ messages in thread
From: Greg KH @ 2018-09-17 4:47 UTC (permalink / raw)
To: Sasha Levin; +Cc: Jarkko Sakkinen, stable@vger.kernel.org, Tomas Winkler
On Mon, Sep 17, 2018 at 12:55:24AM +0000, Sasha Levin wrote:
> On Sun, Sep 16, 2018 at 02:46:42PM +0200, Greg KH wrote:
> >On Sun, Sep 16, 2018 at 03:02:27PM +0300, Jarkko Sakkinen wrote:
> >> From: Tomas Winkler <tomas.winkler@intel.com>
> >>
> >> commit 627448e85c766587f6fdde1ea3886d6615081c77 upstream
> >
> >Are you sure? That commit is not in Linus's tree :(
>
> Are you sure? I see it went in during the 4.19 merge window.
Ugh, it's been a long week, sorry, you are right, my mistake, I was in
the wrong git repo when I checked this.
greg k-h
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm
2018-09-17 4:47 ` Greg KH
@ 2018-09-17 21:14 ` Jarkko Sakkinen
0 siblings, 0 replies; 7+ messages in thread
From: Jarkko Sakkinen @ 2018-09-17 21:14 UTC (permalink / raw)
To: Greg KH; +Cc: Sasha Levin, stable@vger.kernel.org, Tomas Winkler
On Mon, Sep 17, 2018 at 06:47:06AM +0200, Greg KH wrote:
> On Mon, Sep 17, 2018 at 12:55:24AM +0000, Sasha Levin wrote:
> > On Sun, Sep 16, 2018 at 02:46:42PM +0200, Greg KH wrote:
> > >On Sun, Sep 16, 2018 at 03:02:27PM +0300, Jarkko Sakkinen wrote:
> > >> From: Tomas Winkler <tomas.winkler@intel.com>
> > >>
> > >> commit 627448e85c766587f6fdde1ea3886d6615081c77 upstream
> > >
> > >Are you sure? That commit is not in Linus's tree :(
> >
> > Are you sure? I see it went in during the 4.19 merge window.
>
> Ugh, it's been a long week, sorry, you are right, my mistake, I was in
> the wrong git repo when I checked this.
>
> greg k-h
Anyway remainded me that one should is always double check the mainline
tree (which I admit did not do, only James Morris' tree).
/Jarkko
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm
2018-09-17 0:55 ` Sasha Levin
2018-09-17 4:47 ` Greg KH
@ 2018-09-17 7:21 ` Winkler, Tomas
1 sibling, 0 replies; 7+ messages in thread
From: Winkler, Tomas @ 2018-09-17 7:21 UTC (permalink / raw)
To: Sasha Levin, Greg KH; +Cc: Jarkko Sakkinen, stable@vger.kernel.org
>
> On Sun, Sep 16, 2018 at 02:46:42PM +0200, Greg KH wrote:
> >On Sun, Sep 16, 2018 at 03:02:27PM +0300, Jarkko Sakkinen wrote:
> >> From: Tomas Winkler <tomas.winkler@intel.com>
> >>
> >> commit 627448e85c766587f6fdde1ea3886d6615081c77 upstream
> >
> >Are you sure? That commit is not in Linus's tree :(
>
> Are you sure? I see it went in during the 4.19 merge window.
I see it as well in the master branch under this exact SHA1.
Tomas
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm
2018-09-16 12:02 [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm Jarkko Sakkinen
2018-09-16 12:46 ` Greg KH
@ 2018-09-17 9:30 ` Greg KH
1 sibling, 0 replies; 7+ messages in thread
From: Greg KH @ 2018-09-17 9:30 UTC (permalink / raw)
To: Jarkko Sakkinen; +Cc: stable, Tomas Winkler
On Sun, Sep 16, 2018 at 03:02:27PM +0300, Jarkko Sakkinen wrote:
> From: Tomas Winkler <tomas.winkler@intel.com>
>
> commit 627448e85c766587f6fdde1ea3886d6615081c77 upstream
Thanks, now queued up.
greg k-h
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2018-09-18 2:44 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-16 12:02 [PATCH] tpm: separate cmd_ready/go_idle from runtime_pm Jarkko Sakkinen
2018-09-16 12:46 ` Greg KH
2018-09-17 0:55 ` Sasha Levin
2018-09-17 4:47 ` Greg KH
2018-09-17 21:14 ` Jarkko Sakkinen
2018-09-17 7:21 ` Winkler, Tomas
2018-09-17 9:30 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).