2 * s390 storage attributes device -- KVM object
4 * Copyright 2016 IBM Corp.
5 * Author(s): Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
7 * This work is licensed under the terms of the GNU GPL, version 2 or (at
8 * your option) any later version. See the COPYING file in the top-level
12 #include "qemu/osdep.h"
13 #include "hw/boards.h"
14 #include "migration/qemu-file.h"
15 #include "hw/s390x/storage-attributes.h"
16 #include "qemu/error-report.h"
17 #include "sysemu/kvm.h"
18 #include "exec/ram_addr.h"
19 #include "kvm/kvm_s390x.h"
21 Object
*kvm_s390_stattrib_create(void)
24 kvm_check_extension(kvm_state
, KVM_CAP_S390_CMMA_MIGRATION
)) {
25 return object_new(TYPE_KVM_S390_STATTRIB
);
30 static void kvm_s390_stattrib_instance_init(Object
*obj
)
32 KVMS390StAttribState
*sas
= KVM_S390_STATTRIB(obj
);
37 static int kvm_s390_stattrib_read_helper(S390StAttribState
*sa
,
43 KVMS390StAttribState
*sas
= KVM_S390_STATTRIB(sa
);
45 struct kvm_s390_cmma_log clog
= {
46 .values
= (uint64_t)values
,
47 .start_gfn
= *start_gfn
,
52 r
= kvm_vm_ioctl(kvm_state
, KVM_S390_GET_CMMA_BITS
, &clog
);
54 error_report("KVM_S390_GET_CMMA_BITS failed: %s", strerror(-r
));
58 *start_gfn
= clog
.start_gfn
;
59 sas
->still_dirty
= clog
.remaining
;
63 static int kvm_s390_stattrib_get_stattr(S390StAttribState
*sa
,
68 return kvm_s390_stattrib_read_helper(sa
, start_gfn
, count
, values
, 0);
71 static int kvm_s390_stattrib_peek_stattr(S390StAttribState
*sa
,
76 return kvm_s390_stattrib_read_helper(sa
, &start_gfn
, count
, values
,
80 static int kvm_s390_stattrib_set_stattr(S390StAttribState
*sa
,
85 KVMS390StAttribState
*sas
= KVM_S390_STATTRIB(sa
);
86 MachineState
*machine
= MACHINE(qdev_get_machine());
87 unsigned long max
= machine
->ram_size
/ TARGET_PAGE_SIZE
;
89 if (start_gfn
+ count
> max
) {
90 error_report("Out of memory bounds when setting storage attributes");
93 if (!sas
->incoming_buffer
) {
94 sas
->incoming_buffer
= g_malloc0(max
);
97 memcpy(sas
->incoming_buffer
+ start_gfn
, values
, count
);
102 static void kvm_s390_stattrib_synchronize(S390StAttribState
*sa
)
104 KVMS390StAttribState
*sas
= KVM_S390_STATTRIB(sa
);
105 MachineState
*machine
= MACHINE(qdev_get_machine());
106 unsigned long max
= machine
->ram_size
/ TARGET_PAGE_SIZE
;
107 /* We do not need to reach the maximum buffer size allowed */
108 unsigned long cx
, len
= KVM_S390_SKEYS_MAX
/ 2;
110 struct kvm_s390_cmma_log clog
= {
115 if (sas
->incoming_buffer
) {
116 for (cx
= 0; cx
+ len
<= max
; cx
+= len
) {
119 clog
.values
= (uint64_t)(sas
->incoming_buffer
+ cx
);
120 r
= kvm_vm_ioctl(kvm_state
, KVM_S390_SET_CMMA_BITS
, &clog
);
122 error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r
));
128 clog
.count
= max
- cx
;
129 clog
.values
= (uint64_t)(sas
->incoming_buffer
+ cx
);
130 r
= kvm_vm_ioctl(kvm_state
, KVM_S390_SET_CMMA_BITS
, &clog
);
132 error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r
));
135 g_free(sas
->incoming_buffer
);
136 sas
->incoming_buffer
= NULL
;
140 static int kvm_s390_stattrib_set_migrationmode(S390StAttribState
*sa
, bool val
)
142 struct kvm_device_attr attr
= {
143 .group
= KVM_S390_VM_MIGRATION
,
147 return kvm_vm_ioctl(kvm_state
, KVM_SET_DEVICE_ATTR
, &attr
);
150 static long long kvm_s390_stattrib_get_dirtycount(S390StAttribState
*sa
)
152 KVMS390StAttribState
*sas
= KVM_S390_STATTRIB(sa
);
155 kvm_s390_stattrib_peek_stattr(sa
, 0, 1, val
);
156 return sas
->still_dirty
;
159 static int kvm_s390_stattrib_get_active(S390StAttribState
*sa
)
161 return kvm_s390_cmma_active() && sa
->migration_enabled
;
164 static void kvm_s390_stattrib_class_init(ObjectClass
*oc
, void *data
)
166 S390StAttribClass
*sac
= S390_STATTRIB_CLASS(oc
);
167 DeviceClass
*dc
= DEVICE_CLASS(oc
);
169 sac
->get_stattr
= kvm_s390_stattrib_get_stattr
;
170 sac
->peek_stattr
= kvm_s390_stattrib_peek_stattr
;
171 sac
->set_stattr
= kvm_s390_stattrib_set_stattr
;
172 sac
->set_migrationmode
= kvm_s390_stattrib_set_migrationmode
;
173 sac
->get_dirtycount
= kvm_s390_stattrib_get_dirtycount
;
174 sac
->synchronize
= kvm_s390_stattrib_synchronize
;
175 sac
->get_active
= kvm_s390_stattrib_get_active
;
177 /* Reason: Can only be instantiated one time (internally) */
178 dc
->user_creatable
= false;
181 static const TypeInfo kvm_s390_stattrib_info
= {
182 .name
= TYPE_KVM_S390_STATTRIB
,
183 .parent
= TYPE_S390_STATTRIB
,
184 .instance_init
= kvm_s390_stattrib_instance_init
,
185 .instance_size
= sizeof(KVMS390StAttribState
),
186 .class_init
= kvm_s390_stattrib_class_init
,
187 .class_size
= sizeof(S390StAttribClass
),
190 static void kvm_s390_stattrib_register_types(void)
192 type_register_static(&kvm_s390_stattrib_info
);
195 type_init(kvm_s390_stattrib_register_types
)