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

hostmem-memfd.c (4904B)


      1/*
      2 * QEMU host memfd memory backend
      3 *
      4 * Copyright (C) 2018 Red Hat Inc
      5 *
      6 * Authors:
      7 *   Marc-André Lureau <marcandre.lureau@redhat.com>
      8 *
      9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
     10 * See the COPYING file in the top-level directory.
     11 */
     12
     13#include "qemu/osdep.h"
     14#include "sysemu/hostmem.h"
     15#include "qom/object_interfaces.h"
     16#include "qemu/memfd.h"
     17#include "qemu/module.h"
     18#include "qapi/error.h"
     19#include "qom/object.h"
     20
     21#define TYPE_MEMORY_BACKEND_MEMFD "memory-backend-memfd"
     22
     23OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendMemfd, MEMORY_BACKEND_MEMFD)
     24
     25
     26struct HostMemoryBackendMemfd {
     27    HostMemoryBackend parent_obj;
     28
     29    bool hugetlb;
     30    uint64_t hugetlbsize;
     31    bool seal;
     32};
     33
     34static void
     35memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
     36{
     37    HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(backend);
     38    uint32_t ram_flags;
     39    char *name;
     40    int fd;
     41
     42    if (!backend->size) {
     43        error_setg(errp, "can't create backend with size 0");
     44        return;
     45    }
     46
     47    fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
     48                           m->hugetlb, m->hugetlbsize, m->seal ?
     49                           F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
     50                           errp);
     51    if (fd == -1) {
     52        return;
     53    }
     54
     55    name = host_memory_backend_get_name(backend);
     56    ram_flags = backend->share ? RAM_SHARED : 0;
     57    ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
     58    memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
     59                                   backend->size, ram_flags, fd, 0, errp);
     60    g_free(name);
     61}
     62
     63static bool
     64memfd_backend_get_hugetlb(Object *o, Error **errp)
     65{
     66    return MEMORY_BACKEND_MEMFD(o)->hugetlb;
     67}
     68
     69static void
     70memfd_backend_set_hugetlb(Object *o, bool value, Error **errp)
     71{
     72    MEMORY_BACKEND_MEMFD(o)->hugetlb = value;
     73}
     74
     75static void
     76memfd_backend_set_hugetlbsize(Object *obj, Visitor *v, const char *name,
     77                              void *opaque, Error **errp)
     78{
     79    HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(obj);
     80    uint64_t value;
     81
     82    if (host_memory_backend_mr_inited(MEMORY_BACKEND(obj))) {
     83        error_setg(errp, "cannot change property value");
     84        return;
     85    }
     86
     87    if (!visit_type_size(v, name, &value, errp)) {
     88        return;
     89    }
     90    if (!value) {
     91        error_setg(errp, "Property '%s.%s' doesn't take value '%" PRIu64 "'",
     92                   object_get_typename(obj), name, value);
     93        return;
     94    }
     95    m->hugetlbsize = value;
     96}
     97
     98static void
     99memfd_backend_get_hugetlbsize(Object *obj, Visitor *v, const char *name,
    100                              void *opaque, Error **errp)
    101{
    102    HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(obj);
    103    uint64_t value = m->hugetlbsize;
    104
    105    visit_type_size(v, name, &value, errp);
    106}
    107
    108static bool
    109memfd_backend_get_seal(Object *o, Error **errp)
    110{
    111    return MEMORY_BACKEND_MEMFD(o)->seal;
    112}
    113
    114static void
    115memfd_backend_set_seal(Object *o, bool value, Error **errp)
    116{
    117    MEMORY_BACKEND_MEMFD(o)->seal = value;
    118}
    119
    120static void
    121memfd_backend_instance_init(Object *obj)
    122{
    123    HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(obj);
    124
    125    /* default to sealed file */
    126    m->seal = true;
    127    MEMORY_BACKEND(m)->share = true;
    128}
    129
    130static void
    131memfd_backend_class_init(ObjectClass *oc, void *data)
    132{
    133    HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
    134
    135    bc->alloc = memfd_backend_memory_alloc;
    136
    137    if (qemu_memfd_check(MFD_HUGETLB)) {
    138        object_class_property_add_bool(oc, "hugetlb",
    139                                       memfd_backend_get_hugetlb,
    140                                       memfd_backend_set_hugetlb);
    141        object_class_property_set_description(oc, "hugetlb",
    142                                              "Use huge pages");
    143        object_class_property_add(oc, "hugetlbsize", "int",
    144                                  memfd_backend_get_hugetlbsize,
    145                                  memfd_backend_set_hugetlbsize,
    146                                  NULL, NULL);
    147        object_class_property_set_description(oc, "hugetlbsize",
    148                                              "Huge pages size (ex: 2M, 1G)");
    149    }
    150    object_class_property_add_bool(oc, "seal",
    151                                   memfd_backend_get_seal,
    152                                   memfd_backend_set_seal);
    153    object_class_property_set_description(oc, "seal",
    154                                          "Seal growing & shrinking");
    155}
    156
    157static const TypeInfo memfd_backend_info = {
    158    .name = TYPE_MEMORY_BACKEND_MEMFD,
    159    .parent = TYPE_MEMORY_BACKEND,
    160    .instance_init = memfd_backend_instance_init,
    161    .class_init = memfd_backend_class_init,
    162    .instance_size = sizeof(HostMemoryBackendMemfd),
    163};
    164
    165static void register_types(void)
    166{
    167    if (qemu_memfd_check(MFD_ALLOW_SEALING)) {
    168        type_register_static(&memfd_backend_info);
    169    }
    170}
    171
    172type_init(register_types);