diff options
| -rw-r--r-- | drivers/acpi/apei/erst.c | 23 | 
1 files changed, 20 insertions, 3 deletions
| diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index a4904f1680cf..35bb2a0a8de6 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
| @@ -266,13 +266,30 @@ static int erst_exec_move_data(struct apei_exec_context *ctx, | |||
| 266 | { | 266 | { | 
| 267 | int rc; | 267 | int rc; | 
| 268 | u64 offset; | 268 | u64 offset; | 
| 269 | void *src, *dst; | ||
| 270 | |||
| 271 | /* ioremap does not work in interrupt context */ | ||
| 272 | if (in_interrupt()) { | ||
| 273 | pr_warning(ERST_PFX | ||
| 274 | "MOVE_DATA can not be used in interrupt context"); | ||
| 275 | return -EBUSY; | ||
| 276 | } | ||
| 269 | 277 | ||
| 270 | rc = __apei_exec_read_register(entry, &offset); | 278 | rc = __apei_exec_read_register(entry, &offset); | 
| 271 | if (rc) | 279 | if (rc) | 
| 272 | return rc; | 280 | return rc; | 
| 273 | memmove((void *)ctx->dst_base + offset, | 281 | |
| 274 | (void *)ctx->src_base + offset, | 282 | src = ioremap(ctx->src_base + offset, ctx->var2); | 
| 275 | ctx->var2); | 283 | if (!src) | 
| 284 | return -ENOMEM; | ||
| 285 | dst = ioremap(ctx->dst_base + offset, ctx->var2); | ||
| 286 | if (!dst) | ||
| 287 | return -ENOMEM; | ||
| 288 | |||
| 289 | memmove(dst, src, ctx->var2); | ||
| 290 | |||
| 291 | iounmap(src); | ||
| 292 | iounmap(dst); | ||
| 276 | 293 | ||
| 277 | return 0; | 294 | return 0; | 
| 278 | } | 295 | } | 
