Projects STRLCPY criu Commits 78c4e2c0
🤬
  • ■ ■ ■ ■ ■ ■
    criu/cr-dump.c
    skipped 874 lines
    875 875   return parse_file_locks();
    876 876  }
    877 877   
     878 +static bool task_in_rseq(struct criu_rseq_cs *rseq_cs, uint64_t addr)
     879 +{
     880 + return addr >= rseq_cs->start_ip && addr < rseq_cs->start_ip + rseq_cs->post_commit_offset;
     881 +}
     882 + 
     883 +static int fixup_thread_rseq(struct pstree_item *item, int i)
     884 +{
     885 + CoreEntry *core = item->core[i];
     886 + struct criu_rseq_cs *rseq_cs = &dmpi(item)->thread_rseq_cs[i];
     887 + pid_t tid = item->threads[i].real;
     888 + 
     889 + /* equivalent to (struct rseq)->rseq_cs is NULL */
     890 + if (!rseq_cs->start_ip)
     891 + return 0;
     892 + 
     893 + pr_debug(
     894 + "fixup_thread_rseq for %d: rseq_cs start_ip = %llx abort_ip = %llx post_commit_offset = %llx flags = %x version = %x; IP = %lx\n",
     895 + tid, rseq_cs->start_ip, rseq_cs->abort_ip, rseq_cs->post_commit_offset, rseq_cs->flags,
     896 + rseq_cs->version, (unsigned long)TI_IP(core));
     897 + 
     898 + if (rseq_cs->version != 0) {
     899 + pr_err("unsupported RSEQ ABI version = %d\n", rseq_cs->version);
     900 + return -1;
     901 + }
     902 + 
     903 + if (task_in_rseq(rseq_cs, TI_IP(core))) {
     904 + struct pid *tid = &item->threads[i];
     905 + 
     906 + /*
     907 + * We need to fixup task instruction pointer from
     908 + * the original one (which lays inside rseq critical section)
     909 + * to rseq abort handler address. But we need to look on rseq_cs->flags
     910 + * (please refer to struct rseq -> flags field description).
     911 + * Naive idea of flags support may be like... let's change instruction pointer (IP)
     912 + * to rseq_cs->abort_ip if !(rseq_cs->flags & RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL).
     913 + * But unfortunately, it doesn't work properly, because the kernel does
     914 + * clean up of rseq_cs field in the struct rseq (modifies userspace memory).
     915 + * So, we need to preserve original value of (struct rseq)->rseq_cs field in the
     916 + * image and restore it's value before releasing threads (see restore_rseq_cs()).
     917 + *
     918 + * It's worth to mention that we need to fixup IP in CoreEntry
     919 + * (used when full dump/restore is performed) and also in
     920 + * the parasite regs storage (used if --leave-running option is used,
     921 + * or if dump error occurred and process execution is resumed).
     922 + */
     923 + 
     924 + if (!(rseq_cs->flags & RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL)) {
     925 + pr_warn("The %d task is in rseq critical section. IP will be set to rseq abort handler addr\n",
     926 + tid->real);
     927 + 
     928 + TI_IP(core) = rseq_cs->abort_ip;
     929 + 
     930 + if (item->pid->real == tid->real) {
     931 + compel_set_leader_ip(dmpi(item)->parasite_ctl, rseq_cs->abort_ip);
     932 + } else {
     933 + compel_set_thread_ip(dmpi(item)->thread_ctls[i], rseq_cs->abort_ip);
     934 + }
     935 + }
     936 + }
     937 + 
     938 + return 0;
     939 +}
     940 + 
    878 941  static int dump_task_thread(struct parasite_ctl *parasite_ctl, const struct pstree_item *item, int id)
    879 942  {
    880 943   struct parasite_thread_ctl *tctl = dmpi(item)->thread_ctls[id];
    skipped 301 lines
    1182 1245   xfree(thread_rseq_cs);
    1183 1246   dmpi(item)->thread_rseq_cs = NULL;
    1184 1247   return -1;
    1185  -}
    1186  - 
    1187  -static bool task_in_rseq(struct criu_rseq_cs *rseq_cs, uint64_t addr)
    1188  -{
    1189  - return addr >= rseq_cs->start_ip && addr < rseq_cs->start_ip + rseq_cs->post_commit_offset;
    1190  -}
    1191  - 
    1192  -static int fixup_thread_rseq(struct pstree_item *item, int i)
    1193  -{
    1194  - CoreEntry *core = item->core[i];
    1195  - struct criu_rseq_cs *rseq_cs = &dmpi(item)->thread_rseq_cs[i];
    1196  - pid_t tid = item->threads[i].real;
    1197  - 
    1198  - /* equivalent to (struct rseq)->rseq_cs is NULL */
    1199  - if (!rseq_cs->start_ip)
    1200  - return 0;
    1201  - 
    1202  - pr_debug(
    1203  - "fixup_thread_rseq for %d: rseq_cs start_ip = %llx abort_ip = %llx post_commit_offset = %llx flags = %x version = %x; IP = %lx\n",
    1204  - tid, rseq_cs->start_ip, rseq_cs->abort_ip, rseq_cs->post_commit_offset, rseq_cs->flags,
    1205  - rseq_cs->version, (unsigned long)TI_IP(core));
    1206  - 
    1207  - if (rseq_cs->version != 0) {
    1208  - pr_err("unsupported RSEQ ABI version = %d\n", rseq_cs->version);
    1209  - return -1;
    1210  - }
    1211  - 
    1212  - if (task_in_rseq(rseq_cs, TI_IP(core))) {
    1213  - struct pid *tid = &item->threads[i];
    1214  - 
    1215  - /*
    1216  - * We need to fixup task instruction pointer from
    1217  - * the original one (which lays inside rseq critical section)
    1218  - * to rseq abort handler address. But we need to look on rseq_cs->flags
    1219  - * (please refer to struct rseq -> flags field description).
    1220  - * Naive idea of flags support may be like... let's change instruction pointer (IP)
    1221  - * to rseq_cs->abort_ip if !(rseq_cs->flags & RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL).
    1222  - * But unfortunately, it doesn't work properly, because the kernel does
    1223  - * clean up of rseq_cs field in the struct rseq (modifies userspace memory).
    1224  - * So, we need to preserve original value of (struct rseq)->rseq_cs field in the
    1225  - * image and restore it's value before releasing threads (see restore_rseq_cs()).
    1226  - *
    1227  - * It's worth to mention that we need to fixup IP in CoreEntry
    1228  - * (used when full dump/restore is performed) and also in
    1229  - * the parasite regs storage (used if --leave-running option is used,
    1230  - * or if dump error occurred and process execution is resumed).
    1231  - */
    1232  - 
    1233  - if (!(rseq_cs->flags & RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL)) {
    1234  - pr_warn("The %d task is in rseq critical section. IP will be set to rseq abort handler addr\n",
    1235  - tid->real);
    1236  - 
    1237  - TI_IP(core) = rseq_cs->abort_ip;
    1238  - 
    1239  - if (item->pid->real == tid->real) {
    1240  - compel_set_leader_ip(dmpi(item)->parasite_ctl, rseq_cs->abort_ip);
    1241  - } else {
    1242  - compel_set_thread_ip(dmpi(item)->thread_ctls[i], rseq_cs->abort_ip);
    1243  - }
    1244  - }
    1245  - }
    1246  - 
    1247  - return 0;
    1248 1248  }
    1249 1249   
    1250 1250  static int fixup_task_rseq(pid_t pid, struct pstree_item *item)
    skipped 1048 lines
Please wait...
Page is in error, reload to recover