/*
 * s390 storage key device
 *
 * Copyright 2015 IBM Corp.
 * Author(s): Jason J. Herne <jjherne@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at
 * your option) any later version. See the COPYING file in the top-level
 * directory.
 */

#include "qemu/osdep.h"
#include "hw/s390x/storage-keys.h"
#include "sysemu/kvm.h"
#include "qemu/error-report.h"

static int kvm_s390_skeys_enabled(S390SKeysState *ss)
{
    S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss);
    uint8_t single_key;
    int r;

    r = skeyclass->get_skeys(ss, 0, 1, &single_key);
    if (r != 0 && r != KVM_S390_GET_SKEYS_NONE) {
        error_report("S390_GET_KEYS error %d", r);
    }
    return (r == 0);
}

static int kvm_s390_skeys_get(S390SKeysState *ss, uint64_t start_gfn,
                              uint64_t count, uint8_t *keys)
{
    struct kvm_s390_skeys args = {
        .start_gfn = start_gfn,
        .count = count,
        .skeydata_addr = (__u64)keys
    };

    return kvm_vm_ioctl(kvm_state, KVM_S390_GET_SKEYS, &args);
}

static int kvm_s390_skeys_set(S390SKeysState *ss, uint64_t start_gfn,
                              uint64_t count, uint8_t *keys)
{
    struct kvm_s390_skeys args = {
        .start_gfn = start_gfn,
        .count = count,
        .skeydata_addr = (__u64)keys
    };

    return kvm_vm_ioctl(kvm_state, KVM_S390_SET_SKEYS, &args);
}

static void kvm_s390_skeys_class_init(ObjectClass *oc, void *data)
{
    S390SKeysClass *skeyclass = S390_SKEYS_CLASS(oc);

    skeyclass->skeys_enabled = kvm_s390_skeys_enabled;
    skeyclass->get_skeys = kvm_s390_skeys_get;
    skeyclass->set_skeys = kvm_s390_skeys_set;
}

static const TypeInfo kvm_s390_skeys_info = {
    .name          = TYPE_KVM_S390_SKEYS,
    .parent        = TYPE_S390_SKEYS,
    .instance_size = sizeof(S390SKeysState),
    .class_init    = kvm_s390_skeys_class_init,
    .class_size    = sizeof(S390SKeysClass),
};

static void kvm_s390_skeys_register_types(void)
{
    type_register_static(&kvm_s390_skeys_info);
}

type_init(kvm_s390_skeys_register_types)
