cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

cpus-common.c (10334B)


      1/*
      2 * CPU thread main loop - common bits for user and system mode emulation
      3 *
      4 *  Copyright (c) 2003-2005 Fabrice Bellard
      5 *
      6 * This library is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License as published by the Free Software Foundation; either
      9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * This library is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18 */
     19
     20#include "qemu/osdep.h"
     21#include "qemu/main-loop.h"
     22#include "exec/cpu-common.h"
     23#include "hw/core/cpu.h"
     24#include "sysemu/cpus.h"
     25#include "qemu/lockable.h"
     26
     27static QemuMutex qemu_cpu_list_lock;
     28static QemuCond exclusive_cond;
     29static QemuCond exclusive_resume;
     30static QemuCond qemu_work_cond;
     31
     32/* >= 1 if a thread is inside start_exclusive/end_exclusive.  Written
     33 * under qemu_cpu_list_lock, read with atomic operations.
     34 */
     35static int pending_cpus;
     36
     37void qemu_init_cpu_list(void)
     38{
     39    /* This is needed because qemu_init_cpu_list is also called by the
     40     * child process in a fork.  */
     41    pending_cpus = 0;
     42
     43    qemu_mutex_init(&qemu_cpu_list_lock);
     44    qemu_cond_init(&exclusive_cond);
     45    qemu_cond_init(&exclusive_resume);
     46    qemu_cond_init(&qemu_work_cond);
     47}
     48
     49void cpu_list_lock(void)
     50{
     51    qemu_mutex_lock(&qemu_cpu_list_lock);
     52}
     53
     54void cpu_list_unlock(void)
     55{
     56    qemu_mutex_unlock(&qemu_cpu_list_lock);
     57}
     58
     59static bool cpu_index_auto_assigned;
     60
     61static int cpu_get_free_index(void)
     62{
     63    CPUState *some_cpu;
     64    int max_cpu_index = 0;
     65
     66    cpu_index_auto_assigned = true;
     67    CPU_FOREACH(some_cpu) {
     68        if (some_cpu->cpu_index >= max_cpu_index) {
     69            max_cpu_index = some_cpu->cpu_index + 1;
     70        }
     71    }
     72    return max_cpu_index;
     73}
     74
     75CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
     76
     77void cpu_list_add(CPUState *cpu)
     78{
     79    QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
     80    if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) {
     81        cpu->cpu_index = cpu_get_free_index();
     82        assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX);
     83    } else {
     84        assert(!cpu_index_auto_assigned);
     85    }
     86    QTAILQ_INSERT_TAIL_RCU(&cpus, cpu, node);
     87}
     88
     89void cpu_list_remove(CPUState *cpu)
     90{
     91    QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
     92    if (!QTAILQ_IN_USE(cpu, node)) {
     93        /* there is nothing to undo since cpu_exec_init() hasn't been called */
     94        return;
     95    }
     96
     97    QTAILQ_REMOVE_RCU(&cpus, cpu, node);
     98    cpu->cpu_index = UNASSIGNED_CPU_INDEX;
     99}
    100
    101CPUState *qemu_get_cpu(int index)
    102{
    103    CPUState *cpu;
    104
    105    CPU_FOREACH(cpu) {
    106        if (cpu->cpu_index == index) {
    107            return cpu;
    108        }
    109    }
    110
    111    return NULL;
    112}
    113
    114/* current CPU in the current thread. It is only valid inside cpu_exec() */
    115__thread CPUState *current_cpu;
    116
    117struct qemu_work_item {
    118    QSIMPLEQ_ENTRY(qemu_work_item) node;
    119    run_on_cpu_func func;
    120    run_on_cpu_data data;
    121    bool free, exclusive, done;
    122};
    123
    124static void queue_work_on_cpu(CPUState *cpu, struct qemu_work_item *wi)
    125{
    126    qemu_mutex_lock(&cpu->work_mutex);
    127    QSIMPLEQ_INSERT_TAIL(&cpu->work_list, wi, node);
    128    wi->done = false;
    129    qemu_mutex_unlock(&cpu->work_mutex);
    130
    131    qemu_cpu_kick(cpu);
    132}
    133
    134void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data,
    135                   QemuMutex *mutex)
    136{
    137    struct qemu_work_item wi;
    138
    139    if (qemu_cpu_is_self(cpu)) {
    140        func(cpu, data);
    141        return;
    142    }
    143
    144    wi.func = func;
    145    wi.data = data;
    146    wi.done = false;
    147    wi.free = false;
    148    wi.exclusive = false;
    149
    150    queue_work_on_cpu(cpu, &wi);
    151    while (!qatomic_mb_read(&wi.done)) {
    152        CPUState *self_cpu = current_cpu;
    153
    154        qemu_cond_wait(&qemu_work_cond, mutex);
    155        current_cpu = self_cpu;
    156    }
    157}
    158
    159void async_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
    160{
    161    struct qemu_work_item *wi;
    162
    163    wi = g_malloc0(sizeof(struct qemu_work_item));
    164    wi->func = func;
    165    wi->data = data;
    166    wi->free = true;
    167
    168    queue_work_on_cpu(cpu, wi);
    169}
    170
    171/* Wait for pending exclusive operations to complete.  The CPU list lock
    172   must be held.  */
    173static inline void exclusive_idle(void)
    174{
    175    while (pending_cpus) {
    176        qemu_cond_wait(&exclusive_resume, &qemu_cpu_list_lock);
    177    }
    178}
    179
    180/* Start an exclusive operation.
    181   Must only be called from outside cpu_exec.  */
    182void start_exclusive(void)
    183{
    184    CPUState *other_cpu;
    185    int running_cpus;
    186
    187    qemu_mutex_lock(&qemu_cpu_list_lock);
    188    exclusive_idle();
    189
    190    /* Make all other cpus stop executing.  */
    191    qatomic_set(&pending_cpus, 1);
    192
    193    /* Write pending_cpus before reading other_cpu->running.  */
    194    smp_mb();
    195    running_cpus = 0;
    196    CPU_FOREACH(other_cpu) {
    197        if (qatomic_read(&other_cpu->running)) {
    198            other_cpu->has_waiter = true;
    199            running_cpus++;
    200            qemu_cpu_kick(other_cpu);
    201        }
    202    }
    203
    204    qatomic_set(&pending_cpus, running_cpus + 1);
    205    while (pending_cpus > 1) {
    206        qemu_cond_wait(&exclusive_cond, &qemu_cpu_list_lock);
    207    }
    208
    209    /* Can release mutex, no one will enter another exclusive
    210     * section until end_exclusive resets pending_cpus to 0.
    211     */
    212    qemu_mutex_unlock(&qemu_cpu_list_lock);
    213
    214    current_cpu->in_exclusive_context = true;
    215}
    216
    217/* Finish an exclusive operation.  */
    218void end_exclusive(void)
    219{
    220    current_cpu->in_exclusive_context = false;
    221
    222    qemu_mutex_lock(&qemu_cpu_list_lock);
    223    qatomic_set(&pending_cpus, 0);
    224    qemu_cond_broadcast(&exclusive_resume);
    225    qemu_mutex_unlock(&qemu_cpu_list_lock);
    226}
    227
    228/* Wait for exclusive ops to finish, and begin cpu execution.  */
    229void cpu_exec_start(CPUState *cpu)
    230{
    231    qatomic_set(&cpu->running, true);
    232
    233    /* Write cpu->running before reading pending_cpus.  */
    234    smp_mb();
    235
    236    /* 1. start_exclusive saw cpu->running == true and pending_cpus >= 1.
    237     * After taking the lock we'll see cpu->has_waiter == true and run---not
    238     * for long because start_exclusive kicked us.  cpu_exec_end will
    239     * decrement pending_cpus and signal the waiter.
    240     *
    241     * 2. start_exclusive saw cpu->running == false but pending_cpus >= 1.
    242     * This includes the case when an exclusive item is running now.
    243     * Then we'll see cpu->has_waiter == false and wait for the item to
    244     * complete.
    245     *
    246     * 3. pending_cpus == 0.  Then start_exclusive is definitely going to
    247     * see cpu->running == true, and it will kick the CPU.
    248     */
    249    if (unlikely(qatomic_read(&pending_cpus))) {
    250        QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
    251        if (!cpu->has_waiter) {
    252            /* Not counted in pending_cpus, let the exclusive item
    253             * run.  Since we have the lock, just set cpu->running to true
    254             * while holding it; no need to check pending_cpus again.
    255             */
    256            qatomic_set(&cpu->running, false);
    257            exclusive_idle();
    258            /* Now pending_cpus is zero.  */
    259            qatomic_set(&cpu->running, true);
    260        } else {
    261            /* Counted in pending_cpus, go ahead and release the
    262             * waiter at cpu_exec_end.
    263             */
    264        }
    265    }
    266}
    267
    268/* Mark cpu as not executing, and release pending exclusive ops.  */
    269void cpu_exec_end(CPUState *cpu)
    270{
    271    qatomic_set(&cpu->running, false);
    272
    273    /* Write cpu->running before reading pending_cpus.  */
    274    smp_mb();
    275
    276    /* 1. start_exclusive saw cpu->running == true.  Then it will increment
    277     * pending_cpus and wait for exclusive_cond.  After taking the lock
    278     * we'll see cpu->has_waiter == true.
    279     *
    280     * 2. start_exclusive saw cpu->running == false but here pending_cpus >= 1.
    281     * This includes the case when an exclusive item started after setting
    282     * cpu->running to false and before we read pending_cpus.  Then we'll see
    283     * cpu->has_waiter == false and not touch pending_cpus.  The next call to
    284     * cpu_exec_start will run exclusive_idle if still necessary, thus waiting
    285     * for the item to complete.
    286     *
    287     * 3. pending_cpus == 0.  Then start_exclusive is definitely going to
    288     * see cpu->running == false, and it can ignore this CPU until the
    289     * next cpu_exec_start.
    290     */
    291    if (unlikely(qatomic_read(&pending_cpus))) {
    292        QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
    293        if (cpu->has_waiter) {
    294            cpu->has_waiter = false;
    295            qatomic_set(&pending_cpus, pending_cpus - 1);
    296            if (pending_cpus == 1) {
    297                qemu_cond_signal(&exclusive_cond);
    298            }
    299        }
    300    }
    301}
    302
    303void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func,
    304                           run_on_cpu_data data)
    305{
    306    struct qemu_work_item *wi;
    307
    308    wi = g_malloc0(sizeof(struct qemu_work_item));
    309    wi->func = func;
    310    wi->data = data;
    311    wi->free = true;
    312    wi->exclusive = true;
    313
    314    queue_work_on_cpu(cpu, wi);
    315}
    316
    317void process_queued_cpu_work(CPUState *cpu)
    318{
    319    struct qemu_work_item *wi;
    320
    321    qemu_mutex_lock(&cpu->work_mutex);
    322    if (QSIMPLEQ_EMPTY(&cpu->work_list)) {
    323        qemu_mutex_unlock(&cpu->work_mutex);
    324        return;
    325    }
    326    while (!QSIMPLEQ_EMPTY(&cpu->work_list)) {
    327        wi = QSIMPLEQ_FIRST(&cpu->work_list);
    328        QSIMPLEQ_REMOVE_HEAD(&cpu->work_list, node);
    329        qemu_mutex_unlock(&cpu->work_mutex);
    330        if (wi->exclusive) {
    331            /* Running work items outside the BQL avoids the following deadlock:
    332             * 1) start_exclusive() is called with the BQL taken while another
    333             * CPU is running; 2) cpu_exec in the other CPU tries to takes the
    334             * BQL, so it goes to sleep; start_exclusive() is sleeping too, so
    335             * neither CPU can proceed.
    336             */
    337            qemu_mutex_unlock_iothread();
    338            start_exclusive();
    339            wi->func(cpu, wi->data);
    340            end_exclusive();
    341            qemu_mutex_lock_iothread();
    342        } else {
    343            wi->func(cpu, wi->data);
    344        }
    345        qemu_mutex_lock(&cpu->work_mutex);
    346        if (wi->free) {
    347            g_free(wi);
    348        } else {
    349            qatomic_mb_set(&wi->done, true);
    350        }
    351    }
    352    qemu_mutex_unlock(&cpu->work_mutex);
    353    qemu_cond_broadcast(&qemu_work_cond);
    354}