12
#include "qemu/osdep.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"
20
#include "qapi/error.h"
22
Object *kvm_s390_stattrib_create(void)
25
kvm_check_extension(kvm_state, KVM_CAP_S390_CMMA_MIGRATION)) {
26
return object_new(TYPE_KVM_S390_STATTRIB);
31
static void kvm_s390_stattrib_instance_init(Object *obj)
33
KVMS390StAttribState *sas = KVM_S390_STATTRIB(obj);
38
static int kvm_s390_stattrib_read_helper(S390StAttribState *sa,
44
KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa);
46
struct kvm_s390_cmma_log clog = {
47
.values = (uint64_t)values,
48
.start_gfn = *start_gfn,
53
r = kvm_vm_ioctl(kvm_state, KVM_S390_GET_CMMA_BITS, &clog);
55
error_report("KVM_S390_GET_CMMA_BITS failed: %s", strerror(-r));
59
*start_gfn = clog.start_gfn;
60
sas->still_dirty = clog.remaining;
64
static int kvm_s390_stattrib_get_stattr(S390StAttribState *sa,
69
return kvm_s390_stattrib_read_helper(sa, start_gfn, count, values, 0);
72
static int kvm_s390_stattrib_peek_stattr(S390StAttribState *sa,
77
return kvm_s390_stattrib_read_helper(sa, &start_gfn, count, values,
81
static int kvm_s390_stattrib_set_stattr(S390StAttribState *sa,
86
KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa);
87
MachineState *machine = MACHINE(qdev_get_machine());
88
unsigned long max = machine->ram_size / TARGET_PAGE_SIZE;
90
if (start_gfn + count > max) {
91
error_report("Out of memory bounds when setting storage attributes");
94
if (!sas->incoming_buffer) {
95
sas->incoming_buffer = g_malloc0(max);
98
memcpy(sas->incoming_buffer + start_gfn, values, count);
103
static void kvm_s390_stattrib_synchronize(S390StAttribState *sa)
105
KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa);
106
MachineState *machine = MACHINE(qdev_get_machine());
107
unsigned long max = machine->ram_size / TARGET_PAGE_SIZE;
109
unsigned long cx, len = KVM_S390_SKEYS_MAX / 2;
111
struct kvm_s390_cmma_log clog = {
116
if (sas->incoming_buffer) {
117
for (cx = 0; cx + len <= max; cx += len) {
120
clog.values = (uint64_t)(sas->incoming_buffer + cx);
121
r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
123
error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));
129
clog.count = max - cx;
130
clog.values = (uint64_t)(sas->incoming_buffer + cx);
131
r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
133
error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));
136
g_free(sas->incoming_buffer);
137
sas->incoming_buffer = NULL;
141
static int kvm_s390_stattrib_set_migrationmode(S390StAttribState *sa, bool val,
144
struct kvm_device_attr attr = {
145
.group = KVM_S390_VM_MIGRATION,
151
r = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
153
error_setg_errno(errp, -r, "setting KVM_S390_VM_MIGRATION failed");
158
static long long kvm_s390_stattrib_get_dirtycount(S390StAttribState *sa)
160
KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa);
163
kvm_s390_stattrib_peek_stattr(sa, 0, 1, val);
164
return sas->still_dirty;
167
static int kvm_s390_stattrib_get_active(S390StAttribState *sa)
169
return kvm_s390_cmma_active() && sa->migration_enabled;
172
static void kvm_s390_stattrib_class_init(ObjectClass *oc, void *data)
174
S390StAttribClass *sac = S390_STATTRIB_CLASS(oc);
175
DeviceClass *dc = DEVICE_CLASS(oc);
177
sac->get_stattr = kvm_s390_stattrib_get_stattr;
178
sac->peek_stattr = kvm_s390_stattrib_peek_stattr;
179
sac->set_stattr = kvm_s390_stattrib_set_stattr;
180
sac->set_migrationmode = kvm_s390_stattrib_set_migrationmode;
181
sac->get_dirtycount = kvm_s390_stattrib_get_dirtycount;
182
sac->synchronize = kvm_s390_stattrib_synchronize;
183
sac->get_active = kvm_s390_stattrib_get_active;
186
dc->user_creatable = false;
189
static const TypeInfo kvm_s390_stattrib_info = {
190
.name = TYPE_KVM_S390_STATTRIB,
191
.parent = TYPE_S390_STATTRIB,
192
.instance_init = kvm_s390_stattrib_instance_init,
193
.instance_size = sizeof(KVMS390StAttribState),
194
.class_init = kvm_s390_stattrib_class_init,
195
.class_size = sizeof(S390StAttribClass),
198
static void kvm_s390_stattrib_register_types(void)
200
type_register_static(&kvm_s390_stattrib_info);
203
type_init(kvm_s390_stattrib_register_types)