Skip to content

Commit 2eadc1b

Browse files
committed
tpm, tpm: Implement usage counter for locality
JIRA: https://issues.redhat.com/browse/RHEL-72765 Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git commit 7a2f55d Author: Lino Sanfilippo <l.sanfilippo@kunbus.com> Date: Thu Nov 24 14:55:33 2022 +0100 tpm, tpm: Implement usage counter for locality Implement a usage counter for the (default) locality used by the TPM TIS driver: Request the locality from the TPM if it has not been claimed yet, otherwise only increment the counter. Also release the locality if the counter is 0 otherwise only decrement the counter. Since in case of SPI the register accesses are locked by means of the SPI bus mutex use a sleepable lock (i.e. also a mutex) to ensure thread-safety of the counter which may be accessed by both a userspace thread and the interrupt handler. By doing this refactor the names of the amended functions to use a more appropriate prefix. Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com> Tested-by: Michael Niewöhner <linux@mniewoehner.de> Tested-by: Jarkko Sakkinen <jarkko@kernel.org> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Štěpán Horáček <shoracek@redhat.com>
1 parent da682c0 commit 2eadc1b

File tree

2 files changed

+47
-18
lines changed

2 files changed

+47
-18
lines changed

drivers/char/tpm/tpm_tis_core.c

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,27 @@ static bool check_locality(struct tpm_chip *chip, int l)
165165
return false;
166166
}
167167

168-
static int release_locality(struct tpm_chip *chip, int l)
168+
static int __tpm_tis_relinquish_locality(struct tpm_tis_data *priv, int l)
169+
{
170+
tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
171+
172+
return 0;
173+
}
174+
175+
static int tpm_tis_relinquish_locality(struct tpm_chip *chip, int l)
169176
{
170177
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
171178

172-
tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
179+
mutex_lock(&priv->locality_count_mutex);
180+
priv->locality_count--;
181+
if (priv->locality_count == 0)
182+
__tpm_tis_relinquish_locality(priv, l);
183+
mutex_unlock(&priv->locality_count_mutex);
173184

174185
return 0;
175186
}
176187

177-
static int request_locality(struct tpm_chip *chip, int l)
188+
static int __tpm_tis_request_locality(struct tpm_chip *chip, int l)
178189
{
179190
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
180191
unsigned long stop, timeout;
@@ -215,6 +226,20 @@ static int request_locality(struct tpm_chip *chip, int l)
215226
return -1;
216227
}
217228

229+
static int tpm_tis_request_locality(struct tpm_chip *chip, int l)
230+
{
231+
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
232+
int ret = 0;
233+
234+
mutex_lock(&priv->locality_count_mutex);
235+
if (priv->locality_count == 0)
236+
ret = __tpm_tis_request_locality(chip, l);
237+
if (!ret)
238+
priv->locality_count++;
239+
mutex_unlock(&priv->locality_count_mutex);
240+
return ret;
241+
}
242+
218243
static u8 tpm_tis_status(struct tpm_chip *chip)
219244
{
220245
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
@@ -668,7 +693,7 @@ static int probe_itpm(struct tpm_chip *chip)
668693
if (vendor != TPM_VID_INTEL)
669694
return 0;
670695

671-
if (request_locality(chip, 0) != 0)
696+
if (tpm_tis_request_locality(chip, 0) != 0)
672697
return -EBUSY;
673698

674699
rc = tpm_tis_send_data(chip, cmd_getticks, len);
@@ -689,7 +714,7 @@ static int probe_itpm(struct tpm_chip *chip)
689714

690715
out:
691716
tpm_tis_ready(chip);
692-
release_locality(chip, priv->locality);
717+
tpm_tis_relinquish_locality(chip, priv->locality);
693718

694719
return rc;
695720
}
@@ -774,14 +799,14 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
774799
}
775800
priv->irq = irq;
776801

777-
rc = request_locality(chip, 0);
802+
rc = tpm_tis_request_locality(chip, 0);
778803
if (rc < 0)
779804
return rc;
780805

781806
rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
782807
&original_int_vec);
783808
if (rc < 0) {
784-
release_locality(chip, priv->locality);
809+
tpm_tis_relinquish_locality(chip, priv->locality);
785810
return rc;
786811
}
787812

@@ -820,7 +845,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
820845
rc = -1;
821846
}
822847

823-
release_locality(chip, priv->locality);
848+
tpm_tis_relinquish_locality(chip, priv->locality);
824849

825850
return rc;
826851
}
@@ -936,8 +961,8 @@ static const struct tpm_class_ops tpm_tis = {
936961
.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
937962
.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
938963
.req_canceled = tpm_tis_req_canceled,
939-
.request_locality = request_locality,
940-
.relinquish_locality = release_locality,
964+
.request_locality = tpm_tis_request_locality,
965+
.relinquish_locality = tpm_tis_relinquish_locality,
941966
.clk_enable = tpm_tis_clkrun_enable,
942967
};
943968

@@ -971,6 +996,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
971996
priv->timeout_min = TPM_TIMEOUT_USECS_MIN;
972997
priv->timeout_max = TPM_TIMEOUT_USECS_MAX;
973998
priv->phy_ops = phy_ops;
999+
priv->locality_count = 0;
1000+
mutex_init(&priv->locality_count_mutex);
9741001

9751002
dev_set_drvdata(&chip->dev, priv);
9761003

@@ -1049,14 +1076,14 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
10491076

10501077
intmask &= ~TPM_GLOBAL_INT_ENABLE;
10511078

1052-
rc = request_locality(chip, 0);
1079+
rc = tpm_tis_request_locality(chip, 0);
10531080
if (rc < 0) {
10541081
rc = -ENODEV;
10551082
goto out_err;
10561083
}
10571084

10581085
tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
1059-
release_locality(chip, 0);
1086+
tpm_tis_relinquish_locality(chip, 0);
10601087

10611088
rc = tpm_chip_start(chip);
10621089
if (rc)
@@ -1095,13 +1122,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
10951122
* proper timeouts for the driver.
10961123
*/
10971124

1098-
rc = request_locality(chip, 0);
1125+
rc = tpm_tis_request_locality(chip, 0);
10991126
if (rc < 0)
11001127
goto out_err;
11011128

11021129
rc = tpm_get_timeouts(chip);
11031130

1104-
release_locality(chip, 0);
1131+
tpm_tis_relinquish_locality(chip, 0);
11051132

11061133
if (rc) {
11071134
dev_err(dev, "Could not get TPM timeouts and durations\n");
@@ -1121,11 +1148,11 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
11211148
dev_err(&chip->dev, FW_BUG
11221149
"TPM interrupt not working, polling instead\n");
11231150

1124-
rc = request_locality(chip, 0);
1151+
rc = tpm_tis_request_locality(chip, 0);
11251152
if (rc < 0)
11261153
goto out_err;
11271154
disable_interrupts(chip);
1128-
release_locality(chip, 0);
1155+
tpm_tis_relinquish_locality(chip, 0);
11291156
}
11301157
}
11311158

@@ -1192,13 +1219,13 @@ int tpm_tis_resume(struct device *dev)
11921219
* an error code but for unknown reason it isn't handled.
11931220
*/
11941221
if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
1195-
ret = request_locality(chip, 0);
1222+
ret = tpm_tis_request_locality(chip, 0);
11961223
if (ret < 0)
11971224
return ret;
11981225

11991226
tpm1_do_selftest(chip);
12001227

1201-
release_locality(chip, 0);
1228+
tpm_tis_relinquish_locality(chip, 0);
12021229
}
12031230

12041231
return 0;

drivers/char/tpm/tpm_tis_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ enum tpm_tis_flags {
9191

9292
struct tpm_tis_data {
9393
u16 manufacturer_id;
94+
struct mutex locality_count_mutex;
95+
unsigned int locality_count;
9496
int locality;
9597
int irq;
9698
unsigned int int_mask;

0 commit comments

Comments
 (0)