···51275127 __u32 reserved[3];51285128 };5129512951305130-cmd values:51305130+**Ultravisor return codes**51315131+The Ultravisor return (reason) codes are provided by the kernel if a51325132+Ultravisor call has been executed to achieve the results expected by51335133+the command. Therefore they are independent of the IOCTL return51345134+code. If KVM changes `rc`, its value will always be greater than 051355135+hence setting it to 0 before issuing a PV command is advised to be51365136+able to detect a change of `rc`.51375137+51385138+**cmd values:**5131513951325140KVM_PV_ENABLE51335141 Allocate memory and register the VM with the Ultravisor, thereby···51515143 ===== =============================5152514451535145KVM_PV_DISABLE51545154-51555146 Deregister the VM from the Ultravisor and reclaim the memory that51565147 had been donated to the Ultravisor, making it usable by the kernel51575148 again. All registered VCPUs are converted back to non-protected···51665159KVM_PV_VM_VERIFY51675160 Verify the integrity of the unpacked image. Only if this succeeds,51685161 KVM is allowed to start protected VCPUs.51625162+51635163+KVM_PV_INFO51645164+ :Capability: KVM_CAP_S390_PROTECTED_DUMP51655165+51665166+ Presents an API that provides Ultravisor related data to userspace51675167+ via subcommands. len_max is the size of the user space buffer,51685168+ len_written is KVM's indication of how much bytes of that buffer51695169+ were actually written to. len_written can be used to determine the51705170+ valid fields if more response fields are added in the future.51715171+51725172+ ::51735173+51745174+ enum pv_cmd_info_id {51755175+ KVM_PV_INFO_VM,51765176+ KVM_PV_INFO_DUMP,51775177+ };51785178+51795179+ struct kvm_s390_pv_info_header {51805180+ __u32 id;51815181+ __u32 len_max;51825182+ __u32 len_written;51835183+ __u32 reserved;51845184+ };51855185+51865186+ struct kvm_s390_pv_info {51875187+ struct kvm_s390_pv_info_header header;51885188+ struct kvm_s390_pv_info_dump dump;51895189+ struct kvm_s390_pv_info_vm vm;51905190+ };51915191+51925192+**subcommands:**51935193+51945194+ KVM_PV_INFO_VM51955195+ This subcommand provides basic Ultravisor information for PV51965196+ hosts. These values are likely also exported as files in the sysfs51975197+ firmware UV query interface but they are more easily available to51985198+ programs in this API.51995199+52005200+ The installed calls and feature_indication members provide the52015201+ installed UV calls and the UV's other feature indications.52025202+52035203+ The max_* members provide information about the maximum number of PV52045204+ vcpus, PV guests and PV guest memory size.52055205+52065206+ ::52075207+52085208+ struct kvm_s390_pv_info_vm {52095209+ __u64 inst_calls_list[4];52105210+ __u64 max_cpus;52115211+ __u64 max_guests;52125212+ __u64 max_guest_addr;52135213+ __u64 feature_indication;52145214+ };52155215+52165216+52175217+ KVM_PV_INFO_DUMP52185218+ This subcommand provides information related to dumping PV guests.52195219+52205220+ ::52215221+52225222+ struct kvm_s390_pv_info_dump {52235223+ __u64 dump_cpu_buffer_len;52245224+ __u64 dump_config_mem_buffer_per_1m;52255225+ __u64 dump_config_finalize_len;52265226+ };52275227+52285228+KVM_PV_DUMP52295229+ :Capability: KVM_CAP_S390_PROTECTED_DUMP52305230+52315231+ Presents an API that provides calls which facilitate dumping a52325232+ protected VM.52335233+52345234+ ::52355235+52365236+ struct kvm_s390_pv_dmp {52375237+ __u64 subcmd;52385238+ __u64 buff_addr;52395239+ __u64 buff_len;52405240+ __u64 gaddr; /* For dump storage state */52415241+ };52425242+52435243+ **subcommands:**52445244+52455245+ KVM_PV_DUMP_INIT52465246+ Initializes the dump process of a protected VM. If this call does52475247+ not succeed all other subcommands will fail with -EINVAL. This52485248+ subcommand will return -EINVAL if a dump process has not yet been52495249+ completed.52505250+52515251+ Not all PV vms can be dumped, the owner needs to set `dump52525252+ allowed` PCF bit 34 in the SE header to allow dumping.52535253+52545254+ KVM_PV_DUMP_CONFIG_STOR_STATE52555255+ Stores `buff_len` bytes of tweak component values starting with52565256+ the 1MB block specified by the absolute guest address52575257+ (`gaddr`). `buff_len` needs to be `conf_dump_storage_state_len`52585258+ aligned and at least >= the `conf_dump_storage_state_len` value52595259+ provided by the dump uv_info data. buff_user might be written to52605260+ even if an error rc is returned. For instance if we encounter a52615261+ fault after writing the first page of data.52625262+52635263+ KVM_PV_DUMP_COMPLETE52645264+ If the subcommand succeeds it completes the dump process and lets52655265+ KVM_PV_DUMP_INIT be called again.52665266+52675267+ On success `conf_dump_finalize_len` bytes of completion data will be52685268+ stored to the `buff_addr`. The completion data contains a key52695269+ derivation seed, IV, tweak nonce and encryption keys as well as an52705270+ authentication tag all of which are needed to decrypt the dump at a52715271+ later time.52725272+51695273517052744.126 KVM_X86_SET_MSR_FILTER51715275----------------------------···59195801 };5920580259215803This ioctl injects an event channel interrupt directly to the guest vCPU.58045804+58055805+4.136 KVM_S390_PV_CPU_COMMAND58065806+-----------------------------58075807+58085808+:Capability: KVM_CAP_S390_PROTECTED_DUMP58095809+:Architectures: s39058105810+:Type: vcpu ioctl58115811+:Parameters: none58125812+:Returns: 0 on success, < 0 on error58135813+58145814+This ioctl closely mirrors `KVM_S390_PV_COMMAND` but handles requests58155815+for vcpus. It re-uses the kvm_s390_pv_dmp struct and hence also shares58165816+the command ids.58175817+58185818+**command:**58195819+58205820+KVM_PV_DUMP58215821+ Presents an API that provides calls which facilitate dumping a vcpu58225822+ of a protected VM.58235823+58245824+**subcommand:**58255825+58265826+KVM_PV_DUMP_CPU58275827+ Provides encrypted dump data like register values.58285828+ The length of the returned data is provided by uv_info.guest_cpu_stor_len.58295829+59225830592358315. The kvm_run structure59245832========================···8099795581007956When enabled, KVM will exit to userspace with KVM_EXIT_SYSTEM_EVENT of81017957type KVM_SYSTEM_EVENT_SUSPEND to process the guest suspend request.79587958+79597959+8.37 KVM_CAP_S390_PROTECTED_DUMP79607960+--------------------------------79617961+79627962+:Capability: KVM_CAP_S390_PROTECTED_DUMP79637963+:Architectures: s39079647964+:Type: vm79657965+79667966+This capability indicates that KVM and the Ultravisor support dumping79677967+PV guests. The `KVM_PV_DUMP` command is available for the79687968+`KVM_S390_PV_COMMAND` ioctl and the `KVM_PV_INFO` command provides79697969+dump related UV data. Also the vcpu ioctl `KVM_S390_PV_CPU_COMMAND` is79707970+available and supports the `KVM_PV_DUMP_CPU` subcommand.79717971+81027972810379739. Known KVM API problems81047974=========================
···11+.. SPDX-License-Identifier: GPL-2.022+33+===========================================44+s390 (IBM Z) Protected Virtualization dumps55+===========================================66+77+Summary88+-------99+1010+Dumping a VM is an essential tool for debugging problems inside1111+it. This is especially true when a protected VM runs into trouble as1212+there's no way to access its memory and registers from the outside1313+while it's running.1414+1515+However when dumping a protected VM we need to maintain its1616+confidentiality until the dump is in the hands of the VM owner who1717+should be the only one capable of analysing it.1818+1919+The confidentiality of the VM dump is ensured by the Ultravisor who2020+provides an interface to KVM over which encrypted CPU and memory data2121+can be requested. The encryption is based on the Customer2222+Communication Key which is the key that's used to encrypt VM data in a2323+way that the customer is able to decrypt.2424+2525+2626+Dump process2727+------------2828+2929+A dump is done in 3 steps:3030+3131+**Initiation**3232+3333+This step initializes the dump process, generates cryptographic seeds3434+and extracts dump keys with which the VM dump data will be encrypted.3535+3636+**Data gathering**3737+3838+Currently there are two types of data that can be gathered from a VM:3939+the memory and the vcpu state.4040+4141+The vcpu state contains all the important registers, general, floating4242+point, vector, control and tod/timers of a vcpu. The vcpu dump can4343+contain incomplete data if a vcpu is dumped while an instruction is4444+emulated with help of the hypervisor. This is indicated by a flag bit4545+in the dump data. For the same reason it is very important to not only4646+write out the encrypted vcpu state, but also the unencrypted state4747+from the hypervisor.4848+4949+The memory state is further divided into the encrypted memory and its5050+metadata comprised of the encryption tweaks and status flags. The5151+encrypted memory can simply be read once it has been exported. The5252+time of the export does not matter as no re-encryption is5353+needed. Memory that has been swapped out and hence was exported can be5454+read from the swap and written to the dump target without need for any5555+special actions.5656+5757+The tweaks / status flags for the exported pages need to be requested5858+from the Ultravisor.5959+6060+**Finalization**6161+6262+The finalization step will provide the data needed to be able to6363+decrypt the vcpu and memory data and end the dump process. When this6464+step completes successfully a new dump initiation can be started.
···606606 case KVM_CAP_S390_PROTECTED:607607 r = is_prot_virt_host();608608 break;609609+ case KVM_CAP_S390_PROTECTED_DUMP: {610610+ u64 pv_cmds_dump[] = {611611+ BIT_UVC_CMD_DUMP_INIT,612612+ BIT_UVC_CMD_DUMP_CONFIG_STOR_STATE,613613+ BIT_UVC_CMD_DUMP_CPU,614614+ BIT_UVC_CMD_DUMP_COMPLETE,615615+ };616616+ int i;617617+618618+ r = is_prot_virt_host();619619+620620+ for (i = 0; i < ARRAY_SIZE(pv_cmds_dump); i++) {621621+ if (!test_bit_inv(pv_cmds_dump[i],622622+ (unsigned long *)&uv_info.inst_calls_list)) {623623+ r = 0;624624+ break;625625+ }626626+ }627627+ break;628628+ }609629 default:610630 r = 0;611631 }···22402220 return r;22412221}2242222222232223+/*22242224+ * Here we provide user space with a direct interface to query UV22252225+ * related data like UV maxima and available features as well as22262226+ * feature specific data.22272227+ *22282228+ * To facilitate future extension of the data structures we'll try to22292229+ * write data up to the maximum requested length.22302230+ */22312231+static ssize_t kvm_s390_handle_pv_info(struct kvm_s390_pv_info *info)22322232+{22332233+ ssize_t len_min;22342234+22352235+ switch (info->header.id) {22362236+ case KVM_PV_INFO_VM: {22372237+ len_min = sizeof(info->header) + sizeof(info->vm);22382238+22392239+ if (info->header.len_max < len_min)22402240+ return -EINVAL;22412241+22422242+ memcpy(info->vm.inst_calls_list,22432243+ uv_info.inst_calls_list,22442244+ sizeof(uv_info.inst_calls_list));22452245+22462246+ /* It's max cpuid not max cpus, so it's off by one */22472247+ info->vm.max_cpus = uv_info.max_guest_cpu_id + 1;22482248+ info->vm.max_guests = uv_info.max_num_sec_conf;22492249+ info->vm.max_guest_addr = uv_info.max_sec_stor_addr;22502250+ info->vm.feature_indication = uv_info.uv_feature_indications;22512251+22522252+ return len_min;22532253+ }22542254+ case KVM_PV_INFO_DUMP: {22552255+ len_min = sizeof(info->header) + sizeof(info->dump);22562256+22572257+ if (info->header.len_max < len_min)22582258+ return -EINVAL;22592259+22602260+ info->dump.dump_cpu_buffer_len = uv_info.guest_cpu_stor_len;22612261+ info->dump.dump_config_mem_buffer_per_1m = uv_info.conf_dump_storage_state_len;22622262+ info->dump.dump_config_finalize_len = uv_info.conf_dump_finalize_len;22632263+ return len_min;22642264+ }22652265+ default:22662266+ return -EINVAL;22672267+ }22682268+}22692269+22702270+static int kvm_s390_pv_dmp(struct kvm *kvm, struct kvm_pv_cmd *cmd,22712271+ struct kvm_s390_pv_dmp dmp)22722272+{22732273+ int r = -EINVAL;22742274+ void __user *result_buff = (void __user *)dmp.buff_addr;22752275+22762276+ switch (dmp.subcmd) {22772277+ case KVM_PV_DUMP_INIT: {22782278+ if (kvm->arch.pv.dumping)22792279+ break;22802280+22812281+ /*22822282+ * Block SIE entry as concurrent dump UVCs could lead22832283+ * to validities.22842284+ */22852285+ kvm_s390_vcpu_block_all(kvm);22862286+22872287+ r = uv_cmd_nodata(kvm_s390_pv_get_handle(kvm),22882288+ UVC_CMD_DUMP_INIT, &cmd->rc, &cmd->rrc);22892289+ KVM_UV_EVENT(kvm, 3, "PROTVIRT DUMP INIT: rc %x rrc %x",22902290+ cmd->rc, cmd->rrc);22912291+ if (!r) {22922292+ kvm->arch.pv.dumping = true;22932293+ } else {22942294+ kvm_s390_vcpu_unblock_all(kvm);22952295+ r = -EINVAL;22962296+ }22972297+ break;22982298+ }22992299+ case KVM_PV_DUMP_CONFIG_STOR_STATE: {23002300+ if (!kvm->arch.pv.dumping)23012301+ break;23022302+23032303+ /*23042304+ * gaddr is an output parameter since we might stop23052305+ * early. As dmp will be copied back in our caller, we23062306+ * don't need to do it ourselves.23072307+ */23082308+ r = kvm_s390_pv_dump_stor_state(kvm, result_buff, &dmp.gaddr, dmp.buff_len,23092309+ &cmd->rc, &cmd->rrc);23102310+ break;23112311+ }23122312+ case KVM_PV_DUMP_COMPLETE: {23132313+ if (!kvm->arch.pv.dumping)23142314+ break;23152315+23162316+ r = -EINVAL;23172317+ if (dmp.buff_len < uv_info.conf_dump_finalize_len)23182318+ break;23192319+23202320+ r = kvm_s390_pv_dump_complete(kvm, result_buff,23212321+ &cmd->rc, &cmd->rrc);23222322+ break;23232323+ }23242324+ default:23252325+ r = -ENOTTY;23262326+ break;23272327+ }23282328+23292329+ return r;23302330+}23312331+22432332static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)22442333{22452334 int r = 0;···24832354 UVC_CMD_SET_UNSHARE_ALL, &cmd->rc, &cmd->rrc);24842355 KVM_UV_EVENT(kvm, 3, "PROTVIRT UNSHARE: rc %x rrc %x",24852356 cmd->rc, cmd->rrc);23572357+ break;23582358+ }23592359+ case KVM_PV_INFO: {23602360+ struct kvm_s390_pv_info info = {};23612361+ ssize_t data_len;23622362+23632363+ /*23642364+ * No need to check the VM protection here.23652365+ *23662366+ * Maybe user space wants to query some of the data23672367+ * when the VM is still unprotected. If we see the23682368+ * need to fence a new data command we can still23692369+ * return an error in the info handler.23702370+ */23712371+23722372+ r = -EFAULT;23732373+ if (copy_from_user(&info, argp, sizeof(info.header)))23742374+ break;23752375+23762376+ r = -EINVAL;23772377+ if (info.header.len_max < sizeof(info.header))23782378+ break;23792379+23802380+ data_len = kvm_s390_handle_pv_info(&info);23812381+ if (data_len < 0) {23822382+ r = data_len;23832383+ break;23842384+ }23852385+ /*23862386+ * If a data command struct is extended (multiple23872387+ * times) this can be used to determine how much of it23882388+ * is valid.23892389+ */23902390+ info.header.len_written = data_len;23912391+23922392+ r = -EFAULT;23932393+ if (copy_to_user(argp, &info, data_len))23942394+ break;23952395+23962396+ r = 0;23972397+ break;23982398+ }23992399+ case KVM_PV_DUMP: {24002400+ struct kvm_s390_pv_dmp dmp;24012401+24022402+ r = -EINVAL;24032403+ if (!kvm_s390_pv_is_protected(kvm))24042404+ break;24052405+24062406+ r = -EFAULT;24072407+ if (copy_from_user(&dmp, argp, sizeof(dmp)))24082408+ break;24092409+24102410+ r = kvm_s390_pv_dmp(kvm, cmd, dmp);24112411+ if (r)24122412+ break;24132413+24142414+ if (copy_to_user(argp, &dmp, sizeof(dmp))) {24152415+ r = -EFAULT;24162416+ break;24172417+ }24182418+24862419 break;24872420 }24882421 default:···46644473 struct kvm_run *kvm_run = vcpu->run;46654474 int rc;4666447544764476+ /*44774477+ * Running a VM while dumping always has the potential to44784478+ * produce inconsistent dump data. But for PV vcpus a SIE44794479+ * entry while dumping could also lead to a fatal validity44804480+ * intercept which we absolutely want to avoid.44814481+ */44824482+ if (vcpu->kvm->arch.pv.dumping)44834483+ return -EINVAL;44844484+46674485 if (kvm_run->immediate_exit)46684486 return -EINTR;46694487···51124912 return -ENOIOCTLCMD;51134913}5114491449154915+static int kvm_s390_handle_pv_vcpu_dump(struct kvm_vcpu *vcpu,49164916+ struct kvm_pv_cmd *cmd)49174917+{49184918+ struct kvm_s390_pv_dmp dmp;49194919+ void *data;49204920+ int ret;49214921+49224922+ /* Dump initialization is a prerequisite */49234923+ if (!vcpu->kvm->arch.pv.dumping)49244924+ return -EINVAL;49254925+49264926+ if (copy_from_user(&dmp, (__u8 __user *)cmd->data, sizeof(dmp)))49274927+ return -EFAULT;49284928+49294929+ /* We only handle this subcmd right now */49304930+ if (dmp.subcmd != KVM_PV_DUMP_CPU)49314931+ return -EINVAL;49324932+49334933+ /* CPU dump length is the same as create cpu storage donation. */49344934+ if (dmp.buff_len != uv_info.guest_cpu_stor_len)49354935+ return -EINVAL;49364936+49374937+ data = kvzalloc(uv_info.guest_cpu_stor_len, GFP_KERNEL);49384938+ if (!data)49394939+ return -ENOMEM;49404940+49414941+ ret = kvm_s390_pv_dump_cpu(vcpu, data, &cmd->rc, &cmd->rrc);49424942+49434943+ VCPU_EVENT(vcpu, 3, "PROTVIRT DUMP CPU %d rc %x rrc %x",49444944+ vcpu->vcpu_id, cmd->rc, cmd->rrc);49454945+49464946+ if (ret)49474947+ ret = -EINVAL;49484948+49494949+ /* On success copy over the dump data */49504950+ if (!ret && copy_to_user((__u8 __user *)dmp.buff_addr, data, uv_info.guest_cpu_stor_len))49514951+ ret = -EFAULT;49524952+49534953+ kvfree(data);49544954+ return ret;49554955+}49564956+51154957long kvm_arch_vcpu_ioctl(struct file *filp,51164958 unsigned int ioctl, unsigned long arg)51174959{···53165074 r = kvm_s390_get_irq_state(vcpu,53175075 (__u8 __user *) irq_state.buf,53185076 irq_state.len);50775077+ break;50785078+ }50795079+ case KVM_S390_PV_CPU_COMMAND: {50805080+ struct kvm_pv_cmd cmd;50815081+50825082+ r = -EINVAL;50835083+ if (!is_prot_virt_host())50845084+ break;50855085+50865086+ r = -EFAULT;50875087+ if (copy_from_user(&cmd, argp, sizeof(cmd)))50885088+ break;50895089+50905090+ r = -EINVAL;50915091+ if (cmd.flags)50925092+ break;50935093+50945094+ /* We only handle this cmd right now */50955095+ if (cmd.cmd != KVM_PV_DUMP)50965096+ break;50975097+50985098+ r = kvm_s390_handle_pv_vcpu_dump(vcpu, &cmd);50995099+51005100+ /* Always copy over UV rc / rrc data */51015101+ if (copy_to_user((__u8 __user *)argp, &cmd.rc,51025102+ sizeof(cmd.rc) + sizeof(cmd.rrc)))51035103+ r = -EFAULT;53195104 break;53205105 }53215106 default:
···77 */88#include <linux/kvm.h>99#include <linux/kvm_host.h>1010+#include <linux/minmax.h>1011#include <linux/pagemap.h>1112#include <linux/sched/signal.h>1213#include <asm/gmap.h>···298297 if (cc)299298 return -EINVAL;300299 return 0;300300+}301301+302302+int kvm_s390_pv_dump_cpu(struct kvm_vcpu *vcpu, void *buff, u16 *rc, u16 *rrc)303303+{304304+ struct uv_cb_dump_cpu uvcb = {305305+ .header.cmd = UVC_CMD_DUMP_CPU,306306+ .header.len = sizeof(uvcb),307307+ .cpu_handle = vcpu->arch.pv.handle,308308+ .dump_area_origin = (u64)buff,309309+ };310310+ int cc;311311+312312+ cc = uv_call_sched(0, (u64)&uvcb);313313+ *rc = uvcb.header.rc;314314+ *rrc = uvcb.header.rrc;315315+ return cc;316316+}317317+318318+/* Size of the cache for the storage state dump data. 1MB for now */319319+#define DUMP_BUFF_LEN HPAGE_SIZE320320+321321+/**322322+ * kvm_s390_pv_dump_stor_state323323+ *324324+ * @kvm: pointer to the guest's KVM struct325325+ * @buff_user: Userspace pointer where we will write the results to326326+ * @gaddr: Starting absolute guest address for which the storage state327327+ * is requested.328328+ * @buff_user_len: Length of the buff_user buffer329329+ * @rc: Pointer to where the uvcb return code is stored330330+ * @rrc: Pointer to where the uvcb return reason code is stored331331+ *332332+ * Stores buff_len bytes of tweak component values to buff_user333333+ * starting with the 1MB block specified by the absolute guest address334334+ * (gaddr). The gaddr pointer will be updated with the last address335335+ * for which data was written when returning to userspace. buff_user336336+ * might be written to even if an error rc is returned. For instance337337+ * if we encounter a fault after writing the first page of data.338338+ *339339+ * Context: kvm->lock needs to be held340340+ *341341+ * Return:342342+ * 0 on success343343+ * -ENOMEM if allocating the cache fails344344+ * -EINVAL if gaddr is not aligned to 1MB345345+ * -EINVAL if buff_user_len is not aligned to uv_info.conf_dump_storage_state_len346346+ * -EINVAL if the UV call fails, rc and rrc will be set in this case347347+ * -EFAULT if copying the result to buff_user failed348348+ */349349+int kvm_s390_pv_dump_stor_state(struct kvm *kvm, void __user *buff_user,350350+ u64 *gaddr, u64 buff_user_len, u16 *rc, u16 *rrc)351351+{352352+ struct uv_cb_dump_stor_state uvcb = {353353+ .header.cmd = UVC_CMD_DUMP_CONF_STOR_STATE,354354+ .header.len = sizeof(uvcb),355355+ .config_handle = kvm->arch.pv.handle,356356+ .gaddr = *gaddr,357357+ .dump_area_origin = 0,358358+ };359359+ const u64 increment_len = uv_info.conf_dump_storage_state_len;360360+ size_t buff_kvm_size;361361+ size_t size_done = 0;362362+ u8 *buff_kvm = NULL;363363+ int cc, ret;364364+365365+ ret = -EINVAL;366366+ /* UV call processes 1MB guest storage chunks at a time */367367+ if (!IS_ALIGNED(*gaddr, HPAGE_SIZE))368368+ goto out;369369+370370+ /*371371+ * We provide the storage state for 1MB chunks of guest372372+ * storage. The buffer will need to be aligned to373373+ * conf_dump_storage_state_len so we don't end on a partial374374+ * chunk.375375+ */376376+ if (!buff_user_len ||377377+ !IS_ALIGNED(buff_user_len, increment_len))378378+ goto out;379379+380380+ /*381381+ * Allocate a buffer from which we will later copy to the user382382+ * process. We don't want userspace to dictate our buffer size383383+ * so we limit it to DUMP_BUFF_LEN.384384+ */385385+ ret = -ENOMEM;386386+ buff_kvm_size = min_t(u64, buff_user_len, DUMP_BUFF_LEN);387387+ buff_kvm = vzalloc(buff_kvm_size);388388+ if (!buff_kvm)389389+ goto out;390390+391391+ ret = 0;392392+ uvcb.dump_area_origin = (u64)buff_kvm;393393+ /* We will loop until the user buffer is filled or an error occurs */394394+ do {395395+ /* Get 1MB worth of guest storage state data */396396+ cc = uv_call_sched(0, (u64)&uvcb);397397+398398+ /* All or nothing */399399+ if (cc) {400400+ ret = -EINVAL;401401+ break;402402+ }403403+404404+ size_done += increment_len;405405+ uvcb.dump_area_origin += increment_len;406406+ buff_user_len -= increment_len;407407+ uvcb.gaddr += HPAGE_SIZE;408408+409409+ /* KVM Buffer full, time to copy to the process */410410+ if (!buff_user_len || size_done == DUMP_BUFF_LEN) {411411+ if (copy_to_user(buff_user, buff_kvm, size_done)) {412412+ ret = -EFAULT;413413+ break;414414+ }415415+416416+ buff_user += size_done;417417+ size_done = 0;418418+ uvcb.dump_area_origin = (u64)buff_kvm;419419+ }420420+ } while (buff_user_len);421421+422422+ /* Report back where we ended dumping */423423+ *gaddr = uvcb.gaddr;424424+425425+ /* Lets only log errors, we don't want to spam */426426+out:427427+ if (ret)428428+ KVM_UV_EVENT(kvm, 3,429429+ "PROTVIRT DUMP STORAGE STATE: addr %llx ret %d, uvcb rc %x rrc %x",430430+ uvcb.gaddr, ret, uvcb.header.rc, uvcb.header.rrc);431431+ *rc = uvcb.header.rc;432432+ *rrc = uvcb.header.rrc;433433+ vfree(buff_kvm);434434+435435+ return ret;436436+}437437+438438+/**439439+ * kvm_s390_pv_dump_complete440440+ *441441+ * @kvm: pointer to the guest's KVM struct442442+ * @buff_user: Userspace pointer where we will write the results to443443+ * @rc: Pointer to where the uvcb return code is stored444444+ * @rrc: Pointer to where the uvcb return reason code is stored445445+ *446446+ * Completes the dumping operation and writes the completion data to447447+ * user space.448448+ *449449+ * Context: kvm->lock needs to be held450450+ *451451+ * Return:452452+ * 0 on success453453+ * -ENOMEM if allocating the completion buffer fails454454+ * -EINVAL if the UV call fails, rc and rrc will be set in this case455455+ * -EFAULT if copying the result to buff_user failed456456+ */457457+int kvm_s390_pv_dump_complete(struct kvm *kvm, void __user *buff_user,458458+ u16 *rc, u16 *rrc)459459+{460460+ struct uv_cb_dump_complete complete = {461461+ .header.len = sizeof(complete),462462+ .header.cmd = UVC_CMD_DUMP_COMPLETE,463463+ .config_handle = kvm_s390_pv_get_handle(kvm),464464+ };465465+ u64 *compl_data;466466+ int ret;467467+468468+ /* Allocate dump area */469469+ compl_data = vzalloc(uv_info.conf_dump_finalize_len);470470+ if (!compl_data)471471+ return -ENOMEM;472472+ complete.dump_area_origin = (u64)compl_data;473473+474474+ ret = uv_call_sched(0, (u64)&complete);475475+ *rc = complete.header.rc;476476+ *rrc = complete.header.rrc;477477+ KVM_UV_EVENT(kvm, 3, "PROTVIRT DUMP COMPLETE: rc %x rrc %x",478478+ complete.header.rc, complete.header.rrc);479479+480480+ if (!ret) {481481+ /*482482+ * kvm_s390_pv_dealloc_vm() will also (mem)set483483+ * this to false on a reboot or other destroy484484+ * operation for this vm.485485+ */486486+ kvm->arch.pv.dumping = false;487487+ kvm_s390_vcpu_unblock_all(kvm);488488+ ret = copy_to_user(buff_user, compl_data, uv_info.conf_dump_finalize_len);489489+ if (ret)490490+ ret = -EFAULT;491491+ }492492+ vfree(compl_data);493493+ /* If the UVC returned an error, translate it to -EINVAL */494494+ if (ret > 0)495495+ ret = -EINVAL;496496+ return ret;301497}