|
34 | 34 | #include <asm/cpufeature.h>
|
35 | 35 | #include <asm/debug-monitors.h>
|
36 | 36 | #include <asm/fpsimd.h>
|
| 37 | +#include <asm/gcs.h> |
37 | 38 | #include <asm/mte.h>
|
38 | 39 | #include <asm/pointer_auth.h>
|
39 | 40 | #include <asm/stacktrace.h>
|
@@ -1473,6 +1474,52 @@ static int poe_set(struct task_struct *target, const struct
|
1473 | 1474 | }
|
1474 | 1475 | #endif
|
1475 | 1476 |
|
| 1477 | +#ifdef CONFIG_ARM64_GCS |
| 1478 | +static int gcs_get(struct task_struct *target, |
| 1479 | + const struct user_regset *regset, |
| 1480 | + struct membuf to) |
| 1481 | +{ |
| 1482 | + struct user_gcs user_gcs; |
| 1483 | + |
| 1484 | + if (!system_supports_gcs()) |
| 1485 | + return -EINVAL; |
| 1486 | + |
| 1487 | + if (target == current) |
| 1488 | + gcs_preserve_current_state(); |
| 1489 | + |
| 1490 | + user_gcs.features_enabled = target->thread.gcs_el0_mode; |
| 1491 | + user_gcs.features_locked = target->thread.gcs_el0_locked; |
| 1492 | + user_gcs.gcspr_el0 = target->thread.gcspr_el0; |
| 1493 | + |
| 1494 | + return membuf_write(&to, &user_gcs, sizeof(user_gcs)); |
| 1495 | +} |
| 1496 | + |
| 1497 | +static int gcs_set(struct task_struct *target, const struct |
| 1498 | + user_regset *regset, unsigned int pos, |
| 1499 | + unsigned int count, const void *kbuf, const |
| 1500 | + void __user *ubuf) |
| 1501 | +{ |
| 1502 | + int ret; |
| 1503 | + struct user_gcs user_gcs; |
| 1504 | + |
| 1505 | + if (!system_supports_gcs()) |
| 1506 | + return -EINVAL; |
| 1507 | + |
| 1508 | + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_gcs, 0, -1); |
| 1509 | + if (ret) |
| 1510 | + return ret; |
| 1511 | + |
| 1512 | + if (user_gcs.features_enabled & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK) |
| 1513 | + return -EINVAL; |
| 1514 | + |
| 1515 | + target->thread.gcs_el0_mode = user_gcs.features_enabled; |
| 1516 | + target->thread.gcs_el0_locked = user_gcs.features_locked; |
| 1517 | + target->thread.gcspr_el0 = user_gcs.gcspr_el0; |
| 1518 | + |
| 1519 | + return 0; |
| 1520 | +} |
| 1521 | +#endif |
| 1522 | + |
1476 | 1523 | enum aarch64_regset {
|
1477 | 1524 | REGSET_GPR,
|
1478 | 1525 | REGSET_FPR,
|
@@ -1503,7 +1550,10 @@ enum aarch64_regset {
|
1503 | 1550 | REGSET_TAGGED_ADDR_CTRL,
|
1504 | 1551 | #endif
|
1505 | 1552 | #ifdef CONFIG_ARM64_POE
|
1506 |
| - REGSET_POE |
| 1553 | + REGSET_POE, |
| 1554 | +#endif |
| 1555 | +#ifdef CONFIG_ARM64_GCS |
| 1556 | + REGSET_GCS, |
1507 | 1557 | #endif
|
1508 | 1558 | };
|
1509 | 1559 |
|
@@ -1674,6 +1724,16 @@ static const struct user_regset aarch64_regsets[] = {
|
1674 | 1724 | .set = poe_set,
|
1675 | 1725 | },
|
1676 | 1726 | #endif
|
| 1727 | +#ifdef CONFIG_ARM64_GCS |
| 1728 | + [REGSET_GCS] = { |
| 1729 | + .core_note_type = NT_ARM_GCS, |
| 1730 | + .n = sizeof(struct user_gcs) / sizeof(u64), |
| 1731 | + .size = sizeof(u64), |
| 1732 | + .align = sizeof(u64), |
| 1733 | + .regset_get = gcs_get, |
| 1734 | + .set = gcs_set, |
| 1735 | + }, |
| 1736 | +#endif |
1677 | 1737 | };
|
1678 | 1738 |
|
1679 | 1739 | static const struct user_regset_view user_aarch64_view = {
|
|
0 commit comments