Remove the BKL calls from the TPM driver, which were added in the overall
[deliverable/linux.git] / drivers / char / tpm / tpm.c
index e1fc193d9396fc69c41ecd868fd2bd2d60ff73b7..ceba6082bd968373c0bb926b26c7eae7a99443a1 100644 (file)
@@ -580,91 +580,133 @@ void tpm_continue_selftest(struct tpm_chip *chip)
 }
 EXPORT_SYMBOL_GPL(tpm_continue_selftest);
 
+#define  TPM_INTERNAL_RESULT_SIZE 200
+
 ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
                        char *buf)
 {
-       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
+       u8 *data;
        ssize_t rc;
 
        struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
+       data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
        memcpy(data, tpm_cap, sizeof(tpm_cap));
        data[TPM_CAP_IDX] = TPM_CAP_FLAG;
        data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
 
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attemtping to determine the permanent state");
-       if (rc)
+       rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
+                       "attemtping to determine the permanent enabled state");
+       if (rc) {
+               kfree(data);
                return 0;
-       return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
+       }
+
+       rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
+
+       kfree(data);
+       return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_enabled);
 
 ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
                        char *buf)
 {
-       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
+       u8 *data;
        ssize_t rc;
 
        struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
+       data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
        memcpy(data, tpm_cap, sizeof(tpm_cap));
        data[TPM_CAP_IDX] = TPM_CAP_FLAG;
        data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
 
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attemtping to determine the permanent state");
-       if (rc)
+       rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
+                       "attemtping to determine the permanent active state");
+       if (rc) {
+               kfree(data);
                return 0;
-       return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
+       }
+
+       rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
+
+       kfree(data);
+       return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_active);
 
 ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
                        char *buf)
 {
-       u8 data[sizeof(tpm_cap)];
+       u8 *data;
        ssize_t rc;
 
        struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
+       data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
        memcpy(data, tpm_cap, sizeof(tpm_cap));
        data[TPM_CAP_IDX] = TPM_CAP_PROP;
        data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
 
-       rc = transmit_cmd(chip, data, sizeof(data),
+       rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
                        "attempting to determine the owner state");
-       if (rc)
+       if (rc) {
+               kfree(data);
                return 0;
-       return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
+       }
+
+       rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
+
+       kfree(data);
+       return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_owned);
 
 ssize_t tpm_show_temp_deactivated(struct device * dev,
                                struct device_attribute * attr, char *buf)
 {
-       u8 data[sizeof(tpm_cap)];
+       u8 *data;
        ssize_t rc;
 
        struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
+       data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
        memcpy(data, tpm_cap, sizeof(tpm_cap));
        data[TPM_CAP_IDX] = TPM_CAP_FLAG;
        data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
 
-       rc = transmit_cmd(chip, data, sizeof(data),
+       rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
                        "attempting to determine the temporary state");
-       if (rc)
+       if (rc) {
+               kfree(data);
                return 0;
-       return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
+       }
+
+       rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
+
+       kfree(data);
+       return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
 
@@ -678,7 +720,7 @@ static const u8 pcrread[] = {
 ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
-       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
+       u8 *data;
        ssize_t rc;
        int i, j, num_pcrs;
        __be32 index;
@@ -688,21 +730,27 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
        if (chip == NULL)
                return -ENODEV;
 
+       data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
        memcpy(data, tpm_cap, sizeof(tpm_cap));
        data[TPM_CAP_IDX] = TPM_CAP_PROP;
        data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
 
-       rc = transmit_cmd(chip, data, sizeof(data),
+       rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
                        "attempting to determine the number of PCRS");
-       if (rc)
+       if (rc) {
+               kfree(data);
                return 0;
+       }
 
        num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
        for (i = 0; i < num_pcrs; i++) {
                memcpy(data, pcrread, sizeof(pcrread));
                index = cpu_to_be32(i);
                memcpy(data + 10, &index, 4);
-               rc = transmit_cmd(chip, data, sizeof(data),
+               rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
                                "attempting to read a PCR");
                if (rc)
                        goto out;
@@ -712,6 +760,7 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
                str += sprintf(str, "\n");
        }
 out:
+       kfree(data);
        return str - buf;
 }
 EXPORT_SYMBOL_GPL(tpm_show_pcrs);
@@ -795,7 +844,7 @@ static const u8 cap_version[] = {
 ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
-       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
+       u8 *data;
        ssize_t rc;
        char *str = buf;
 
@@ -803,21 +852,27 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
        if (chip == NULL)
                return -ENODEV;
 
+       data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
        memcpy(data, tpm_cap, sizeof(tpm_cap));
        data[TPM_CAP_IDX] = TPM_CAP_PROP;
        data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
 
-       rc = transmit_cmd(chip, data, sizeof(data),
+       rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
                        "attempting to determine the manufacturer");
-       if (rc)
+       if (rc) {
+               kfree(data);
                return 0;
+       }
 
        str += sprintf(str, "Manufacturer: 0x%x\n",
                       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
 
        memcpy(data, cap_version, sizeof(cap_version));
        data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
-       rc = transmit_cmd(chip, data, sizeof(data),
+       rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
                        "attempting to determine the 1.1 version");
        if (rc)
                goto out;
@@ -828,6 +883,7 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
                       (int) data[17]);
 
 out:
+       kfree(data);
        return str - buf;
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps);
@@ -835,7 +891,7 @@ EXPORT_SYMBOL_GPL(tpm_show_caps);
 ssize_t tpm_show_caps_1_2(struct device * dev,
                          struct device_attribute * attr, char *buf)
 {
-       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
+       u8 *data;
        ssize_t len;
        char *str = buf;
 
@@ -843,15 +899,20 @@ ssize_t tpm_show_caps_1_2(struct device * dev,
        if (chip == NULL)
                return -ENODEV;
 
+       data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
        memcpy(data, tpm_cap, sizeof(tpm_cap));
        data[TPM_CAP_IDX] = TPM_CAP_PROP;
        data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
 
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <=
-           TPM_ERROR_SIZE) {
+       len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
+       if (len <= TPM_ERROR_SIZE) {
                dev_dbg(chip->dev, "A TPM error (%d) occurred "
                        "attempting to determine the manufacturer\n",
                        be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+               kfree(data);
                return 0;
        }
 
@@ -861,8 +922,8 @@ ssize_t tpm_show_caps_1_2(struct device * dev,
        memcpy(data, cap_version, sizeof(cap_version));
        data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
 
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <=
-           TPM_ERROR_SIZE) {
+       len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
+       if (len <= TPM_ERROR_SIZE) {
                dev_err(chip->dev, "A TPM error (%d) occurred "
                        "attempting to determine the 1.2 version\n",
                        be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
@@ -874,6 +935,7 @@ ssize_t tpm_show_caps_1_2(struct device * dev,
                       (int) data[19]);
 
 out:
+       kfree(data);
        return str - buf;
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
@@ -892,13 +954,16 @@ EXPORT_SYMBOL_GPL(tpm_store_cancel);
 
 /*
  * Device file system interface to the TPM
+ *
+ * It's assured that the chip will be opened just once,
+ * by the check of is_open variable, which is protected
+ * by driver_lock.
  */
 int tpm_open(struct inode *inode, struct file *file)
 {
        int rc = 0, minor = iminor(inode);
        struct tpm_chip *chip = NULL, *pos;
 
-       lock_kernel();
        spin_lock(&driver_lock);
 
        list_for_each_entry(pos, &tpm_chip_list, list) {
@@ -928,19 +993,16 @@ int tpm_open(struct inode *inode, struct file *file)
        if (chip->data_buffer == NULL) {
                chip->num_opens--;
                put_device(chip->dev);
-               unlock_kernel();
                return -ENOMEM;
        }
 
        atomic_set(&chip->data_pending, 0);
 
        file->private_data = chip;
-       unlock_kernel();
        return 0;
 
 err_out:
        spin_unlock(&driver_lock);
-       unlock_kernel();
        return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_open);
@@ -966,7 +1028,7 @@ ssize_t tpm_write(struct file *file, const char __user *buf,
                  size_t size, loff_t *off)
 {
        struct tpm_chip *chip = file->private_data;
-       int in_size = size, out_size;
+       size_t in_size = size, out_size;
 
        /* cannot perform a write until the read has cleared
           either via tpm_read or a user_read_timer timeout */
@@ -1001,7 +1063,7 @@ ssize_t tpm_read(struct file *file, char __user *buf,
                 size_t size, loff_t *off)
 {
        struct tpm_chip *chip = file->private_data;
-       int ret_size;
+       ssize_t ret_size;
 
        del_singleshot_timer_sync(&chip->user_read_timer);
        flush_scheduled_work();
This page took 0.029815 seconds and 5 git commands to generate.