qemu

Форк
0
/
main-loop.c 
653 строки · 16.9 Кб
1
/*
2
 * QEMU System Emulator
3
 *
4
 * Copyright (c) 2003-2008 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

25
#include "qemu/osdep.h"
26
#include "qapi/error.h"
27
#include "qemu/cutils.h"
28
#include "qemu/timer.h"
29
#include "sysemu/cpu-timers.h"
30
#include "sysemu/replay.h"
31
#include "qemu/main-loop.h"
32
#include "block/aio.h"
33
#include "block/thread-pool.h"
34
#include "qemu/error-report.h"
35
#include "qemu/queue.h"
36
#include "qom/object.h"
37

38
#ifndef _WIN32
39
#include <sys/wait.h>
40
#endif
41

42
#ifndef _WIN32
43

44
/* If we have signalfd, we mask out the signals we want to handle and then
45
 * use signalfd to listen for them.  We rely on whatever the current signal
46
 * handler is to dispatch the signals when we receive them.
47
 */
48
/*
49
 * Disable CFI checks.
50
 * We are going to call a signal handler directly. Such handler may or may not
51
 * have been defined in our binary, so there's no guarantee that the pointer
52
 * used to set the handler is a cfi-valid pointer. Since the handlers are
53
 * stored in kernel memory, changing the handler to an attacker-defined
54
 * function requires being able to call a sigaction() syscall,
55
 * which is not as easy as overwriting a pointer in memory.
56
 */
57
QEMU_DISABLE_CFI
58
static void sigfd_handler(void *opaque)
59
{
60
    int fd = (intptr_t)opaque;
61
    struct qemu_signalfd_siginfo info;
62
    struct sigaction action;
63
    ssize_t len;
64

65
    while (1) {
66
        len = RETRY_ON_EINTR(read(fd, &info, sizeof(info)));
67

68
        if (len == -1 && errno == EAGAIN) {
69
            break;
70
        }
71

72
        if (len != sizeof(info)) {
73
            error_report("read from sigfd returned %zd: %s", len,
74
                         g_strerror(errno));
75
            return;
76
        }
77

78
        sigaction(info.ssi_signo, NULL, &action);
79
        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
80
            sigaction_invoke(&action, &info);
81
        } else if (action.sa_handler) {
82
            action.sa_handler(info.ssi_signo);
83
        }
84
    }
85
}
86

87
static int qemu_signal_init(Error **errp)
88
{
89
    int sigfd;
90
    sigset_t set;
91

92
    /*
93
     * SIG_IPI must be blocked in the main thread and must not be caught
94
     * by sigwait() in the signal thread. Otherwise, the cpu thread will
95
     * not catch it reliably.
96
     */
97
    sigemptyset(&set);
98
    sigaddset(&set, SIG_IPI);
99
    sigaddset(&set, SIGIO);
100
    sigaddset(&set, SIGALRM);
101
    sigaddset(&set, SIGBUS);
102
    /* SIGINT cannot be handled via signalfd, so that ^C can be used
103
     * to interrupt QEMU when it is being run under gdb.  SIGHUP and
104
     * SIGTERM are also handled asynchronously, even though it is not
105
     * strictly necessary, because they use the same handler as SIGINT.
106
     */
107
    pthread_sigmask(SIG_BLOCK, &set, NULL);
108

109
    sigdelset(&set, SIG_IPI);
110
    sigfd = qemu_signalfd(&set);
111
    if (sigfd == -1) {
112
        error_setg_errno(errp, errno, "failed to create signalfd");
113
        return -errno;
114
    }
115

116
    g_unix_set_fd_nonblocking(sigfd, true, NULL);
117

118
    qemu_set_fd_handler(sigfd, sigfd_handler, NULL, (void *)(intptr_t)sigfd);
119

120
    return 0;
121
}
122

123
#else /* _WIN32 */
124

125
static int qemu_signal_init(Error **errp)
126
{
127
    return 0;
128
}
129
#endif
130

131
static AioContext *qemu_aio_context;
132
static QEMUBH *qemu_notify_bh;
133

134
static void notify_event_cb(void *opaque)
135
{
136
    /* No need to do anything; this bottom half is only used to
137
     * kick the kernel out of ppoll/poll/WaitForMultipleObjects.
138
     */
139
}
140

141
AioContext *qemu_get_aio_context(void)
142
{
143
    return qemu_aio_context;
144
}
145

146
void qemu_notify_event(void)
147
{
148
    if (!qemu_aio_context) {
149
        return;
150
    }
151
    qemu_bh_schedule(qemu_notify_bh);
152
}
153

154
static GArray *gpollfds;
155

156
int qemu_init_main_loop(Error **errp)
157
{
158
    int ret;
159
    GSource *src;
160

161
    init_clocks(qemu_timer_notify_cb);
162

163
    ret = qemu_signal_init(errp);
164
    if (ret) {
165
        return ret;
166
    }
167

168
    qemu_aio_context = aio_context_new(errp);
169
    if (!qemu_aio_context) {
170
        return -EMFILE;
171
    }
172
    qemu_set_current_aio_context(qemu_aio_context);
173
    qemu_notify_bh = qemu_bh_new(notify_event_cb, NULL);
174
    gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
175
    src = aio_get_g_source(qemu_aio_context);
176
    g_source_set_name(src, "aio-context");
177
    g_source_attach(src, NULL);
178
    g_source_unref(src);
179
    src = iohandler_get_g_source();
180
    g_source_set_name(src, "io-handler");
181
    g_source_attach(src, NULL);
182
    g_source_unref(src);
183
    return 0;
184
}
185

186
static void main_loop_update_params(EventLoopBase *base, Error **errp)
187
{
188
    ERRP_GUARD();
189

190
    if (!qemu_aio_context) {
191
        error_setg(errp, "qemu aio context not ready");
192
        return;
193
    }
194

195
    aio_context_set_aio_params(qemu_aio_context, base->aio_max_batch);
196

197
    aio_context_set_thread_pool_params(qemu_aio_context, base->thread_pool_min,
198
                                       base->thread_pool_max, errp);
199
}
200

201
MainLoop *mloop;
202

203
static void main_loop_init(EventLoopBase *base, Error **errp)
204
{
205
    MainLoop *m = MAIN_LOOP(base);
206

207
    if (mloop) {
208
        error_setg(errp, "only one main-loop instance allowed");
209
        return;
210
    }
211

212
    main_loop_update_params(base, errp);
213

214
    mloop = m;
215
    return;
216
}
217

218
static bool main_loop_can_be_deleted(EventLoopBase *base)
219
{
220
    return false;
221
}
222

223
static void main_loop_class_init(ObjectClass *oc, void *class_data)
224
{
225
    EventLoopBaseClass *bc = EVENT_LOOP_BASE_CLASS(oc);
226

227
    bc->init = main_loop_init;
228
    bc->update_params = main_loop_update_params;
229
    bc->can_be_deleted = main_loop_can_be_deleted;
230
}
231

232
static const TypeInfo main_loop_info = {
233
    .name = TYPE_MAIN_LOOP,
234
    .parent = TYPE_EVENT_LOOP_BASE,
235
    .class_init = main_loop_class_init,
236
    .instance_size = sizeof(MainLoop),
237
};
238

239
static void main_loop_register_types(void)
240
{
241
    type_register_static(&main_loop_info);
242
}
243

244
type_init(main_loop_register_types)
245

246
static int max_priority;
247

248
#ifndef _WIN32
249
static int glib_pollfds_idx;
250
static int glib_n_poll_fds;
251

252
static void glib_pollfds_fill(int64_t *cur_timeout)
253
{
254
    GMainContext *context = g_main_context_default();
255
    int timeout = 0;
256
    int64_t timeout_ns;
257
    int n;
258

259
    g_main_context_prepare(context, &max_priority);
260

261
    glib_pollfds_idx = gpollfds->len;
262
    n = glib_n_poll_fds;
263
    do {
264
        GPollFD *pfds;
265
        glib_n_poll_fds = n;
266
        g_array_set_size(gpollfds, glib_pollfds_idx + glib_n_poll_fds);
267
        pfds = &g_array_index(gpollfds, GPollFD, glib_pollfds_idx);
268
        n = g_main_context_query(context, max_priority, &timeout, pfds,
269
                                 glib_n_poll_fds);
270
    } while (n != glib_n_poll_fds);
271

272
    if (timeout < 0) {
273
        timeout_ns = -1;
274
    } else {
275
        timeout_ns = (int64_t)timeout * (int64_t)SCALE_MS;
276
    }
277

278
    *cur_timeout = qemu_soonest_timeout(timeout_ns, *cur_timeout);
279
}
280

281
static void glib_pollfds_poll(void)
282
{
283
    GMainContext *context = g_main_context_default();
284
    GPollFD *pfds = &g_array_index(gpollfds, GPollFD, glib_pollfds_idx);
285

286
    if (g_main_context_check(context, max_priority, pfds, glib_n_poll_fds)) {
287
        g_main_context_dispatch(context);
288
    }
289
}
290

291
#define MAX_MAIN_LOOP_SPIN (1000)
292

293
static int os_host_main_loop_wait(int64_t timeout)
294
{
295
    GMainContext *context = g_main_context_default();
296
    int ret;
297

298
    g_main_context_acquire(context);
299

300
    glib_pollfds_fill(&timeout);
301

302
    bql_unlock();
303
    replay_mutex_unlock();
304

305
    ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout);
306

307
    replay_mutex_lock();
308
    bql_lock();
309

310
    glib_pollfds_poll();
311

312
    g_main_context_release(context);
313

314
    return ret;
315
}
316
#else
317
/***********************************************************/
318
/* Polling handling */
319

320
typedef struct PollingEntry {
321
    PollingFunc *func;
322
    void *opaque;
323
    struct PollingEntry *next;
324
} PollingEntry;
325

326
static PollingEntry *first_polling_entry;
327

328
int qemu_add_polling_cb(PollingFunc *func, void *opaque)
329
{
330
    PollingEntry **ppe, *pe;
331
    pe = g_new0(PollingEntry, 1);
332
    pe->func = func;
333
    pe->opaque = opaque;
334
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
335
    *ppe = pe;
336
    return 0;
337
}
338

339
void qemu_del_polling_cb(PollingFunc *func, void *opaque)
340
{
341
    PollingEntry **ppe, *pe;
342
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
343
        pe = *ppe;
344
        if (pe->func == func && pe->opaque == opaque) {
345
            *ppe = pe->next;
346
            g_free(pe);
347
            break;
348
        }
349
    }
350
}
351

352
/***********************************************************/
353
/* Wait objects support */
354
typedef struct WaitObjects {
355
    int num;
356
    int revents[MAXIMUM_WAIT_OBJECTS];
357
    HANDLE events[MAXIMUM_WAIT_OBJECTS];
358
    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS];
359
    void *opaque[MAXIMUM_WAIT_OBJECTS];
360
} WaitObjects;
361

362
static WaitObjects wait_objects = {0};
363

364
int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
365
{
366
    int i;
367
    WaitObjects *w = &wait_objects;
368

369
    if (w->num >= MAXIMUM_WAIT_OBJECTS) {
370
        return -1;
371
    }
372

373
    for (i = 0; i < w->num; i++) {
374
        /* check if the same handle is added twice */
375
        if (w->events[i] == handle) {
376
            return -1;
377
        }
378
    }
379

380
    w->events[w->num] = handle;
381
    w->func[w->num] = func;
382
    w->opaque[w->num] = opaque;
383
    w->revents[w->num] = 0;
384
    w->num++;
385
    return 0;
386
}
387

388
void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
389
{
390
    int i, found;
391
    WaitObjects *w = &wait_objects;
392

393
    found = 0;
394
    for (i = 0; i < w->num; i++) {
395
        if (w->events[i] == handle) {
396
            found = 1;
397
        }
398
        if (found && i < (MAXIMUM_WAIT_OBJECTS - 1)) {
399
            w->events[i] = w->events[i + 1];
400
            w->func[i] = w->func[i + 1];
401
            w->opaque[i] = w->opaque[i + 1];
402
            w->revents[i] = w->revents[i + 1];
403
        }
404
    }
405
    if (found) {
406
        w->num--;
407
    }
408
}
409

410
static int pollfds_fill(GArray *pollfds, fd_set *rfds, fd_set *wfds,
411
                        fd_set *xfds)
412
{
413
    int nfds = -1;
414
    int i;
415

416
    for (i = 0; i < pollfds->len; i++) {
417
        GPollFD *pfd = &g_array_index(pollfds, GPollFD, i);
418
        int fd = pfd->fd;
419
        int events = pfd->events;
420
        if (events & G_IO_IN) {
421
            FD_SET(fd, rfds);
422
            nfds = MAX(nfds, fd);
423
        }
424
        if (events & G_IO_OUT) {
425
            FD_SET(fd, wfds);
426
            nfds = MAX(nfds, fd);
427
        }
428
        if (events & G_IO_PRI) {
429
            FD_SET(fd, xfds);
430
            nfds = MAX(nfds, fd);
431
        }
432
    }
433
    return nfds;
434
}
435

436
static void pollfds_poll(GArray *pollfds, int nfds, fd_set *rfds,
437
                         fd_set *wfds, fd_set *xfds)
438
{
439
    int i;
440

441
    for (i = 0; i < pollfds->len; i++) {
442
        GPollFD *pfd = &g_array_index(pollfds, GPollFD, i);
443
        int fd = pfd->fd;
444
        int revents = 0;
445

446
        if (FD_ISSET(fd, rfds)) {
447
            revents |= G_IO_IN;
448
        }
449
        if (FD_ISSET(fd, wfds)) {
450
            revents |= G_IO_OUT;
451
        }
452
        if (FD_ISSET(fd, xfds)) {
453
            revents |= G_IO_PRI;
454
        }
455
        pfd->revents = revents & pfd->events;
456
    }
457
}
458

459
static int os_host_main_loop_wait(int64_t timeout)
460
{
461
    GMainContext *context = g_main_context_default();
462
    GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
463
    int select_ret = 0;
464
    int g_poll_ret, ret, i, n_poll_fds;
465
    PollingEntry *pe;
466
    WaitObjects *w = &wait_objects;
467
    gint poll_timeout;
468
    int64_t poll_timeout_ns;
469
    static struct timeval tv0;
470
    fd_set rfds, wfds, xfds;
471
    int nfds;
472

473
    g_main_context_acquire(context);
474

475
    /* XXX: need to suppress polling by better using win32 events */
476
    ret = 0;
477
    for (pe = first_polling_entry; pe != NULL; pe = pe->next) {
478
        ret |= pe->func(pe->opaque);
479
    }
480
    if (ret != 0) {
481
        g_main_context_release(context);
482
        return ret;
483
    }
484

485
    FD_ZERO(&rfds);
486
    FD_ZERO(&wfds);
487
    FD_ZERO(&xfds);
488
    nfds = pollfds_fill(gpollfds, &rfds, &wfds, &xfds);
489
    if (nfds >= 0) {
490
        select_ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
491
        if (select_ret != 0) {
492
            timeout = 0;
493
        }
494
        if (select_ret > 0) {
495
            pollfds_poll(gpollfds, nfds, &rfds, &wfds, &xfds);
496
        }
497
    }
498

499
    g_main_context_prepare(context, &max_priority);
500
    n_poll_fds = g_main_context_query(context, max_priority, &poll_timeout,
501
                                      poll_fds, ARRAY_SIZE(poll_fds));
502
    g_assert(n_poll_fds + w->num <= ARRAY_SIZE(poll_fds));
503

504
    for (i = 0; i < w->num; i++) {
505
        poll_fds[n_poll_fds + i].fd = (DWORD_PTR)w->events[i];
506
        poll_fds[n_poll_fds + i].events = G_IO_IN;
507
    }
508

509
    if (poll_timeout < 0) {
510
        poll_timeout_ns = -1;
511
    } else {
512
        poll_timeout_ns = (int64_t)poll_timeout * (int64_t)SCALE_MS;
513
    }
514

515
    poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout);
516

517
    bql_unlock();
518

519
    replay_mutex_unlock();
520

521
    g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns);
522

523
    replay_mutex_lock();
524

525
    bql_lock();
526
    if (g_poll_ret > 0) {
527
        for (i = 0; i < w->num; i++) {
528
            w->revents[i] = poll_fds[n_poll_fds + i].revents;
529
        }
530
        for (i = 0; i < w->num; i++) {
531
            if (w->revents[i] && w->func[i]) {
532
                w->func[i](w->opaque[i]);
533
            }
534
        }
535
    }
536

537
    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
538
        g_main_context_dispatch(context);
539
    }
540

541
    g_main_context_release(context);
542

543
    return select_ret || g_poll_ret;
544
}
545
#endif
546

547
static NotifierList main_loop_poll_notifiers =
548
    NOTIFIER_LIST_INITIALIZER(main_loop_poll_notifiers);
549

550
void main_loop_poll_add_notifier(Notifier *notify)
551
{
552
    notifier_list_add(&main_loop_poll_notifiers, notify);
553
}
554

555
void main_loop_poll_remove_notifier(Notifier *notify)
556
{
557
    notifier_remove(notify);
558
}
559

560
void main_loop_wait(int nonblocking)
561
{
562
    MainLoopPoll mlpoll = {
563
        .state = MAIN_LOOP_POLL_FILL,
564
        .timeout = UINT32_MAX,
565
        .pollfds = gpollfds,
566
    };
567
    int ret;
568
    int64_t timeout_ns;
569

570
    if (nonblocking) {
571
        mlpoll.timeout = 0;
572
    }
573

574
    /* poll any events */
575
    g_array_set_size(gpollfds, 0); /* reset for new iteration */
576
    /* XXX: separate device handlers from system ones */
577
    notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);
578

579
    if (mlpoll.timeout == UINT32_MAX) {
580
        timeout_ns = -1;
581
    } else {
582
        timeout_ns = (uint64_t)mlpoll.timeout * (int64_t)(SCALE_MS);
583
    }
584

585
    timeout_ns = qemu_soonest_timeout(timeout_ns,
586
                                      timerlistgroup_deadline_ns(
587
                                          &main_loop_tlg));
588

589
    ret = os_host_main_loop_wait(timeout_ns);
590
    mlpoll.state = ret < 0 ? MAIN_LOOP_POLL_ERR : MAIN_LOOP_POLL_OK;
591
    notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);
592

593
    if (icount_enabled()) {
594
        /*
595
         * CPU thread can infinitely wait for event after
596
         * missing the warp
597
         */
598
        icount_start_warp_timer();
599
    }
600
    qemu_clock_run_all_timers();
601
}
602

603
/* Functions to operate on the main QEMU AioContext.  */
604

605
QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name,
606
                         MemReentrancyGuard *reentrancy_guard)
607
{
608
    return aio_bh_new_full(qemu_aio_context, cb, opaque, name,
609
                           reentrancy_guard);
610
}
611

612
/*
613
 * Functions to operate on the I/O handler AioContext.
614
 * This context runs on top of main loop. We can't reuse qemu_aio_context
615
 * because iohandlers mustn't be polled by aio_poll(qemu_aio_context).
616
 */
617
static AioContext *iohandler_ctx;
618

619
static void iohandler_init(void)
620
{
621
    if (!iohandler_ctx) {
622
        iohandler_ctx = aio_context_new(&error_abort);
623
    }
624
}
625

626
AioContext *iohandler_get_aio_context(void)
627
{
628
    iohandler_init();
629
    return iohandler_ctx;
630
}
631

632
GSource *iohandler_get_g_source(void)
633
{
634
    iohandler_init();
635
    return aio_get_g_source(iohandler_ctx);
636
}
637

638
void qemu_set_fd_handler(int fd,
639
                         IOHandler *fd_read,
640
                         IOHandler *fd_write,
641
                         void *opaque)
642
{
643
    iohandler_init();
644
    aio_set_fd_handler(iohandler_ctx, fd, fd_read, fd_write, NULL, NULL,
645
                       opaque);
646
}
647

648
void event_notifier_set_handler(EventNotifier *e,
649
                                EventNotifierHandler *handler)
650
{
651
    iohandler_init();
652
    aio_set_event_notifier(iohandler_ctx, e, handler, NULL, NULL);
653
}
654

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.