| 1077 | } |
| 1078 | |
| 1079 | int |
| 1080 | npxsetxstate(struct thread *td, char *xfpustate, size_t xfpustate_size) |
| 1081 | { |
| 1082 | struct xstate_hdr *hdr, *ehdr; |
| 1083 | size_t len, max_len; |
| 1084 | uint64_t bv; |
| 1085 | |
| 1086 | /* XXXKIB should we clear all extended state in xstate_bv instead ? */ |
| 1087 | if (xfpustate == NULL) |
| 1088 | return (0); |
| 1089 | if (!use_xsave) |
| 1090 | return (EOPNOTSUPP); |
| 1091 | |
| 1092 | len = xfpustate_size; |
| 1093 | if (len < sizeof(struct xstate_hdr)) |
| 1094 | return (EINVAL); |
| 1095 | max_len = cpu_max_ext_state_size - sizeof(union savefpu); |
| 1096 | if (len > max_len) |
| 1097 | return (EINVAL); |
| 1098 | |
| 1099 | ehdr = (struct xstate_hdr *)xfpustate; |
| 1100 | bv = ehdr->xstate_bv; |
| 1101 | |
| 1102 | /* |
| 1103 | * Avoid #gp. |
| 1104 | */ |
| 1105 | if (bv & ~xsave_mask) |
| 1106 | return (EINVAL); |
| 1107 | |
| 1108 | hdr = (struct xstate_hdr *)(get_pcb_user_save_td(td) + 1); |
| 1109 | |
| 1110 | hdr->xstate_bv = bv; |
| 1111 | bcopy(xfpustate + sizeof(struct xstate_hdr), |
| 1112 | (char *)(hdr + 1), len - sizeof(struct xstate_hdr)); |
| 1113 | |
| 1114 | return (0); |
| 1115 | } |
| 1116 | |
| 1117 | int |
| 1118 | npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate, |
no test coverage detected