Serialize TPM 1.2 commands, character-device methods, and power transitions with an sx lock, following the command ownership model used by the TPM 2.0 driver. Reject new operations once detach starts and drain the character device before releasing transport resources. Giant also closed the interrupt race between the final TIS status check and tsleep. Replace that implicit dependency with a mutex and condition variable, use an absolute deadline across unrelated wakeups, and make the interrupt handler MPSAFE. Create the device node atomically with its softc and finish failed write transactions so every command path releases its transport state. The polling path was validated on ThinkPad T430 and T440p systems with their STMicro TPM 1.2 devices enabled. Exclusive-open behavior, 100 consecutive PCR reads, and module unload and reload completed without errors on both systems. Two consecutive S3 cycles on each system preserved PCR values and command access, including another 100 PCR reads after resume, without lock or TPM diagnostics. MFC after: 2 weeks
Details
Details
Diff Detail
Diff Detail
- Lint
Lint Skipped - Unit
Tests Skipped
Event Timeline
| sys/dev/tpm/tpm.c | ||
|---|---|---|
| 796 | I nkow that this matches the pre-existing behavior, but what if we didn't get the desired mask? Given the transaction-ish model of the chip I imagine there's no use in waiting any more, but Is rv == 0 actually what we want? | |
| sys/dev/tpm/tpm.c | ||
|---|---|---|
| 796 | rv == 0 only means the CV was awakened. The interrupt is a hint, so the status must be rechecked and the wait continued after an unrelated wake. Success is returned only once the requested mask is observed. The absolute deadline bounds repeated wakeups so otherwise the timeout or signal error is preserved. Note most TPMs seem to not use IRQs (and I think OpenBSD deleted the mode) so this is just my interpretation. | |
| sys/dev/tpm/tpm.c | ||
|---|---|---|
| 796 | Yes, sorry, I EDOOFUS'd here | |