]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.15.10/tpm-keep-clkrun-enabled-throughout-the-duration-of-transmit_cmd.patch
Fix up backported ptrace patch
[thirdparty/kernel/stable-queue.git] / releases / 4.15.10 / tpm-keep-clkrun-enabled-throughout-the-duration-of-transmit_cmd.patch
1 From b3e958ce4c585bf666de249dc794971ebc62d2d3 Mon Sep 17 00:00:00 2001
2 From: Azhar Shaikh <azhar.shaikh@intel.com>
3 Date: Fri, 22 Dec 2017 12:13:44 -0800
4 Subject: tpm: Keep CLKRUN enabled throughout the duration of transmit_cmd()
5
6 From: Azhar Shaikh <azhar.shaikh@intel.com>
7
8 commit b3e958ce4c585bf666de249dc794971ebc62d2d3 upstream.
9
10 Commit 5e572cab92f0bb5 ("tpm: Enable CLKRUN protocol for Braswell
11 systems") disabled CLKRUN protocol during TPM transactions and re-enabled
12 once the transaction is completed. But there were still some corner cases
13 observed where, reading of TPM header failed for savestate command
14 while going to suspend, which resulted in suspend failure.
15 To fix this issue keep the CLKRUN protocol disabled for the entire
16 duration of a single TPM command and not disabling and re-enabling
17 again for every TPM transaction. For the other TPM accesses outside
18 TPM command flow, add a higher level of disabling and re-enabling
19 the CLKRUN protocol, instead of doing for every TPM transaction.
20
21 Fixes: 5e572cab92f0bb5 ("tpm: Enable CLKRUN protocol for Braswell systems")
22 Signed-off-by: Azhar Shaikh <azhar.shaikh@intel.com>
23 Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
24 Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
25 Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
26 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
27
28 ---
29 drivers/char/tpm/tpm-interface.c | 6 ++
30 drivers/char/tpm/tpm_tis.c | 92 +++------------------------------
31 drivers/char/tpm/tpm_tis_core.c | 108 +++++++++++++++++++++++++++++++++++----
32 drivers/char/tpm/tpm_tis_core.h | 4 +
33 include/linux/tpm.h | 1
34 5 files changed, 119 insertions(+), 92 deletions(-)
35
36 --- a/drivers/char/tpm/tpm-interface.c
37 +++ b/drivers/char/tpm/tpm-interface.c
38 @@ -413,6 +413,9 @@ ssize_t tpm_transmit(struct tpm_chip *ch
39 if (chip->dev.parent)
40 pm_runtime_get_sync(chip->dev.parent);
41
42 + if (chip->ops->clk_enable != NULL)
43 + chip->ops->clk_enable(chip, true);
44 +
45 /* Store the decision as chip->locality will be changed. */
46 need_locality = chip->locality == -1;
47
48 @@ -489,6 +492,9 @@ out:
49 chip->locality = -1;
50 }
51 out_no_locality:
52 + if (chip->ops->clk_enable != NULL)
53 + chip->ops->clk_enable(chip, false);
54 +
55 if (chip->dev.parent)
56 pm_runtime_put_sync(chip->dev.parent);
57
58 --- a/drivers/char/tpm/tpm_tis.c
59 +++ b/drivers/char/tpm/tpm_tis.c
60 @@ -133,79 +133,17 @@ static int check_acpi_tpm2(struct device
61 }
62 #endif
63
64 -#ifdef CONFIG_X86
65 -#define LPC_CNTRL_OFFSET 0x84
66 -#define LPC_CLKRUN_EN (1 << 2)
67 -
68 -/**
69 - * tpm_platform_begin_xfer() - clear LPC CLKRUN_EN i.e. clocks will be running
70 - */
71 -static void tpm_platform_begin_xfer(struct tpm_tis_data *data)
72 -{
73 - u32 clkrun_val;
74 -
75 - if (!is_bsw())
76 - return;
77 -
78 - clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
79 -
80 - /* Disable LPC CLKRUN# */
81 - clkrun_val &= ~LPC_CLKRUN_EN;
82 - iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
83 -
84 - /*
85 - * Write any random value on port 0x80 which is on LPC, to make
86 - * sure LPC clock is running before sending any TPM command.
87 - */
88 - outb(0xCC, 0x80);
89 -
90 -}
91 -
92 -/**
93 - * tpm_platform_end_xfer() - set LPC CLKRUN_EN i.e. clocks can be turned off
94 - */
95 -static void tpm_platform_end_xfer(struct tpm_tis_data *data)
96 -{
97 - u32 clkrun_val;
98 -
99 - if (!is_bsw())
100 - return;
101 -
102 - clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
103 -
104 - /* Enable LPC CLKRUN# */
105 - clkrun_val |= LPC_CLKRUN_EN;
106 - iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
107 -
108 - /*
109 - * Write any random value on port 0x80 which is on LPC, to make
110 - * sure LPC clock is running before sending any TPM command.
111 - */
112 - outb(0xCC, 0x80);
113 -
114 -}
115 -#else
116 -static void tpm_platform_begin_xfer(struct tpm_tis_data *data)
117 -{
118 -}
119 -
120 -static void tpm_platform_end_xfer(struct tpm_tis_data *data)
121 -{
122 -}
123 -#endif
124 -
125 static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
126 u8 *result)
127 {
128 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
129
130 - tpm_platform_begin_xfer(data);
131 + if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
132 + WARN(1, "CLKRUN not enabled!\n");
133
134 while (len--)
135 *result++ = ioread8(phy->iobase + addr);
136
137 - tpm_platform_end_xfer(data);
138 -
139 return 0;
140 }
141
142 @@ -214,13 +152,12 @@ static int tpm_tcg_write_bytes(struct tp
143 {
144 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
145
146 - tpm_platform_begin_xfer(data);
147 + if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
148 + WARN(1, "CLKRUN not enabled!\n");
149
150 while (len--)
151 iowrite8(*value++, phy->iobase + addr);
152
153 - tpm_platform_end_xfer(data);
154 -
155 return 0;
156 }
157
158 @@ -228,12 +165,11 @@ static int tpm_tcg_read16(struct tpm_tis
159 {
160 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
161
162 - tpm_platform_begin_xfer(data);
163 + if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
164 + WARN(1, "CLKRUN not enabled!\n");
165
166 *result = ioread16(phy->iobase + addr);
167
168 - tpm_platform_end_xfer(data);
169 -
170 return 0;
171 }
172
173 @@ -241,12 +177,11 @@ static int tpm_tcg_read32(struct tpm_tis
174 {
175 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
176
177 - tpm_platform_begin_xfer(data);
178 + if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
179 + WARN(1, "CLKRUN not enabled!\n");
180
181 *result = ioread32(phy->iobase + addr);
182
183 - tpm_platform_end_xfer(data);
184 -
185 return 0;
186 }
187
188 @@ -254,12 +189,11 @@ static int tpm_tcg_write32(struct tpm_ti
189 {
190 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
191
192 - tpm_platform_begin_xfer(data);
193 + if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
194 + WARN(1, "CLKRUN not enabled!\n");
195
196 iowrite32(value, phy->iobase + addr);
197
198 - tpm_platform_end_xfer(data);
199 -
200 return 0;
201 }
202
203 @@ -341,9 +275,6 @@ static void tpm_tis_pnp_remove(struct pn
204
205 tpm_chip_unregister(chip);
206 tpm_tis_remove(chip);
207 - if (is_bsw())
208 - iounmap(priv->ilb_base_addr);
209 -
210 }
211
212 static struct pnp_driver tis_pnp_driver = {
213 @@ -395,9 +326,6 @@ static int tpm_tis_plat_remove(struct pl
214 tpm_chip_unregister(chip);
215 tpm_tis_remove(chip);
216
217 - if (is_bsw())
218 - iounmap(priv->ilb_base_addr);
219 -
220 return 0;
221 }
222
223 --- a/drivers/char/tpm/tpm_tis_core.c
224 +++ b/drivers/char/tpm/tpm_tis_core.c
225 @@ -31,6 +31,8 @@
226 #include "tpm.h"
227 #include "tpm_tis_core.h"
228
229 +static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
230 +
231 /* Before we attempt to access the TPM we must see that the valid bit is set.
232 * The specification says that this bit is 0 at reset and remains 0 until the
233 * 'TPM has gone through its self test and initialization and has established
234 @@ -422,19 +424,28 @@ static bool tpm_tis_update_timeouts(stru
235 int i, rc;
236 u32 did_vid;
237
238 + if (chip->ops->clk_enable != NULL)
239 + chip->ops->clk_enable(chip, true);
240 +
241 rc = tpm_tis_read32(priv, TPM_DID_VID(0), &did_vid);
242 if (rc < 0)
243 - return rc;
244 + goto out;
245
246 for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) {
247 if (vendor_timeout_overrides[i].did_vid != did_vid)
248 continue;
249 memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us,
250 sizeof(vendor_timeout_overrides[i].timeout_us));
251 - return true;
252 + rc = true;
253 }
254
255 - return false;
256 + rc = false;
257 +
258 +out:
259 + if (chip->ops->clk_enable != NULL)
260 + chip->ops->clk_enable(chip, false);
261 +
262 + return rc;
263 }
264
265 /*
266 @@ -654,14 +665,74 @@ void tpm_tis_remove(struct tpm_chip *chi
267 u32 interrupt;
268 int rc;
269
270 + tpm_tis_clkrun_enable(chip, true);
271 +
272 rc = tpm_tis_read32(priv, reg, &interrupt);
273 if (rc < 0)
274 interrupt = 0;
275
276 tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt);
277 +
278 + tpm_tis_clkrun_enable(chip, false);
279 +
280 + if (priv->ilb_base_addr)
281 + iounmap(priv->ilb_base_addr);
282 }
283 EXPORT_SYMBOL_GPL(tpm_tis_remove);
284
285 +/**
286 + * tpm_tis_clkrun_enable() - Keep clkrun protocol disabled for entire duration
287 + * of a single TPM command
288 + * @chip: TPM chip to use
289 + * @value: 1 - Disable CLKRUN protocol, so that clocks are free running
290 + * 0 - Enable CLKRUN protocol
291 + * Call this function directly in tpm_tis_remove() in error or driver removal
292 + * path, since the chip->ops is set to NULL in tpm_chip_unregister().
293 + */
294 +static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value)
295 +{
296 + struct tpm_tis_data *data = dev_get_drvdata(&chip->dev);
297 + u32 clkrun_val;
298 +
299 + if (!IS_ENABLED(CONFIG_X86) || !is_bsw())
300 + return;
301 +
302 + if (value) {
303 + data->flags |= TPM_TIS_CLK_ENABLE;
304 + data->clkrun_enabled++;
305 + if (data->clkrun_enabled > 1)
306 + return;
307 + clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
308 +
309 + /* Disable LPC CLKRUN# */
310 + clkrun_val &= ~LPC_CLKRUN_EN;
311 + iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
312 +
313 + /*
314 + * Write any random value on port 0x80 which is on LPC, to make
315 + * sure LPC clock is running before sending any TPM command.
316 + */
317 + outb(0xCC, 0x80);
318 + } else {
319 + data->clkrun_enabled--;
320 + if (data->clkrun_enabled)
321 + return;
322 +
323 + clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
324 +
325 + /* Enable LPC CLKRUN# */
326 + clkrun_val |= LPC_CLKRUN_EN;
327 + iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
328 +
329 + /*
330 + * Write any random value on port 0x80 which is on LPC, to make
331 + * sure LPC clock is running before sending any TPM command.
332 + */
333 + outb(0xCC, 0x80);
334 + data->flags &= ~TPM_TIS_CLK_ENABLE;
335 + }
336 +}
337 +
338 static const struct tpm_class_ops tpm_tis = {
339 .flags = TPM_OPS_AUTO_STARTUP,
340 .status = tpm_tis_status,
341 @@ -674,6 +745,7 @@ static const struct tpm_class_ops tpm_ti
342 .req_canceled = tpm_tis_req_canceled,
343 .request_locality = request_locality,
344 .relinquish_locality = release_locality,
345 + .clk_enable = tpm_tis_clkrun_enable,
346 };
347
348 int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
349 @@ -708,6 +780,9 @@ int tpm_tis_core_init(struct device *dev
350 return -ENOMEM;
351 }
352
353 + if (chip->ops->clk_enable != NULL)
354 + chip->ops->clk_enable(chip, true);
355 +
356 if (wait_startup(chip, 0) != 0) {
357 rc = -ENODEV;
358 goto out_err;
359 @@ -799,14 +874,18 @@ int tpm_tis_core_init(struct device *dev
360 }
361
362 rc = tpm_chip_register(chip);
363 - if (rc && is_bsw())
364 - iounmap(priv->ilb_base_addr);
365 + if (rc)
366 + goto out_err;
367
368 - return rc;
369 + if (chip->ops->clk_enable != NULL)
370 + chip->ops->clk_enable(chip, false);
371 +
372 + return 0;
373 out_err:
374 + if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL))
375 + chip->ops->clk_enable(chip, false);
376 +
377 tpm_tis_remove(chip);
378 - if (is_bsw())
379 - iounmap(priv->ilb_base_addr);
380
381 return rc;
382 }
383 @@ -819,22 +898,31 @@ static void tpm_tis_reenable_interrupts(
384 u32 intmask;
385 int rc;
386
387 + if (chip->ops->clk_enable != NULL)
388 + chip->ops->clk_enable(chip, true);
389 +
390 /* reenable interrupts that device may have lost or
391 * BIOS/firmware may have disabled
392 */
393 rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq);
394 if (rc < 0)
395 - return;
396 + goto out;
397
398 rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
399 if (rc < 0)
400 - return;
401 + goto out;
402
403 intmask |= TPM_INTF_CMD_READY_INT
404 | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
405 | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
406
407 tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
408 +
409 +out:
410 + if (chip->ops->clk_enable != NULL)
411 + chip->ops->clk_enable(chip, false);
412 +
413 + return;
414 }
415
416 int tpm_tis_resume(struct device *dev)
417 --- a/drivers/char/tpm/tpm_tis_core.h
418 +++ b/drivers/char/tpm/tpm_tis_core.h
419 @@ -79,11 +79,14 @@ enum tis_defaults {
420 #define TPM_DID_VID(l) (0x0F00 | ((l) << 12))
421 #define TPM_RID(l) (0x0F04 | ((l) << 12))
422
423 +#define LPC_CNTRL_OFFSET 0x84
424 +#define LPC_CLKRUN_EN (1 << 2)
425 #define INTEL_LEGACY_BLK_BASE_ADDR 0xFED08000
426 #define ILB_REMAP_SIZE 0x100
427
428 enum tpm_tis_flags {
429 TPM_TIS_ITPM_WORKAROUND = BIT(0),
430 + TPM_TIS_CLK_ENABLE = BIT(1),
431 };
432
433 struct tpm_tis_data {
434 @@ -93,6 +96,7 @@ struct tpm_tis_data {
435 bool irq_tested;
436 unsigned int flags;
437 void __iomem *ilb_base_addr;
438 + u16 clkrun_enabled;
439 wait_queue_head_t int_queue;
440 wait_queue_head_t read_queue;
441 const struct tpm_tis_phy_ops *phy_ops;
442 --- a/include/linux/tpm.h
443 +++ b/include/linux/tpm.h
444 @@ -50,6 +50,7 @@ struct tpm_class_ops {
445 unsigned long *timeout_cap);
446 int (*request_locality)(struct tpm_chip *chip, int loc);
447 void (*relinquish_locality)(struct tpm_chip *chip, int loc);
448 + void (*clk_enable)(struct tpm_chip *chip, bool value);
449 };
450
451 #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)