If clk_enable is not defined and chip initialization is canceled code hits null dereference. Easily reproducible with vTPM init fail: swtpm chardev --tpmstate dir=nonexistent_dir --tpm2 --vtpm-proxy BUG: kernel NULL pointer dereference, address: 00000000 ... Call Trace: tpm_chip_start+0x9d/0xa0 [tpm] tpm_chip_register+0x10/0x1a0 [tpm] vtpm_proxy_work+0x11/0x30 [tpm_vtpm_proxy] process_one_work+0x214/0x5a0 worker_thread+0x134/0x3e0 ? process_one_work+0x5a0/0x5a0 kthread+0xd4/0x100 ? process_one_work+0x5a0/0x5a0 ? kthread_park+0x90/0x90 ret_from_fork+0x19/0x24
Unified · Split
| @@ -77,6 +77,18 @@ static int tpm_go_idle(struct tpm_chip *chip) · 76 unmodified lines | |||
| 77 | return chip->ops->go_idle(chip); | 77 | return chip->ops->go_idle(chip); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static void tpm_clk_enable(struct tpm_chip *chip) | ||
| 81 | { | ||
| 82 | if (chip->ops->clk_enable) | ||
| 83 | chip->ops->clk_enable(chip, true); | ||
| 84 | } | ||
| 85 | |||
| 86 | static void tpm_clk_disable(struct tpm_chip *chip) | ||
| 87 | { | ||
| 88 | if (chip->ops->clk_enable) | ||
| 89 | chip->ops->clk_enable(chip, false); | ||
| 90 | } | ||
| 91 | |||
| 80 | /** | 92 | /** |
| 81 | * tpm_chip_start() - power on the TPM | 93 | * tpm_chip_start() - power on the TPM |
| 82 | * @chip: a TPM chip to use | 94 | * @chip: a TPM chip to use |
| @@ -89,13 +101,12 @@ int tpm_chip_start(struct tpm_chip *chip) · 6 unmodified lines | |||
| 89 | { | 101 | { |
| 90 | int ret; | 102 | int ret; |
| 91 | 103 | ||
| 92 | if (chip->ops->clk_enable) | 104 | tpm_clk_enable(chip); |
| 93 | chip->ops->clk_enable(chip, true); | ||
| 94 | 105 | ||
| 95 | if (chip->locality == -1) { | 106 | if (chip->locality == -1) { |
| 96 | ret = tpm_request_locality(chip); | 107 | ret = tpm_request_locality(chip); |
| 97 | if (ret) { | 108 | if (ret) { |
| 98 | chip->ops->clk_enable(chip, false); | 109 | tpm_clk_disable(chip); |
| 99 | return ret; | 110 | return ret; |
| 100 | } | 111 | } |
| 101 | } | 112 | } |
| @@ -103,8 +114,7 @@ int tpm_chip_start(struct tpm_chip *chip) · 1 unmodified line | |||
| 103 | ret = tpm_cmd_ready(chip); | 114 | ret = tpm_cmd_ready(chip); |
| 104 | if (ret) { | 115 | if (ret) { |
| 105 | tpm_relinquish_locality(chip); | 116 | tpm_relinquish_locality(chip); |
| 106 | if (chip->ops->clk_enable) | 117 | tpm_clk_disable(chip); |
| 107 | chip->ops->clk_enable(chip, false); | ||
| 108 | return ret; | 118 | return ret; |
| 109 | } | 119 | } |
| 110 | 120 | ||
| @@ -124,8 +134,7 @@ void tpm_chip_stop(struct tpm_chip *chip) · 13 unmodified lines | |||
| 124 | { | 134 | { |
| 125 | tpm_go_idle(chip); | 135 | tpm_go_idle(chip); |
| 126 | tpm_relinquish_locality(chip); | 136 | tpm_relinquish_locality(chip); |
| 127 | if (chip->ops->clk_enable) | 137 | tpm_clk_disable(chip); |
| 128 | chip->ops->clk_enable(chip, false); | ||
| 129 | } | 138 | } |
| 130 | EXPORT_SYMBOL_GPL(tpm_chip_stop); | 139 | EXPORT_SYMBOL_GPL(tpm_chip_stop); |
| 131 | 140 | ||