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

pef.c (3355B)


      1/*
      2 * PEF (Protected Execution Facility) for POWER support
      3 *
      4 * Copyright Red Hat.
      5 *
      6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
      7 * See the COPYING file in the top-level directory.
      8 *
      9 */
     10
     11#include "qemu/osdep.h"
     12
     13#include "qapi/error.h"
     14#include "qom/object_interfaces.h"
     15#include "sysemu/kvm.h"
     16#include "migration/blocker.h"
     17#include "exec/confidential-guest-support.h"
     18#include "hw/ppc/pef.h"
     19
     20#define TYPE_PEF_GUEST "pef-guest"
     21OBJECT_DECLARE_SIMPLE_TYPE(PefGuest, PEF_GUEST)
     22
     23typedef struct PefGuest PefGuest;
     24typedef struct PefGuestClass PefGuestClass;
     25
     26struct PefGuestClass {
     27    ConfidentialGuestSupportClass parent_class;
     28};
     29
     30/**
     31 * PefGuest:
     32 *
     33 * The PefGuest object is used for creating and managing a PEF
     34 * guest.
     35 *
     36 * # $QEMU \
     37 *         -object pef-guest,id=pef0 \
     38 *         -machine ...,confidential-guest-support=pef0
     39 */
     40struct PefGuest {
     41    ConfidentialGuestSupport parent_obj;
     42};
     43
     44static int kvmppc_svm_init(ConfidentialGuestSupport *cgs, Error **errp)
     45{
     46#ifdef CONFIG_KVM
     47    static Error *pef_mig_blocker;
     48
     49    if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_SECURE_GUEST)) {
     50        error_setg(errp,
     51                   "KVM implementation does not support Secure VMs (is an ultravisor running?)");
     52        return -1;
     53    } else {
     54        int ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_SECURE_GUEST, 0, 1);
     55
     56        if (ret < 0) {
     57            error_setg(errp,
     58                       "Error enabling PEF with KVM");
     59            return -1;
     60        }
     61    }
     62
     63    /* add migration blocker */
     64    error_setg(&pef_mig_blocker, "PEF: Migration is not implemented");
     65    /* NB: This can fail if --only-migratable is used */
     66    migrate_add_blocker(pef_mig_blocker, &error_fatal);
     67
     68    cgs->ready = true;
     69
     70    return 0;
     71#else
     72    g_assert_not_reached();
     73#endif
     74}
     75
     76/*
     77 * Don't set error if KVM_PPC_SVM_OFF ioctl is invoked on kernels
     78 * that don't support this ioctl.
     79 */
     80static int kvmppc_svm_off(Error **errp)
     81{
     82#ifdef CONFIG_KVM
     83    int rc;
     84
     85    rc = kvm_vm_ioctl(KVM_STATE(current_accel()), KVM_PPC_SVM_OFF);
     86    if (rc && rc != -ENOTTY) {
     87        error_setg_errno(errp, -rc, "KVM_PPC_SVM_OFF ioctl failed");
     88        return rc;
     89    }
     90    return 0;
     91#else
     92    g_assert_not_reached();
     93#endif
     94}
     95
     96int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
     97{
     98    if (!object_dynamic_cast(OBJECT(cgs), TYPE_PEF_GUEST)) {
     99        return 0;
    100    }
    101
    102    if (!kvm_enabled()) {
    103        error_setg(errp, "PEF requires KVM");
    104        return -1;
    105    }
    106
    107    return kvmppc_svm_init(cgs, errp);
    108}
    109
    110int pef_kvm_reset(ConfidentialGuestSupport *cgs, Error **errp)
    111{
    112    if (!object_dynamic_cast(OBJECT(cgs), TYPE_PEF_GUEST)) {
    113        return 0;
    114    }
    115
    116    /*
    117     * If we don't have KVM we should never have been able to
    118     * initialize PEF, so we should never get this far
    119     */
    120    assert(kvm_enabled());
    121
    122    return kvmppc_svm_off(errp);
    123}
    124
    125OBJECT_DEFINE_TYPE_WITH_INTERFACES(PefGuest,
    126                                   pef_guest,
    127                                   PEF_GUEST,
    128                                   CONFIDENTIAL_GUEST_SUPPORT,
    129                                   { TYPE_USER_CREATABLE },
    130                                   { NULL })
    131
    132static void pef_guest_class_init(ObjectClass *oc, void *data)
    133{
    134}
    135
    136static void pef_guest_init(Object *obj)
    137{
    138}
    139
    140static void pef_guest_finalize(Object *obj)
    141{
    142}