From: Tony Krowiak <akrow...@linux.vnet.ibm.com>

Check for the aes_key_wrap and dea_key_wrap machine options and set the
appropriate KVM device attribute(s) to tell the kernel to enable or disable
the AES/DEA protected key functions for the guest domain.

This patch introduces two new machine options for indicating the state of
AES/DEA key wrapping functions.  This controls whether the guest will
have access to the AES/DEA crypto functions.

aes_key_wrap="on | off" is changed to aes-key-wrap="on | off"
dea_key_wrap="on | off" is changed to dea-key-wrap="on | off"

Check for the aes-key-wrap and dea-key-wrap machine options and set the
appropriate KVM device attribute(s) to tell the kernel to enable or disable
the AES/DEA protected key functions for the guest domain.

Reviewed-by: David Hildenbrand <d...@linux.vnet.ibm.com>
Signed-off-by: Tony Krowiak <akrow...@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jf...@linux.vnet.ibm.com>
Message-Id: <1426164834-38648-4-git-send-email-jf...@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.h...@de.ibm.com>
---
 hw/s390x/s390-virtio-ccw.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
 qemu-options.hx            | 12 ++++++++-
 target-s390x/kvm.c         | 51 +++++++++++++++++++++++++++++++++++++
 3 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index eea0742..afb539a 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -22,6 +22,18 @@
 
 #define TYPE_S390_CCW_MACHINE               "s390-ccw-machine"
 
+#define S390_CCW_MACHINE(obj) \
+    OBJECT_CHECK(S390CcwMachineState, (obj), TYPE_S390_CCW_MACHINE)
+
+typedef struct S390CcwMachineState {
+    /*< private >*/
+    MachineState parent_obj;
+
+    /*< public >*/
+    bool aes_key_wrap;
+    bool dea_key_wrap;
+} S390CcwMachineState;
+
 void io_subsystem_reset(void)
 {
     DeviceState *css, *sclp, *flic;
@@ -207,9 +219,60 @@ static void ccw_machine_class_init(ObjectClass *oc, void 
*data)
     nc->nmi_monitor_handler = s390_nmi;
 }
 
+static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
+{
+    S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
+
+    return ms->aes_key_wrap;
+}
+
+static inline void machine_set_aes_key_wrap(Object *obj, bool value,
+                                            Error **errp)
+{
+    S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
+
+    ms->aes_key_wrap = value;
+}
+
+static inline bool machine_get_dea_key_wrap(Object *obj, Error **errp)
+{
+    S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
+
+    return ms->dea_key_wrap;
+}
+
+static inline void machine_set_dea_key_wrap(Object *obj, bool value,
+                                            Error **errp)
+{
+    S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
+
+    ms->dea_key_wrap = value;
+}
+
+static inline void s390_machine_initfn(Object *obj)
+{
+    object_property_add_bool(obj, "aes-key-wrap",
+                             machine_get_aes_key_wrap,
+                             machine_set_aes_key_wrap, NULL);
+    object_property_set_description(obj, "aes-key-wrap",
+            "enable/disable AES key wrapping using the CPACF wrapping key",
+            NULL);
+    object_property_set_bool(obj, true, "aes-key-wrap", NULL);
+
+    object_property_add_bool(obj, "dea-key-wrap",
+                             machine_get_dea_key_wrap,
+                             machine_set_dea_key_wrap, NULL);
+    object_property_set_description(obj, "dea-key-wrap",
+            "enable/disable DEA key wrapping using the CPACF wrapping key",
+            NULL);
+    object_property_set_bool(obj, true, "dea-key-wrap", NULL);
+}
+
 static const TypeInfo ccw_machine_info = {
     .name          = TYPE_S390_CCW_MACHINE,
     .parent        = TYPE_MACHINE,
+    .instance_size = sizeof(S390CcwMachineState),
+    .instance_init = s390_machine_initfn,
     .class_init    = ccw_machine_class_init,
     .interfaces = (InterfaceInfo[]) {
         { TYPE_NMI },
diff --git a/qemu-options.hx b/qemu-options.hx
index 837624d..ad07dde 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -37,7 +37,9 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
     "                kvm_shadow_mem=size of KVM shadow MMU\n"
     "                dump-guest-core=on|off include guest memory in a core 
dump (default=on)\n"
     "                mem-merge=on|off controls memory merge support (default: 
on)\n"
-    "                iommu=on|off controls emulated Intel IOMMU (VT-d) support 
(default=off)\n",
+    "                iommu=on|off controls emulated Intel IOMMU (VT-d) support 
(default=off)\n"
+    "                aes-key-wrap=on|off controls support for AES key wrapping 
(default=on)\n"
+    "                dea-key-wrap=on|off controls support for DEA key wrapping 
(default=on)\n",
     QEMU_ARCH_ALL)
 STEXI
 @item -machine [type=]@var{name}[,prop=@var{value}[,...]]
@@ -66,6 +68,14 @@ the host, de-duplicates identical memory pages among VMs 
instances
 (enabled by default).
 @item iommu=on|off
 Enables or disables emulated Intel IOMMU (VT-d) support. The default is off.
+@item aes-key-wrap=on|off
+Enables or disables AES key wrapping support on s390-ccw hosts. This feature
+controls whether AES wrapping keys will be created to allow
+execution of AES cryptographic functions.  The default is on.
+@item dea-key-wrap=on|off
+Enables or disables DEA key wrapping support on s390-ccw hosts. This feature
+controls whether DEA wrapping keys will be created to allow
+execution of DEA cryptographic functions.  The default is on.
 @end table
 ETEXI
 
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 38887aa..b48c643 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -193,6 +193,55 @@ static void kvm_s390_enable_cmma(KVMState *s)
     trace_kvm_enable_cmma(rc);
 }
 
+static void kvm_s390_set_attr(uint64_t attr)
+{
+    struct kvm_device_attr attribute = {
+        .group = KVM_S390_VM_CRYPTO,
+        .attr  = attr,
+    };
+
+    int ret = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attribute);
+
+    if (ret) {
+        error_report("Failed to set crypto device attribute %lu: %s",
+                     attr, strerror(-ret));
+    }
+}
+
+static void kvm_s390_init_aes_kw(void)
+{
+    uint64_t attr = KVM_S390_VM_CRYPTO_DISABLE_AES_KW;
+
+    if (object_property_get_bool(OBJECT(qdev_get_machine()), "aes-key-wrap",
+                                 NULL)) {
+            attr = KVM_S390_VM_CRYPTO_ENABLE_AES_KW;
+    }
+
+    if (kvm_vm_check_attr(kvm_state, KVM_S390_VM_CRYPTO, attr)) {
+            kvm_s390_set_attr(attr);
+    }
+}
+
+static void kvm_s390_init_dea_kw(void)
+{
+    uint64_t attr = KVM_S390_VM_CRYPTO_DISABLE_DEA_KW;
+
+    if (object_property_get_bool(OBJECT(qdev_get_machine()), "dea-key-wrap",
+                                 NULL)) {
+            attr = KVM_S390_VM_CRYPTO_ENABLE_DEA_KW;
+    }
+
+    if (kvm_vm_check_attr(kvm_state, KVM_S390_VM_CRYPTO, attr)) {
+            kvm_s390_set_attr(attr);
+    }
+}
+
+static void kvm_s390_init_crypto(void)
+{
+    kvm_s390_init_aes_kw();
+    kvm_s390_init_dea_kw();
+}
+
 int kvm_arch_init(MachineState *ms, KVMState *s)
 {
     cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
@@ -234,6 +283,8 @@ void kvm_s390_reset_vcpu(S390CPU *cpu)
     if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL)) {
         error_report("Initial CPU reset failed on CPU %i", cs->cpu_index);
     }
+
+    kvm_s390_init_crypto();
 }
 
 static int can_sync_regs(CPUState *cs, int regs)
-- 
2.3.3


Reply via email to