1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk}) 4 * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de) 5 * Copyright (C) 2012-2014 Cisco Systems 6 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 7 * Copyright (C) 2019 Intel Corporation 8 */ 9 10 #include <linux/clockchips.h> 11 #include <linux/init.h> 12 #include <linux/interrupt.h> 13 #include <linux/jiffies.h> 14 #include <linux/mm.h> 15 #include <linux/sched.h> 16 #include <linux/spinlock.h> 17 #include <linux/threads.h> 18 #include <asm/irq.h> 19 #include <asm/param.h> 20 #include <kern_util.h> 21 #include <os.h> 22 #include <linux/delay.h> 23 #include <linux/time-internal.h> 24 #include <linux/um_timetravel.h> 25 #include <shared/init.h> 26 27 #ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT 28 enum time_travel_mode time_travel_mode; 29 EXPORT_SYMBOL_GPL(time_travel_mode); 30 31 static bool time_travel_start_set; 32 static unsigned long long time_travel_start; 33 static unsigned long long time_travel_time; 34 static unsigned long long time_travel_shm_offset; 35 static LIST_HEAD(time_travel_events); 36 static LIST_HEAD(time_travel_irqs); 37 static unsigned long long time_travel_timer_interval; 38 static unsigned long long time_travel_next_event; 39 static struct time_travel_event time_travel_timer_event; 40 static int time_travel_ext_fd = -1; 41 static unsigned int time_travel_ext_waiting; 42 static bool time_travel_ext_prev_request_valid; 43 static unsigned long long time_travel_ext_prev_request; 44 static unsigned long long *time_travel_ext_free_until; 45 static unsigned long long _time_travel_ext_free_until; 46 static u16 time_travel_shm_id; 47 static struct um_timetravel_schedshm *time_travel_shm; 48 static union um_timetravel_schedshm_client *time_travel_shm_client; 49 50 static void time_travel_set_time(unsigned long long ns) 51 { 52 if (unlikely(ns < time_travel_time)) 53 panic("time-travel: time goes backwards %lld -> %lld\n", 54 time_travel_time, ns); 55 else if (unlikely(ns >= S64_MAX)) 56 panic("The system was going to sleep forever, aborting"); 57 58 time_travel_time = ns; 59 } 60 61 enum time_travel_message_handling { 62 TTMH_IDLE, 63 TTMH_POLL, 64 TTMH_READ, 65 TTMH_READ_START_ACK, 66 }; 67 68 static u64 bc_message; 69 int time_travel_should_print_bc_msg; 70 71 void _time_travel_print_bc_msg(void) 72 { 73 time_travel_should_print_bc_msg = 0; 74 printk(KERN_INFO "time-travel: received broadcast 0x%llx\n", bc_message); 75 } 76 77 static void time_travel_setup_shm(int fd, u16 id) 78 { 79 u32 len; 80 81 time_travel_shm = os_mmap_rw_shared(fd, sizeof(*time_travel_shm)); 82 83 if (!time_travel_shm) 84 goto out; 85 86 len = time_travel_shm->len; 87 88 if (time_travel_shm->version != UM_TIMETRAVEL_SCHEDSHM_VERSION || 89 len < struct_size(time_travel_shm, clients, id + 1)) { 90 os_unmap_memory(time_travel_shm, sizeof(*time_travel_shm)); 91 time_travel_shm = NULL; 92 goto out; 93 } 94 95 time_travel_shm = os_mremap_rw_shared(time_travel_shm, 96 sizeof(*time_travel_shm), 97 len); 98 if (!time_travel_shm) 99 goto out; 100 101 time_travel_shm_offset = time_travel_shm->current_time; 102 time_travel_shm_client = &time_travel_shm->clients[id]; 103 time_travel_shm_client->capa |= UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE; 104 time_travel_shm_id = id; 105 /* always look at that free_until from now on */ 106 time_travel_ext_free_until = &time_travel_shm->free_until; 107 out: 108 os_close_file(fd); 109 } 110 111 static void time_travel_handle_message(struct um_timetravel_msg *msg, 112 enum time_travel_message_handling mode) 113 { 114 struct um_timetravel_msg resp = { 115 .op = UM_TIMETRAVEL_ACK, 116 }; 117 int ret; 118 119 /* 120 * We can't unlock here, but interrupt signals with a timetravel_handler 121 * (see um_request_irq_tt) get to the timetravel_handler anyway. 122 */ 123 if (mode != TTMH_READ) { 124 BUG_ON(mode == TTMH_IDLE && !irqs_disabled()); 125 126 while (os_poll(1, &time_travel_ext_fd) != 0) { 127 /* nothing */ 128 } 129 } 130 131 if (unlikely(mode == TTMH_READ_START_ACK)) { 132 int fd[UM_TIMETRAVEL_SHARED_MAX_FDS]; 133 134 ret = os_rcv_fd_msg(time_travel_ext_fd, fd, 135 ARRAY_SIZE(fd), msg, sizeof(*msg)); 136 if (ret == sizeof(*msg)) { 137 time_travel_setup_shm(fd[UM_TIMETRAVEL_SHARED_MEMFD], 138 msg->time & UM_TIMETRAVEL_START_ACK_ID); 139 /* we don't use the logging for now */ 140 os_close_file(fd[UM_TIMETRAVEL_SHARED_LOGFD]); 141 } 142 } else { 143 ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg)); 144 } 145 146 if (ret == 0) 147 panic("time-travel external link is broken\n"); 148 if (ret != sizeof(*msg)) 149 panic("invalid time-travel message - %d bytes\n", ret); 150 151 switch (msg->op) { 152 default: 153 WARN_ONCE(1, "time-travel: unexpected message %lld\n", 154 (unsigned long long)msg->op); 155 break; 156 case UM_TIMETRAVEL_ACK: 157 return; 158 case UM_TIMETRAVEL_RUN: 159 time_travel_set_time(msg->time); 160 if (time_travel_shm) { 161 /* no request right now since we're running */ 162 time_travel_shm_client->flags &= 163 ~UM_TIMETRAVEL_SCHEDSHM_FLAGS_REQ_RUN; 164 /* no ack for shared memory RUN */ 165 return; 166 } 167 break; 168 case UM_TIMETRAVEL_FREE_UNTIL: 169 /* not supposed to get this with shm, but ignore it */ 170 if (time_travel_shm) 171 break; 172 time_travel_ext_free_until = &_time_travel_ext_free_until; 173 _time_travel_ext_free_until = msg->time; 174 break; 175 case UM_TIMETRAVEL_BROADCAST: 176 bc_message = msg->time; 177 time_travel_should_print_bc_msg = 1; 178 break; 179 } 180 181 resp.seq = msg->seq; 182 os_write_file(time_travel_ext_fd, &resp, sizeof(resp)); 183 } 184 185 static u64 time_travel_ext_req(u32 op, u64 time) 186 { 187 static int seq; 188 int mseq = ++seq; 189 struct um_timetravel_msg msg = { 190 .op = op, 191 .time = time, 192 .seq = mseq, 193 }; 194 195 /* 196 * We need to block even the timetravel handlers of SIGIO here and 197 * only restore their use when we got the ACK - otherwise we may 198 * (will) get interrupted by that, try to queue the IRQ for future 199 * processing and thus send another request while we're still waiting 200 * for an ACK, but the peer doesn't know we got interrupted and will 201 * send the ACKs in the same order as the message, but we'd need to 202 * see them in the opposite order ... 203 * 204 * This wouldn't matter *too* much, but some ACKs carry the 205 * current time (for UM_TIMETRAVEL_GET) and getting another 206 * ACK without a time would confuse us a lot! 207 * 208 * The sequence number assignment that happens here lets us 209 * debug such message handling issues more easily. 210 */ 211 block_signals_hard(); 212 os_write_file(time_travel_ext_fd, &msg, sizeof(msg)); 213 214 /* no ACK expected for WAIT in shared memory mode */ 215 if (msg.op == UM_TIMETRAVEL_WAIT && time_travel_shm) 216 goto done; 217 218 while (msg.op != UM_TIMETRAVEL_ACK) 219 time_travel_handle_message(&msg, 220 op == UM_TIMETRAVEL_START ? 221 TTMH_READ_START_ACK : 222 TTMH_READ); 223 224 if (msg.seq != mseq) 225 panic("time-travel: ACK message has different seqno! op=%d, seq=%d != %d time=%lld\n", 226 msg.op, msg.seq, mseq, msg.time); 227 228 if (op == UM_TIMETRAVEL_GET) 229 time_travel_set_time(msg.time); 230 done: 231 unblock_signals_hard(); 232 233 return msg.time; 234 } 235 236 void __time_travel_wait_readable(int fd) 237 { 238 int fds[2] = { fd, time_travel_ext_fd }; 239 int ret; 240 241 if (time_travel_mode != TT_MODE_EXTERNAL) 242 return; 243 244 while ((ret = os_poll(2, fds))) { 245 struct um_timetravel_msg msg; 246 247 if (ret == 1) 248 time_travel_handle_message(&msg, TTMH_READ); 249 } 250 } 251 EXPORT_SYMBOL_GPL(__time_travel_wait_readable); 252 253 static void time_travel_ext_update_request(unsigned long long time) 254 { 255 if (time_travel_mode != TT_MODE_EXTERNAL) 256 return; 257 258 /* asked for exactly this time previously */ 259 if (time_travel_ext_prev_request_valid && 260 time == time_travel_ext_prev_request) 261 return; 262 263 /* 264 * if we're running and are allowed to run past the request 265 * then we don't need to update it either 266 * 267 * Note for shm we ignore FREE_UNTIL messages and leave the pointer 268 * to shared memory, and for non-shm the offset is 0. 269 */ 270 if (!time_travel_ext_waiting && time_travel_ext_free_until && 271 time < (*time_travel_ext_free_until - time_travel_shm_offset)) 272 return; 273 274 time_travel_ext_prev_request = time; 275 time_travel_ext_prev_request_valid = true; 276 277 if (time_travel_shm) { 278 union um_timetravel_schedshm_client *running; 279 280 running = &time_travel_shm->clients[time_travel_shm->running_id]; 281 282 if (running->capa & UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE) { 283 time_travel_shm_client->flags |= 284 UM_TIMETRAVEL_SCHEDSHM_FLAGS_REQ_RUN; 285 time += time_travel_shm_offset; 286 time_travel_shm_client->req_time = time; 287 if (time < time_travel_shm->free_until) 288 time_travel_shm->free_until = time; 289 return; 290 } 291 } 292 293 time_travel_ext_req(UM_TIMETRAVEL_REQUEST, time); 294 } 295 296 void __time_travel_propagate_time(void) 297 { 298 static unsigned long long last_propagated; 299 300 if (time_travel_shm) { 301 if (time_travel_shm->running_id != time_travel_shm_id) 302 panic("time-travel: setting time while not running\n"); 303 time_travel_shm->current_time = time_travel_time + 304 time_travel_shm_offset; 305 return; 306 } 307 308 if (last_propagated == time_travel_time) 309 return; 310 311 time_travel_ext_req(UM_TIMETRAVEL_UPDATE, time_travel_time); 312 last_propagated = time_travel_time; 313 } 314 EXPORT_SYMBOL_GPL(__time_travel_propagate_time); 315 316 /* returns true if we must do a wait to the simtime device */ 317 static bool time_travel_ext_request(unsigned long long time) 318 { 319 /* 320 * If we received an external sync point ("free until") then we 321 * don't have to request/wait for anything until then, unless 322 * we're already waiting. 323 * 324 * Note for shm we ignore FREE_UNTIL messages and leave the pointer 325 * to shared memory, and for non-shm the offset is 0. 326 */ 327 if (!time_travel_ext_waiting && time_travel_ext_free_until && 328 time < (*time_travel_ext_free_until - time_travel_shm_offset)) 329 return false; 330 331 time_travel_ext_update_request(time); 332 return true; 333 } 334 335 static void time_travel_ext_wait(bool idle) 336 { 337 struct um_timetravel_msg msg = { 338 .op = UM_TIMETRAVEL_ACK, 339 }; 340 341 time_travel_ext_prev_request_valid = false; 342 if (!time_travel_shm) 343 time_travel_ext_free_until = NULL; 344 time_travel_ext_waiting++; 345 346 time_travel_ext_req(UM_TIMETRAVEL_WAIT, -1); 347 348 /* 349 * Here we are deep in the idle loop, so we have to break out of the 350 * kernel abstraction in a sense and implement this in terms of the 351 * UML system waiting on the VQ interrupt while sleeping, when we get 352 * the signal it'll call time_travel_ext_vq_notify_done() completing the 353 * call. 354 */ 355 while (msg.op != UM_TIMETRAVEL_RUN) 356 time_travel_handle_message(&msg, idle ? TTMH_IDLE : TTMH_POLL); 357 358 time_travel_ext_waiting--; 359 360 /* we might request more stuff while polling - reset when we run */ 361 time_travel_ext_prev_request_valid = false; 362 } 363 364 static void time_travel_ext_get_time(void) 365 { 366 if (time_travel_shm) 367 time_travel_set_time(time_travel_shm->current_time - 368 time_travel_shm_offset); 369 else 370 time_travel_ext_req(UM_TIMETRAVEL_GET, -1); 371 } 372 373 static void __time_travel_update_time(unsigned long long ns, bool idle) 374 { 375 if (time_travel_mode == TT_MODE_EXTERNAL && time_travel_ext_request(ns)) 376 time_travel_ext_wait(idle); 377 else 378 time_travel_set_time(ns); 379 } 380 381 static struct time_travel_event *time_travel_first_event(void) 382 { 383 return list_first_entry_or_null(&time_travel_events, 384 struct time_travel_event, 385 list); 386 } 387 388 static void __time_travel_add_event(struct time_travel_event *e, 389 unsigned long long time) 390 { 391 struct time_travel_event *tmp; 392 bool inserted = false; 393 unsigned long flags; 394 395 if (e->pending) 396 return; 397 398 e->pending = true; 399 e->time = time; 400 401 local_irq_save(flags); 402 list_for_each_entry(tmp, &time_travel_events, list) { 403 /* 404 * Add the new entry before one with higher time, 405 * or if they're equal and both on stack, because 406 * in that case we need to unwind the stack in the 407 * right order, and the later event (timer sleep 408 * or such) must be dequeued first. 409 */ 410 if ((tmp->time > e->time) || 411 (tmp->time == e->time && tmp->onstack && e->onstack)) { 412 list_add_tail(&e->list, &tmp->list); 413 inserted = true; 414 break; 415 } 416 } 417 418 if (!inserted) 419 list_add_tail(&e->list, &time_travel_events); 420 421 tmp = time_travel_first_event(); 422 time_travel_ext_update_request(tmp->time); 423 time_travel_next_event = tmp->time; 424 local_irq_restore(flags); 425 } 426 427 static void time_travel_add_event(struct time_travel_event *e, 428 unsigned long long time) 429 { 430 if (WARN_ON(!e->fn)) 431 return; 432 433 __time_travel_add_event(e, time); 434 } 435 436 void time_travel_add_event_rel(struct time_travel_event *e, 437 unsigned long long delay_ns) 438 { 439 time_travel_add_event(e, time_travel_time + delay_ns); 440 } 441 442 static void time_travel_periodic_timer(struct time_travel_event *e) 443 { 444 time_travel_add_event(&time_travel_timer_event, 445 time_travel_time + time_travel_timer_interval); 446 deliver_alarm(); 447 } 448 449 void deliver_time_travel_irqs(void) 450 { 451 struct time_travel_event *e; 452 unsigned long flags; 453 454 /* 455 * Don't do anything for most cases. Note that because here we have 456 * to disable IRQs (and re-enable later) we'll actually recurse at 457 * the end of the function, so this is strictly necessary. 458 */ 459 if (likely(list_empty(&time_travel_irqs))) 460 return; 461 462 local_irq_save(flags); 463 irq_enter(); 464 while ((e = list_first_entry_or_null(&time_travel_irqs, 465 struct time_travel_event, 466 list))) { 467 list_del(&e->list); 468 e->pending = false; 469 e->fn(e); 470 } 471 irq_exit(); 472 local_irq_restore(flags); 473 } 474 475 static void time_travel_deliver_event(struct time_travel_event *e) 476 { 477 if (e == &time_travel_timer_event) { 478 /* 479 * deliver_alarm() does the irq_enter/irq_exit 480 * by itself, so must handle it specially here 481 */ 482 e->fn(e); 483 } else if (irqs_disabled()) { 484 list_add_tail(&e->list, &time_travel_irqs); 485 /* 486 * set pending again, it was set to false when the 487 * event was deleted from the original list, but 488 * now it's still pending until we deliver the IRQ. 489 */ 490 e->pending = true; 491 } else { 492 unsigned long flags; 493 494 local_irq_save(flags); 495 irq_enter(); 496 e->fn(e); 497 irq_exit(); 498 local_irq_restore(flags); 499 } 500 } 501 502 bool time_travel_del_event(struct time_travel_event *e) 503 { 504 unsigned long flags; 505 506 if (!e->pending) 507 return false; 508 local_irq_save(flags); 509 list_del(&e->list); 510 e->pending = false; 511 local_irq_restore(flags); 512 return true; 513 } 514 515 static void time_travel_update_time(unsigned long long next, bool idle) 516 { 517 struct time_travel_event ne = { 518 .onstack = true, 519 }; 520 struct time_travel_event *e; 521 bool finished = idle; 522 523 /* add it without a handler - we deal with that specifically below */ 524 __time_travel_add_event(&ne, next); 525 526 do { 527 e = time_travel_first_event(); 528 529 BUG_ON(!e); 530 __time_travel_update_time(e->time, idle); 531 532 /* new events may have been inserted while we were waiting */ 533 if (e == time_travel_first_event()) { 534 BUG_ON(!time_travel_del_event(e)); 535 BUG_ON(time_travel_time != e->time); 536 537 if (e == &ne) { 538 finished = true; 539 } else { 540 if (e->onstack) 541 panic("On-stack event dequeued outside of the stack! time=%lld, event time=%lld, event=%pS\n", 542 time_travel_time, e->time, e); 543 time_travel_deliver_event(e); 544 } 545 } 546 547 e = time_travel_first_event(); 548 if (e) 549 time_travel_ext_update_request(e->time); 550 } while (ne.pending && !finished); 551 552 time_travel_del_event(&ne); 553 } 554 555 static void time_travel_update_time_rel(unsigned long long offs) 556 { 557 unsigned long flags; 558 559 /* 560 * Disable interrupts before calculating the new time so 561 * that a real timer interrupt (signal) can't happen at 562 * a bad time e.g. after we read time_travel_time but 563 * before we've completed updating the time. 564 */ 565 local_irq_save(flags); 566 time_travel_update_time(time_travel_time + offs, false); 567 local_irq_restore(flags); 568 } 569 570 void time_travel_ndelay(unsigned long nsec) 571 { 572 /* 573 * Not strictly needed to use _rel() version since this is 574 * only used in INFCPU/EXT modes, but it doesn't hurt and 575 * is more readable too. 576 */ 577 time_travel_update_time_rel(nsec); 578 } 579 EXPORT_SYMBOL(time_travel_ndelay); 580 581 void time_travel_add_irq_event(struct time_travel_event *e) 582 { 583 BUG_ON(time_travel_mode != TT_MODE_EXTERNAL); 584 585 time_travel_ext_get_time(); 586 /* 587 * We could model interrupt latency here, for now just 588 * don't have any latency at all and request the exact 589 * same time (again) to run the interrupt... 590 */ 591 time_travel_add_event(e, time_travel_time); 592 } 593 EXPORT_SYMBOL_GPL(time_travel_add_irq_event); 594 595 static void time_travel_oneshot_timer(struct time_travel_event *e) 596 { 597 deliver_alarm(); 598 } 599 600 void time_travel_sleep(void) 601 { 602 /* 603 * Wait "forever" (using S64_MAX because there are some potential 604 * wrapping issues, especially with the current TT_MODE_EXTERNAL 605 * controller application. 606 */ 607 unsigned long long next = S64_MAX; 608 609 if (time_travel_mode == TT_MODE_BASIC) 610 os_timer_disable(); 611 612 time_travel_update_time(next, true); 613 614 if (time_travel_mode == TT_MODE_BASIC && 615 time_travel_timer_event.pending) { 616 if (time_travel_timer_event.fn == time_travel_periodic_timer) { 617 /* 618 * This is somewhat wrong - we should get the first 619 * one sooner like the os_timer_one_shot() below... 620 */ 621 os_timer_set_interval(time_travel_timer_interval); 622 } else { 623 os_timer_one_shot(time_travel_timer_event.time - next); 624 } 625 } 626 } 627 628 static void time_travel_handle_real_alarm(void) 629 { 630 time_travel_set_time(time_travel_next_event); 631 632 time_travel_del_event(&time_travel_timer_event); 633 634 if (time_travel_timer_event.fn == time_travel_periodic_timer) 635 time_travel_add_event(&time_travel_timer_event, 636 time_travel_time + 637 time_travel_timer_interval); 638 } 639 640 static void time_travel_set_interval(unsigned long long interval) 641 { 642 time_travel_timer_interval = interval; 643 } 644 645 static int time_travel_connect_external(const char *socket) 646 { 647 const char *sep; 648 unsigned long long id = (unsigned long long)-1; 649 int rc; 650 651 if ((sep = strchr(socket, ':'))) { 652 char buf[25] = {}; 653 if (sep - socket > sizeof(buf) - 1) 654 goto invalid_number; 655 656 memcpy(buf, socket, sep - socket); 657 if (kstrtoull(buf, 0, &id)) { 658 invalid_number: 659 panic("time-travel: invalid external ID in string '%s'\n", 660 socket); 661 return -EINVAL; 662 } 663 664 socket = sep + 1; 665 } 666 667 rc = os_connect_socket(socket); 668 if (rc < 0) { 669 panic("time-travel: failed to connect to external socket %s\n", 670 socket); 671 return rc; 672 } 673 674 time_travel_ext_fd = rc; 675 676 time_travel_ext_req(UM_TIMETRAVEL_START, id); 677 678 return 1; 679 } 680 681 static void time_travel_set_start(void) 682 { 683 if (time_travel_start_set) 684 return; 685 686 switch (time_travel_mode) { 687 case TT_MODE_EXTERNAL: 688 time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); 689 /* controller gave us the *current* time, so adjust by that */ 690 time_travel_ext_get_time(); 691 time_travel_start -= time_travel_time; 692 break; 693 case TT_MODE_INFCPU: 694 case TT_MODE_BASIC: 695 if (!time_travel_start_set) 696 time_travel_start = os_persistent_clock_emulation(); 697 break; 698 case TT_MODE_OFF: 699 /* we just read the host clock with os_persistent_clock_emulation() */ 700 break; 701 } 702 703 time_travel_start_set = true; 704 } 705 #else /* CONFIG_UML_TIME_TRAVEL_SUPPORT */ 706 #define time_travel_start_set 0 707 #define time_travel_start 0 708 #define time_travel_time 0 709 #define time_travel_ext_waiting 0 710 711 static inline void time_travel_update_time(unsigned long long ns, bool idle) 712 { 713 } 714 715 static inline void time_travel_update_time_rel(unsigned long long offs) 716 { 717 } 718 719 static inline void time_travel_handle_real_alarm(void) 720 { 721 } 722 723 static void time_travel_set_interval(unsigned long long interval) 724 { 725 } 726 727 static inline void time_travel_set_start(void) 728 { 729 } 730 731 /* fail link if this actually gets used */ 732 extern u64 time_travel_ext_req(u32 op, u64 time); 733 734 /* these are empty macros so the struct/fn need not exist */ 735 #define time_travel_add_event(e, time) do { } while (0) 736 /* externally not usable - redefine here so we can */ 737 #undef time_travel_del_event 738 #define time_travel_del_event(e) do { } while (0) 739 #endif 740 741 void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) 742 { 743 unsigned long flags; 744 745 /* 746 * In basic time-travel mode we still get real interrupts 747 * (signals) but since we don't read time from the OS, we 748 * must update the simulated time here to the expiry when 749 * we get a signal. 750 * This is not the case in inf-cpu mode, since there we 751 * never get any real signals from the OS. 752 */ 753 if (time_travel_mode == TT_MODE_BASIC) 754 time_travel_handle_real_alarm(); 755 756 local_irq_save(flags); 757 do_IRQ(TIMER_IRQ, regs); 758 local_irq_restore(flags); 759 } 760 761 static int itimer_shutdown(struct clock_event_device *evt) 762 { 763 if (time_travel_mode != TT_MODE_OFF) 764 time_travel_del_event(&time_travel_timer_event); 765 766 if (time_travel_mode != TT_MODE_INFCPU && 767 time_travel_mode != TT_MODE_EXTERNAL) 768 os_timer_disable(); 769 770 return 0; 771 } 772 773 static int itimer_set_periodic(struct clock_event_device *evt) 774 { 775 unsigned long long interval = NSEC_PER_SEC / HZ; 776 777 if (time_travel_mode != TT_MODE_OFF) { 778 time_travel_del_event(&time_travel_timer_event); 779 time_travel_set_event_fn(&time_travel_timer_event, 780 time_travel_periodic_timer); 781 time_travel_set_interval(interval); 782 time_travel_add_event(&time_travel_timer_event, 783 time_travel_time + interval); 784 } 785 786 if (time_travel_mode != TT_MODE_INFCPU && 787 time_travel_mode != TT_MODE_EXTERNAL) 788 os_timer_set_interval(interval); 789 790 return 0; 791 } 792 793 static int itimer_next_event(unsigned long delta, 794 struct clock_event_device *evt) 795 { 796 delta += 1; 797 798 if (time_travel_mode != TT_MODE_OFF) { 799 time_travel_del_event(&time_travel_timer_event); 800 time_travel_set_event_fn(&time_travel_timer_event, 801 time_travel_oneshot_timer); 802 time_travel_add_event(&time_travel_timer_event, 803 time_travel_time + delta); 804 } 805 806 if (time_travel_mode != TT_MODE_INFCPU && 807 time_travel_mode != TT_MODE_EXTERNAL) 808 return os_timer_one_shot(delta); 809 810 return 0; 811 } 812 813 static int itimer_one_shot(struct clock_event_device *evt) 814 { 815 return itimer_next_event(0, evt); 816 } 817 818 static struct clock_event_device timer_clockevent = { 819 .name = "posix-timer", 820 .rating = 250, 821 .cpumask = cpu_possible_mask, 822 .features = CLOCK_EVT_FEAT_PERIODIC | 823 CLOCK_EVT_FEAT_ONESHOT, 824 .set_state_shutdown = itimer_shutdown, 825 .set_state_periodic = itimer_set_periodic, 826 .set_state_oneshot = itimer_one_shot, 827 .set_next_event = itimer_next_event, 828 .shift = 0, 829 .max_delta_ns = 0xffffffff, 830 .max_delta_ticks = 0xffffffff, 831 .min_delta_ns = TIMER_MIN_DELTA, 832 .min_delta_ticks = TIMER_MIN_DELTA, // microsecond resolution should be enough for anyone, same as 640K RAM 833 .irq = 0, 834 .mult = 1, 835 }; 836 837 static irqreturn_t um_timer(int irq, void *dev) 838 { 839 if (get_current()->mm != NULL) 840 { 841 /* userspace - relay signal, results in correct userspace timers */ 842 os_alarm_process(get_current()->mm->context.id.u.pid); 843 } 844 845 (*timer_clockevent.event_handler)(&timer_clockevent); 846 847 return IRQ_HANDLED; 848 } 849 850 static u64 timer_read(struct clocksource *cs) 851 { 852 if (time_travel_mode != TT_MODE_OFF) { 853 /* 854 * We make reading the timer cost a bit so that we don't get 855 * stuck in loops that expect time to move more than the 856 * exact requested sleep amount, e.g. python's socket server, 857 * see https://bugs.python.org/issue37026. 858 * 859 * However, don't do that when we're in interrupt or such as 860 * then we might recurse into our own processing, and get to 861 * even more waiting, and that's not good - it messes up the 862 * "what do I do next" and onstack event we use to know when 863 * to return from time_travel_update_time(). 864 */ 865 if (!irqs_disabled() && !in_interrupt() && !in_softirq() && 866 !time_travel_ext_waiting) 867 time_travel_update_time_rel(TIMER_MULTIPLIER); 868 return time_travel_time / TIMER_MULTIPLIER; 869 } 870 871 return os_nsecs() / TIMER_MULTIPLIER; 872 } 873 874 static struct clocksource timer_clocksource = { 875 .name = "timer", 876 .rating = 300, 877 .read = timer_read, 878 .mask = CLOCKSOURCE_MASK(64), 879 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 880 }; 881 882 static void __init um_timer_setup(void) 883 { 884 int err; 885 886 err = request_irq(TIMER_IRQ, um_timer, IRQF_TIMER, "hr timer", NULL); 887 if (err != 0) 888 printk(KERN_ERR "register_timer : request_irq failed - " 889 "errno = %d\n", -err); 890 891 err = os_timer_create(); 892 if (err != 0) { 893 printk(KERN_ERR "creation of timer failed - errno = %d\n", -err); 894 return; 895 } 896 897 err = clocksource_register_hz(&timer_clocksource, NSEC_PER_SEC/TIMER_MULTIPLIER); 898 if (err) { 899 printk(KERN_ERR "clocksource_register_hz returned %d\n", err); 900 return; 901 } 902 clockevents_register_device(&timer_clockevent); 903 } 904 905 void read_persistent_clock64(struct timespec64 *ts) 906 { 907 long long nsecs; 908 909 time_travel_set_start(); 910 911 if (time_travel_mode != TT_MODE_OFF) 912 nsecs = time_travel_start + time_travel_time; 913 else 914 nsecs = os_persistent_clock_emulation(); 915 916 set_normalized_timespec64(ts, nsecs / NSEC_PER_SEC, 917 nsecs % NSEC_PER_SEC); 918 } 919 920 void __init time_init(void) 921 { 922 timer_set_signal_handler(); 923 late_time_init = um_timer_setup; 924 } 925 926 #ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT 927 unsigned long calibrate_delay_is_known(void) 928 { 929 if (time_travel_mode == TT_MODE_INFCPU || 930 time_travel_mode == TT_MODE_EXTERNAL) 931 return 1; 932 return 0; 933 } 934 935 static int setup_time_travel(char *str) 936 { 937 if (strcmp(str, "=inf-cpu") == 0) { 938 time_travel_mode = TT_MODE_INFCPU; 939 timer_clockevent.name = "time-travel-timer-infcpu"; 940 timer_clocksource.name = "time-travel-clock"; 941 return 1; 942 } 943 944 if (strncmp(str, "=ext:", 5) == 0) { 945 time_travel_mode = TT_MODE_EXTERNAL; 946 timer_clockevent.name = "time-travel-timer-external"; 947 timer_clocksource.name = "time-travel-clock-external"; 948 return time_travel_connect_external(str + 5); 949 } 950 951 if (!*str) { 952 time_travel_mode = TT_MODE_BASIC; 953 timer_clockevent.name = "time-travel-timer"; 954 timer_clocksource.name = "time-travel-clock"; 955 return 1; 956 } 957 958 return -EINVAL; 959 } 960 961 __setup("time-travel", setup_time_travel); 962 __uml_help(setup_time_travel, 963 "time-travel\n" 964 "This option just enables basic time travel mode, in which the clock/timers\n" 965 "inside the UML instance skip forward when there's nothing to do, rather than\n" 966 "waiting for real time to elapse. However, instance CPU speed is limited by\n" 967 "the real CPU speed, so e.g. a 10ms timer will always fire after ~10ms wall\n" 968 "clock (but quicker when there's nothing to do).\n" 969 "\n" 970 "time-travel=inf-cpu\n" 971 "This enables time travel mode with infinite processing power, in which there\n" 972 "are no wall clock timers, and any CPU processing happens - as seen from the\n" 973 "guest - instantly. This can be useful for accurate simulation regardless of\n" 974 "debug overhead, physical CPU speed, etc. but is somewhat dangerous as it can\n" 975 "easily lead to getting stuck (e.g. if anything in the system busy loops).\n" 976 "\n" 977 "time-travel=ext:[ID:]/path/to/socket\n" 978 "This enables time travel mode similar to =inf-cpu, except the system will\n" 979 "use the given socket to coordinate with a central scheduler, in order to\n" 980 "have more than one system simultaneously be on simulated time. The virtio\n" 981 "driver code in UML knows about this so you can also simulate networks and\n" 982 "devices using it, assuming the device has the right capabilities.\n" 983 "The optional ID is a 64-bit integer that's sent to the central scheduler.\n"); 984 985 static int setup_time_travel_start(char *str) 986 { 987 int err; 988 989 err = kstrtoull(str, 0, &time_travel_start); 990 if (err) 991 return err; 992 993 time_travel_start_set = 1; 994 return 1; 995 } 996 997 __setup("time-travel-start=", setup_time_travel_start); 998 __uml_help(setup_time_travel_start, 999 "time-travel-start=<nanoseconds>\n" 1000 "Configure the UML instance's wall clock to start at this value rather than\n" 1001 "the host's wall clock at the time of UML boot.\n"); 1002 static struct kobject *bc_time_kobject; 1003 1004 static ssize_t bc_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 1005 { 1006 return sprintf(buf, "0x%llx", bc_message); 1007 } 1008 1009 static ssize_t bc_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) 1010 { 1011 int ret; 1012 u64 user_bc_message; 1013 1014 ret = kstrtou64(buf, 0, &user_bc_message); 1015 if (ret) 1016 return ret; 1017 1018 bc_message = user_bc_message; 1019 1020 time_travel_ext_req(UM_TIMETRAVEL_BROADCAST, bc_message); 1021 pr_info("um: time: sent broadcast message: 0x%llx\n", bc_message); 1022 return count; 1023 } 1024 1025 static struct kobj_attribute bc_attribute = __ATTR(bc-message, 0660, bc_show, bc_store); 1026 1027 static int __init um_bc_start(void) 1028 { 1029 if (time_travel_mode != TT_MODE_EXTERNAL) 1030 return 0; 1031 1032 bc_time_kobject = kobject_create_and_add("um-ext-time", kernel_kobj); 1033 if (!bc_time_kobject) 1034 return 0; 1035 1036 if (sysfs_create_file(bc_time_kobject, &bc_attribute.attr)) 1037 pr_debug("failed to create the bc file in /sys/kernel/um_time"); 1038 1039 return 0; 1040 } 1041 late_initcall(um_bc_start); 1042 #endif 1043
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.