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

pr-manager.c (3585B)


      1/*
      2 * Persistent reservation manager abstract class
      3 *
      4 * Copyright (c) 2017 Red Hat, Inc.
      5 *
      6 * Author: Paolo Bonzini <pbonzini@redhat.com>
      7 *
      8 * This code is licensed under the LGPL.
      9 *
     10 */
     11
     12#include "qemu/osdep.h"
     13#include <scsi/sg.h>
     14
     15#include "qapi/error.h"
     16#include "block/aio.h"
     17#include "block/thread-pool.h"
     18#include "scsi/pr-manager.h"
     19#include "trace.h"
     20#include "qapi/qapi-types-block.h"
     21#include "qemu/module.h"
     22#include "qapi/qapi-commands-block.h"
     23
     24#define PR_MANAGER_PATH     "/objects"
     25
     26typedef struct PRManagerData {
     27    PRManager *pr_mgr;
     28    struct sg_io_hdr *hdr;
     29    int fd;
     30} PRManagerData;
     31
     32static int pr_manager_worker(void *opaque)
     33{
     34    PRManagerData *data = opaque;
     35    PRManager *pr_mgr = data->pr_mgr;
     36    PRManagerClass *pr_mgr_class =
     37        PR_MANAGER_GET_CLASS(pr_mgr);
     38    struct sg_io_hdr *hdr = data->hdr;
     39    int fd = data->fd;
     40    int r;
     41
     42    trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
     43
     44    /* The reference was taken in pr_manager_execute.  */
     45    r = pr_mgr_class->run(pr_mgr, fd, hdr);
     46    object_unref(OBJECT(pr_mgr));
     47    return r;
     48}
     49
     50
     51int coroutine_fn pr_manager_execute(PRManager *pr_mgr, AioContext *ctx, int fd,
     52                                    struct sg_io_hdr *hdr)
     53{
     54    ThreadPool *pool = aio_get_thread_pool(ctx);
     55    PRManagerData data = {
     56        .pr_mgr = pr_mgr,
     57        .fd     = fd,
     58        .hdr    = hdr,
     59    };
     60
     61    trace_pr_manager_execute(fd, hdr->cmdp[0], hdr->cmdp[1]);
     62
     63    /* The matching object_unref is in pr_manager_worker.  */
     64    object_ref(OBJECT(pr_mgr));
     65    return thread_pool_submit_co(pool, pr_manager_worker, &data);
     66}
     67
     68bool pr_manager_is_connected(PRManager *pr_mgr)
     69{
     70    PRManagerClass *pr_mgr_class =
     71        PR_MANAGER_GET_CLASS(pr_mgr);
     72
     73    return !pr_mgr_class->is_connected || pr_mgr_class->is_connected(pr_mgr);
     74}
     75
     76static const TypeInfo pr_manager_info = {
     77    .parent = TYPE_OBJECT,
     78    .name = TYPE_PR_MANAGER,
     79    .class_size = sizeof(PRManagerClass),
     80    .abstract = true,
     81    .interfaces = (InterfaceInfo[]) {
     82        { TYPE_USER_CREATABLE },
     83        { }
     84    }
     85};
     86
     87PRManager *pr_manager_lookup(const char *id, Error **errp)
     88{
     89    Object *obj;
     90    PRManager *pr_mgr;
     91
     92    obj = object_resolve_path_component(object_get_objects_root(), id);
     93    if (!obj) {
     94        error_setg(errp, "No persistent reservation manager with id '%s'", id);
     95        return NULL;
     96    }
     97
     98    pr_mgr = (PRManager *)
     99        object_dynamic_cast(obj,
    100                            TYPE_PR_MANAGER);
    101    if (!pr_mgr) {
    102        error_setg(errp,
    103                   "Object with id '%s' is not a persistent reservation manager",
    104                   id);
    105        return NULL;
    106    }
    107
    108    return pr_mgr;
    109}
    110
    111static void
    112pr_manager_register_types(void)
    113{
    114    type_register_static(&pr_manager_info);
    115}
    116
    117static int query_one_pr_manager(Object *object, void *opaque)
    118{
    119    PRManagerInfoList ***tail = opaque;
    120    PRManagerInfo *info;
    121    PRManager *pr_mgr;
    122
    123    pr_mgr = (PRManager *)object_dynamic_cast(object, TYPE_PR_MANAGER);
    124    if (!pr_mgr) {
    125        return 0;
    126    }
    127
    128    info = g_new0(PRManagerInfo, 1);
    129    info->id = g_strdup(object_get_canonical_path_component(object));
    130    info->connected = pr_manager_is_connected(pr_mgr);
    131    QAPI_LIST_APPEND(*tail, info);
    132    return 0;
    133}
    134
    135PRManagerInfoList *qmp_query_pr_managers(Error **errp)
    136{
    137    PRManagerInfoList *head = NULL;
    138    PRManagerInfoList **prev = &head;
    139    Object *container = container_get(object_get_root(), PR_MANAGER_PATH);
    140
    141    object_child_foreach(container, query_one_pr_manager, &prev);
    142    return head;
    143}
    144
    145type_init(pr_manager_register_types);