Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: s390: pv: Add query interface

Some of the query information is already available via sysfs but
having a IOCTL makes the information easier to retrieve.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Link: https://lore.kernel.org/r/20220517163629.3443-4-frankja@linux.ibm.com
Message-Id: <20220517163629.3443-4-frankja@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>

authored by

Janosch Frank and committed by
Christian Borntraeger
35d02493 38c21825

+101
+76
arch/s390/kvm/kvm-s390.c
··· 2224 2224 return r; 2225 2225 } 2226 2226 2227 + /* 2228 + * Here we provide user space with a direct interface to query UV 2229 + * related data like UV maxima and available features as well as 2230 + * feature specific data. 2231 + * 2232 + * To facilitate future extension of the data structures we'll try to 2233 + * write data up to the maximum requested length. 2234 + */ 2235 + static ssize_t kvm_s390_handle_pv_info(struct kvm_s390_pv_info *info) 2236 + { 2237 + ssize_t len_min; 2238 + 2239 + switch (info->header.id) { 2240 + case KVM_PV_INFO_VM: { 2241 + len_min = sizeof(info->header) + sizeof(info->vm); 2242 + 2243 + if (info->header.len_max < len_min) 2244 + return -EINVAL; 2245 + 2246 + memcpy(info->vm.inst_calls_list, 2247 + uv_info.inst_calls_list, 2248 + sizeof(uv_info.inst_calls_list)); 2249 + 2250 + /* It's max cpuid not max cpus, so it's off by one */ 2251 + info->vm.max_cpus = uv_info.max_guest_cpu_id + 1; 2252 + info->vm.max_guests = uv_info.max_num_sec_conf; 2253 + info->vm.max_guest_addr = uv_info.max_sec_stor_addr; 2254 + info->vm.feature_indication = uv_info.uv_feature_indications; 2255 + 2256 + return len_min; 2257 + } 2258 + default: 2259 + return -EINVAL; 2260 + } 2261 + } 2262 + 2227 2263 static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd) 2228 2264 { 2229 2265 int r = 0; ··· 2394 2358 UVC_CMD_SET_UNSHARE_ALL, &cmd->rc, &cmd->rrc); 2395 2359 KVM_UV_EVENT(kvm, 3, "PROTVIRT UNSHARE: rc %x rrc %x", 2396 2360 cmd->rc, cmd->rrc); 2361 + break; 2362 + } 2363 + case KVM_PV_INFO: { 2364 + struct kvm_s390_pv_info info = {}; 2365 + ssize_t data_len; 2366 + 2367 + /* 2368 + * No need to check the VM protection here. 2369 + * 2370 + * Maybe user space wants to query some of the data 2371 + * when the VM is still unprotected. If we see the 2372 + * need to fence a new data command we can still 2373 + * return an error in the info handler. 2374 + */ 2375 + 2376 + r = -EFAULT; 2377 + if (copy_from_user(&info, argp, sizeof(info.header))) 2378 + break; 2379 + 2380 + r = -EINVAL; 2381 + if (info.header.len_max < sizeof(info.header)) 2382 + break; 2383 + 2384 + data_len = kvm_s390_handle_pv_info(&info); 2385 + if (data_len < 0) { 2386 + r = data_len; 2387 + break; 2388 + } 2389 + /* 2390 + * If a data command struct is extended (multiple 2391 + * times) this can be used to determine how much of it 2392 + * is valid. 2393 + */ 2394 + info.header.len_written = data_len; 2395 + 2396 + r = -EFAULT; 2397 + if (copy_to_user(argp, &info, data_len)) 2398 + break; 2399 + 2400 + r = 0; 2397 2401 break; 2398 2402 } 2399 2403 default:
+25
include/uapi/linux/kvm.h
··· 1660 1660 __u64 tweak; 1661 1661 }; 1662 1662 1663 + enum pv_cmd_info_id { 1664 + KVM_PV_INFO_VM, 1665 + }; 1666 + 1667 + struct kvm_s390_pv_info_vm { 1668 + __u64 inst_calls_list[4]; 1669 + __u64 max_cpus; 1670 + __u64 max_guests; 1671 + __u64 max_guest_addr; 1672 + __u64 feature_indication; 1673 + }; 1674 + 1675 + struct kvm_s390_pv_info_header { 1676 + __u32 id; 1677 + __u32 len_max; 1678 + __u32 len_written; 1679 + __u32 reserved; 1680 + }; 1681 + 1682 + struct kvm_s390_pv_info { 1683 + struct kvm_s390_pv_info_header header; 1684 + struct kvm_s390_pv_info_vm vm; 1685 + }; 1686 + 1663 1687 enum pv_cmd_id { 1664 1688 KVM_PV_ENABLE, 1665 1689 KVM_PV_DISABLE, ··· 1692 1668 KVM_PV_VERIFY, 1693 1669 KVM_PV_PREP_RESET, 1694 1670 KVM_PV_UNSHARE_ALL, 1671 + KVM_PV_INFO, 1695 1672 }; 1696 1673 1697 1674 struct kvm_pv_cmd {