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 | 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 | 93 | * tpm_chip_start() - power on the TPM |
| 82 | 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 | 102 | int ret; |
| 91 | 103 | |
| 92 | − if (chip->ops->clk_enable) | |
| 93 | − chip->ops->clk_enable(chip, true); | |
| 104 | + tpm_clk_enable(chip); | |
| 94 | 105 | |
| 95 | 106 | if (chip->locality == -1) { |
| 96 | 107 | ret = tpm_request_locality(chip); |
| 97 | 108 | if (ret) { |
| 98 | − chip->ops->clk_enable(chip, false); | |
| 109 | + tpm_clk_disable(chip); | |
| 99 | 110 | return ret; |
| 100 | 111 | } |
| 101 | 112 | } |
| @@ -103,8 +114,7 @@ int tpm_chip_start(struct tpm_chip *chip) · 1 unmodified line | ||
| 103 | 114 | ret = tpm_cmd_ready(chip); |
| 104 | 115 | if (ret) { |
| 105 | 116 | tpm_relinquish_locality(chip); |
| 106 | − if (chip->ops->clk_enable) | |
| 107 | − chip->ops->clk_enable(chip, false); | |
| 117 | + tpm_clk_disable(chip); | |
| 108 | 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 | 135 | tpm_go_idle(chip); |
| 126 | 136 | tpm_relinquish_locality(chip); |
| 127 | − if (chip->ops->clk_enable) | |
| 128 | − chip->ops->clk_enable(chip, false); | |
| 137 | + tpm_clk_disable(chip); | |
| 129 | 138 | } |
| 130 | 139 | EXPORT_SYMBOL_GPL(tpm_chip_stop); |
| 131 | 140 | |