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"
20 #include "kvm_s390x.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
->maxram_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
->maxram_size
/ TARGET_PAGE_SIZE
;
108 unsigned long cx
, len
= 1 << 19;
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
)