summaryrefslogtreecommitdiff
path: root/drivers/char/tpm/tpm-chip.c
AgeCommit message (Collapse)Author
2016-07-19tpm: Factor out common startup codeJason Gunthorpe
The TCG standard startup sequence (get timeouts, tpm startup, etc) for TPM and TPM2 chips is being open coded in many drivers, move it into the core code. tpm_tis and tpm_crb are used as the basis for the core code implementation and the easy drivers are converted. In the process several small drivers bugs relating to error handling this flow are fixed. For now the flag TPM_OPS_AUTO_STARTUP is optional to allow a staged driver roll out, but ultimately all drivers should use this flow and the flag removed. Some drivers still do not implement the startup sequence at all and will need to be tested with it enabled. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Tested-by: Andrew Zamansky <andrew.zamansky@nuvoton.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-07-19tpm: use devm_add_action_or_resetSudip Mukherjee
If devm_add_action() fails we are explicitly calling put_device() to free the resources allocated. Lets use the helper devm_add_action_or_reset() and return directly in case of error, as we know that the cleanup function has been already called by the helper if there was any error. Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-06-25tpm: Introduce TPM_CHIP_FLAG_VIRTUALStefan Berger
Introduce TPM_CHIP_FLAG_VIRTUAL to be used when the chip device has no parent device. Prevent sysfs entries requiring a parent device from being created. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-06-25tpm: Remove all uses of drvdata from the TPM CoreJason Gunthorpe
The final thing preventing this was the way the sysfs files were attached to the pdev. Follow the approach developed for ppi and move the sysfs files to the chip->dev with symlinks from the pdev for compatibility. Everything in the core now sanely uses container_of to get the chip. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-06-25tpm: check for TPM_CHIP_FLAG_TPM2 before calling tpm2_shutdown()Jarkko Sakkinen
Fixes: 20e0152393b41 ("tpm: fix crash in tpm_tis deinitialization") Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reported-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Tested-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-By: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
2016-06-25tpm: fix crash in tpm_tis deinitializationJarkko Sakkinen
rmmod crashes the driver because tpm_chip_unregister() already sets ops to NULL. This commit fixes the issue by moving tpm2_shutdown() to tpm_chip_unregister(). This commit is also cleanup because it removes duplicate code from tpm_crb and tpm_tis to the core. Fixes: 4d3eac5e156a ("tpm: Provide strong locking for device removal") Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
2016-06-25tpm: Replace device number bitmap with IDRStefan Berger
Replace the device number bitmap with IDR. Extend the number of devices we can create to 64k. Since an IDR allows us to associate a pointer with an ID, we use this now to rewrite tpm_chip_find_get() to simply look up the chip pointer by the given device ID. Protect the IDR calls with a mutex. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-06-25tpm: Split out the devm stuff from tpmm_chip_allocJason Gunthorpe
tpm_chip_alloc becomes a typical subsystem allocate call. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Tested-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-06-25tpm: Get rid of module lockingStefan Berger
Now that the tpm core has strong locking around 'ops' it is possible to remove a TPM driver, module and all, even while user space still has things like /dev/tpmX open. For consistency and simplicity, drop the module locking entirely. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-06-25tpm: Provide strong locking for device removalJason Gunthorpe
Add a read/write semaphore around the ops function pointers so ops can be set to null when the driver un-registers. Previously the tpm core expected module locking to be enough to ensure that tpm_unregister could not be called during certain times, however that hasn't been sufficient for a long time. Introduce a read/write semaphore around 'ops' so the core can set it to null when unregistering. This provides a strong fence around the driver callbacks, guaranteeing to the driver that no callbacks are running or will run again. For now the ops_lock is placed very high in the call stack, it could be pushed down and made more granular in future if necessary. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-06-25tpm: Get rid of devnameJason Gunthorpe
Now that we have a proper struct device just use dev_name() to access this value instead of keeping two copies. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-06-25tpm: Get rid of chip->pdevJason Gunthorpe
This is a hold over from before the struct device conversion. - All prints should be using &chip->dev, which is the Linux standard. This changes prints to use tpm0 as the device name, not the PnP/etc ID. - The few places involving sysfs/modules that really do need the parent just use chip->dev.parent instead - We no longer need to get_device(pdev) in any places since it is no longer used by any of the code. The kref on the parent is held by the device core during device_add and dropped in device_del Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Tested-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
2016-02-20tpm: fix: return rc when devm_add_action() failsJarkko Sakkinen
Call put_device() and return error code if devm_add_action() fails. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reported-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Fixes: 8e0ee3c9faed ("tpm: fix the cleanup of struct tpm_chip")
2016-02-10tpm: fix the cleanup of struct tpm_chipJarkko Sakkinen
If the initialization fails before tpm_chip_register(), put_device() will be not called, which causes release callback not to be called. This patch fixes the issue by adding put_device() to devres list of the parent device. Fixes: 313d21eeab ("tpm: device class for tpm") Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> cc: stable@vger.kernel.org Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
2016-02-10tpm: fix the rollback in tpm_chip_register()Jarkko Sakkinen
Fixed the rollback and gave more self-documenting names for the functions. Fixes: d972b0523f ("tpm: fix call order in tpm-chip.c") Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> cc: stable@vger.kernel.org Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
2015-11-09tpm: fix compat 'ppi' link handling in tpm_chip_register()Jarkko Sakkinen
__compat_only_sysfs_link_entry_to_kobj() was unconditionally called for TPM1 chips, which caused crash on Acer C720 laptop where DSM for the ACPI object did not exist. There are two reasons for unwanted behavior: * The code did not check whether __compat_only_sysfs_link_entry_to_kobj() returned -ENOENT. This is OK. It just meanst that ppi is not available. * The code did not clean up properly. Compat link should added only after all other init is done. This patch sorts out these issues. Fixes: 9b774d5cf2db Reported-by: Jeremiah Mahler <jmmahler@gmail.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Jeremiah Mahler <jmmahler@gmail.com> Acked-by: Peter Huewe <PeterHuewe@gmx.de>
2015-11-09TPM: revert the list handling logic fixed in 398a1e7Jarkko Sakkinen
Mimi reported that afb5abc reverts the fix in 398a1e7. This patch reverts it back. Fixes: afb5abc262e9 ("tpm: two-phase chip management functions") Reported-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Acked-by: Peter Huewe <PeterHuewe@gmx.de>
2015-10-19tpm: move the PPI attributes to character device directory.Jarkko Sakkinen
Moved PPI attributes to the character device directory. This aligns with the sysfs guidelines and makes them race free because they are created atomically with the character device as part of device_register().The character device and the sysfs attributes appear at the same time to the user space. As part of this change we enable PPI attributes also for TPM 2.0 devices. In order to retain backwards compatibility with TPM 1.x devices, a symlink is created to the platform device directory. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jason Gunthorpe <jason.gunthorpe@obsidianresearch.com> Tested-by: Mimi Zohar <zohar@linux.vnet.ibm.com> (on TPM 1.2) Tested-by: Chris J Arges <chris.j.arges@canonical.com> Tested-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
2015-07-13tpm: Fix initialization of the cdevJason Gunthorpe
When a cdev is contained in a dynamic structure the cdev parent kobj should be set to the kobj that controls the lifetime of the enclosing structure. In TPM's case this is the embedded struct device. Also, cdev_init 0's the whole structure, so all sets must be after, not before. This fixes module ref counting and cdev. Cc: <stable@vger.kernel.org> Fixes: 313d21eeab92 ("tpm: device class for tpm") Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
2015-03-18tpm: fix: sanitized code paths in tpm_chip_register()Jarkko Sakkinen
I started to work with PPI interface so that it would be available under character device sysfs directory and realized that chip registeration was still too messy. In TPM 1.x in some rare scenarios (errors that almost never occur) wrong order in deinitialization steps was taken in teardown. I reproduced these scenarios by manually inserting error codes in the place of the corresponding function calls. The key problem is that the teardown is messy with two separate code paths (this was inherited when moving code from tpm-interface.c). Moved TPM 1.x specific register/unregister functionality to own helper functions and added single code path for teardown in tpm_chip_register(). Now the code paths have been fixed and it should be easier to review later on this part of the code. Cc: <stable@vger.kernel.org> Fixes: 7a1d7e6dd76a ("tpm: TPM 2.0 baseline support") Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Scot Doyle <lkml14@scotdoyle.com> Reviewed-by: Peter Huewe <peterhuewe@gmx.de> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
2015-03-05tpm: fix call order in tpm-chip.cJarkko Sakkinen
- tpm_dev_add_device(): cdev_add() must be done before uevent is propagated in order to avoid races. - tpm_chip_register(): tpm_dev_add_device() must be done as the last step before exposing device to the user space in order to avoid races. In addition clarified description in tpm_chip_register(). Fixes: 313d21eeab92 ("tpm: device class for tpm") Fixes: afb5abc262e9 ("tpm: two-phase chip management functions") Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Peter Huewe <peterhuewe@gmx.de> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
2015-01-20tpm: fix format string error in tpm-chip.cJarkko Sakkinen
dev_set_name() takes three arguments where the second argument is a format string. This patch fixes the call accordingly in tpm-chip.c Reported-by: kbuild test robot <fengguang.wu@intel.com> Fixes: 313d21eeab92 ("tpm: device class for tpm") Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
2015-01-17tpm: TPM 2.0 baseline supportJarkko Sakkinen
TPM 2.0 devices are separated by adding a field 'flags' to struct tpm_chip and defining a flag TPM_CHIP_FLAG_TPM2 for tagging them. This patch adds the following internal functions: - tpm2_get_random() - tpm2_get_tpm_pt() - tpm2_pcr_extend() - tpm2_pcr_read() - tpm2_startup() Additionally, the following exported functions are implemented for implementing TPM 2.0 device drivers: - tpm2_do_selftest() - tpm2_calc_ordinal_durations() - tpm2_gen_interrupt() The existing functions that are exported for the use for existing subsystems have been changed to check the flags field in struct tpm_chip and use appropriate TPM 2.0 counterpart if TPM_CHIP_FLAG_TPM2 is est. The code for tpm2_calc_ordinal_duration() and tpm2_startup() were originally written by Will Arthur. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Will Arthur <will.c.arthur@intel.com> Reviewed-by: Jasob Gunthorpe <jason.gunthorpe@obsidianresearch.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Peter Huewe <peterhuewe@gmx.de> Tested-by: Peter Huewe <peterhuewe@gmx.de> [phuewe: Fixed copy paste error * 2] Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
2015-01-17tpm: device class for tpmJarkko Sakkinen
Added own device class for TPM. Uses MISC_MAJOR:TPM_MINOR for the first character device in order to retain backwards compatibility. Added tpm_dev_release() back attached to the character device. I've been running this code now for a while on my laptop (Lenovo T430S) TrouSerS works perfectly without modifications. I don't believe it breaks anything significantly. The sysfs attributes that have been placed under the wrong place and are against sysfs-rules.txt should be probably left to stagnate under platform device directory and start defining new sysfs attributes to the char device directory. Guidelines for future TPM sysfs attributes should be probably along the lines of - Single flat set of mandatory sysfs attributes. For example, current PPI interface is way way too rich when you only want to use it to clear and activate the TPM. - Define sysfs attribute if and only if there's no way to get the value from ring-3. No attributes for TPM properties. It's just unnecessary maintenance hurdle that we don't want. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jasob Gunthorpe <jason.gunthorpe@obsidianresearch.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Tested-by: Scot Doyle <lkml14@scotdoyle.com> Tested-by: Peter Huewe <peterhuewe@gmx.de> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
2015-01-17tpm: rename chip->dev to chip->pdevJarkko Sakkinen
Rename chip->dev to chip->pdev to make it explicit that this not the character device but actually represents the platform device. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jasob Gunthorpe <jason.gunthorpe@obsidianresearch.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Reviewed-by: Peter Huewe <peterhuewe@gmx.de> Tested-by: Scot Doyle <lkml14@scotdoyle.com> Tested-by: Peter Huewe <peterhuewe@gmx.de> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
2015-01-17tpm: fix raciness of PPI interface lookupJarkko Sakkinen
Traversal of the ACPI device tree was not done right. PPI interface should be looked up only from the ACPI device that is the platform device for the TPM. This could cause problems with systems with two TPM chips such as 4th gen Intel systems. In addition, added the missing license and copyright platter to the tpm_ppi.c. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jasob Gunthorpe <jason.gunthorpe@obsidianresearch.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Tested-by: Scot Doyle <lkml14@scotdoyle.com> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
2015-01-17tpm: two-phase chip management functionsJarkko Sakkinen
tpm_register_hardware() and tpm_remove_hardware() are called often before initializing the device. The problem is that the device might not be fully initialized when it comes visible to the user space. This patch resolves the issue by diving initialization into two parts: - tpmm_chip_alloc() creates struct tpm_chip. - tpm_chip_register() sets up the character device and sysfs attributes. The framework takes care of freeing struct tpm_chip by using the devres API. The broken release callback has been wiped. ACPI drivers do not ever get this callback. Regards to Jason Gunthorpe for carefully reviewing this part of the code. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jasob Gunthorpe <jason.gunthorpe@obsidianresearch.com> Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Tested-by: Scot Doyle <lkml14@scotdoyle.com> Tested-by: Peter Huewe <peterhuewe@gmx.de> [phuewe: update to upstream changes] Signed-off-by: Peter Huewe <peterhuewe@gmx.de>