qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200430' into staging

- update Linux headers to 5.7-rc3 (and virtio-net fixup)
- support for protected virtualization aka secure execution

# gpg: Signature made Thu 30 Apr 2020 10:41:31 BST
# gpg: using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF
# gpg: issuer "cohuck@redhat.com"
# gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [marginal]
# gpg: aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full]
# gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full]
# gpg: aka "Cornelia Huck <cohuck@kernel.org>" [marginal]
# gpg: aka "Cornelia Huck <cohuck@redhat.com>" [marginal]
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20200430:
s390x/s390-virtio-ccw: Fix build on systems without KVM
s390x/pv: Retry ioctls on -EINTR
s390x: protvirt: Fix stray error_report_err in s390_machine_protect
s390x: Add unpack facility feature to GA1
docs: system: Add protvirt docs
s390x: protvirt: Handle SIGP store status correctly
s390x: protvirt: Move IO control structures over SIDA
s390x: protvirt: Disable address checks for PV guest IO emulation
s390x: protvirt: Move diag 308 data over SIDA
s390x: protvirt: Set guest IPL PSW
s390x: protvirt: SCLP interpretation
s390x: protvirt: Move STSI data over SIDAD
s390x: Add SIDA memory ops
s390x: protvirt: KVM intercept changes
s390x: protvirt: Inhibit balloon when switching to protected mode
s390x: protvirt: Add migration blocker
s390x: protvirt: Support unpack facility
s390x: Move diagnose 308 subcodes and rcs into ipl.h
linux-headers: update against Linux 5.7-rc3
virtio-net: fix rsc_ext compat handling

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+1116 -98
+2
MAINTAINERS
··· 396 396 F: target/s390x/sigp.c 397 397 F: target/s390x/cpu_features*.[ch] 398 398 F: target/s390x/cpu_models.[ch] 399 + F: hw/s390x/pv.c 400 + F: include/hw/s390x/pv.h 399 401 F: hw/intc/s390_flic.c 400 402 F: hw/intc/s390_flic_kvm.c 401 403 F: include/hw/s390x/s390_flic.h
+60
docs/system/s390x/protvirt.rst
··· 1 + Protected Virtualization on s390x 2 + ================================= 3 + 4 + The memory and most of the registers of Protected Virtual Machines 5 + (PVMs) are encrypted or inaccessible to the hypervisor, effectively 6 + prohibiting VM introspection when the VM is running. At rest, PVMs are 7 + encrypted and can only be decrypted by the firmware, represented by an 8 + entity called Ultravisor, of specific IBM Z machines. 9 + 10 + 11 + Prerequisites 12 + ------------- 13 + 14 + To run PVMs, a machine with the Protected Virtualization feature, as 15 + indicated by the Ultravisor Call facility (stfle bit 158), is 16 + required. The Ultravisor needs to be initialized at boot by setting 17 + `prot_virt=1` on the host's kernel command line. 18 + 19 + Running PVMs requires using the KVM hypervisor. 20 + 21 + If those requirements are met, the capability `KVM_CAP_S390_PROTECTED` 22 + will indicate that KVM can support PVMs on that LPAR. 23 + 24 + 25 + QEMU Settings 26 + ------------- 27 + 28 + To indicate to the VM that it can transition into protected mode, the 29 + `Unpack facility` (stfle bit 161 represented by the feature 30 + `unpack`/`S390_FEAT_UNPACK`) needs to be part of the cpu model of 31 + the VM. 32 + 33 + All I/O devices need to use the IOMMU. 34 + Passthrough (vfio) devices are currently not supported. 35 + 36 + Host huge page backings are not supported. However guests can use huge 37 + pages as indicated by its facilities. 38 + 39 + 40 + Boot Process 41 + ------------ 42 + 43 + A secure guest image can either be loaded from disk or supplied on the 44 + QEMU command line. Booting from disk is done by the unmodified 45 + s390-ccw BIOS. I.e., the bootmap is interpreted, multiple components 46 + are read into memory and control is transferred to one of the 47 + components (zipl stage3). Stage3 does some fixups and then transfers 48 + control to some program residing in guest memory, which is normally 49 + the OS kernel. The secure image has another component prepended 50 + (stage3a) that uses the new diag308 subcodes 8 and 10 to trigger the 51 + transition into secure mode. 52 + 53 + Booting from the image supplied on the QEMU command line requires that 54 + the file passed via -kernel has the same memory layout as would result 55 + from the disk boot. This memory layout includes the encrypted 56 + components (kernel, initrd, cmdline), the stage3a loader and 57 + metadata. In case this boot method is used, the command line 58 + options -initrd and -cmdline are ineffective. The preparation of a PVM 59 + image is done via the `genprotimg` tool from the s390-tools 60 + collection.
+5
docs/system/target-s390x.rst
··· 24 24 .. toctree:: 25 25 s390x/vfio-ap 26 26 27 + Architectural features 28 + ====================== 29 + 30 + .. toctree:: 31 + s390x/protvirt
+2 -2
hw/net/virtio-net.c
··· 83 83 #define VIRTIO_NET_HDR_F_RSC_INFO 4 /* rsc_ext data in csum_ fields */ 84 84 #define VIRTIO_NET_F_RSC_EXT 61 85 85 86 + #endif 87 + 86 88 static inline __virtio16 *virtio_net_rsc_ext_num_packets( 87 89 struct virtio_net_hdr *hdr) 88 90 { ··· 94 96 { 95 97 return &hdr->csum_offset; 96 98 } 97 - 98 - #endif 99 99 100 100 static VirtIOFeature feature_sizes[] = { 101 101 {.flags = 1ULL << VIRTIO_NET_F_MAC,
+1
hw/s390x/Makefile.objs
··· 31 31 obj-$(CONFIG_KVM) += tod-kvm.o 32 32 obj-$(CONFIG_KVM) += s390-skeys-kvm.o 33 33 obj-$(CONFIG_KVM) += s390-stattrib-kvm.o 34 + obj-$(CONFIG_KVM) += pv.o 34 35 obj-y += s390-ccw.o 35 36 obj-y += ap-device.o 36 37 obj-y += ap-bridge.o
+56 -3
hw/s390x/ipl.c
··· 1 1 /* 2 2 * bootloader support 3 3 * 4 - * Copyright IBM, Corp. 2012 4 + * Copyright IBM, Corp. 2012, 2020 5 5 * 6 6 * Authors: 7 7 * Christian Borntraeger <borntraeger@de.ibm.com> 8 + * Janosch Frank <frankja@linux.ibm.com> 8 9 * 9 10 * This work is licensed under the terms of the GNU GPL, version 2 or (at your 10 11 * option) any later version. See the COPYING file in the top-level directory. ··· 27 28 #include "hw/s390x/vfio-ccw.h" 28 29 #include "hw/s390x/css.h" 29 30 #include "hw/s390x/ebcdic.h" 31 + #include "hw/s390x/pv.h" 30 32 #include "ipl.h" 31 33 #include "qemu/error-report.h" 32 34 #include "qemu/config-file.h" ··· 566 568 { 567 569 S390IPLState *ipl = get_ipl_device(); 568 570 569 - ipl->iplb = *iplb; 570 - ipl->iplb_valid = true; 571 + /* 572 + * The IPLB set and retrieved by subcodes 8/9 is completely 573 + * separate from the one managed via subcodes 5/6. 574 + */ 575 + if (iplb->pbt == S390_IPL_TYPE_PV) { 576 + ipl->iplb_pv = *iplb; 577 + ipl->iplb_valid_pv = true; 578 + } else { 579 + ipl->iplb = *iplb; 580 + ipl->iplb_valid = true; 581 + } 571 582 ipl->netboot = is_virtio_net_device(iplb); 572 583 update_machine_ipl_properties(iplb); 584 + } 585 + 586 + IplParameterBlock *s390_ipl_get_iplb_pv(void) 587 + { 588 + S390IPLState *ipl = get_ipl_device(); 589 + 590 + if (!ipl->iplb_valid_pv) { 591 + return NULL; 592 + } 593 + return &ipl->iplb_pv; 573 594 } 574 595 575 596 IplParameterBlock *s390_ipl_get_iplb(void) ··· 658 679 } 659 680 memcpy(addr + QIPL_ADDRESS, &ipl->qipl, sizeof(QemuIplParameters)); 660 681 cpu_physical_memory_unmap(addr, len, 1, len); 682 + } 683 + 684 + int s390_ipl_prepare_pv_header(void) 685 + { 686 + IplParameterBlock *ipib = s390_ipl_get_iplb_pv(); 687 + IPLBlockPV *ipib_pv = &ipib->pv; 688 + void *hdr = g_malloc(ipib_pv->pv_header_len); 689 + int rc; 690 + 691 + cpu_physical_memory_read(ipib_pv->pv_header_addr, hdr, 692 + ipib_pv->pv_header_len); 693 + rc = s390_pv_set_sec_parms((uintptr_t)hdr, 694 + ipib_pv->pv_header_len); 695 + g_free(hdr); 696 + return rc; 697 + } 698 + 699 + int s390_ipl_pv_unpack(void) 700 + { 701 + IplParameterBlock *ipib = s390_ipl_get_iplb_pv(); 702 + IPLBlockPV *ipib_pv = &ipib->pv; 703 + int i, rc = 0; 704 + 705 + for (i = 0; i < ipib_pv->num_comp; i++) { 706 + rc = s390_pv_unpack(ipib_pv->components[i].addr, 707 + TARGET_PAGE_ALIGN(ipib_pv->components[i].size), 708 + ipib_pv->components[i].tweak_pref); 709 + if (rc) { 710 + break; 711 + } 712 + } 713 + return rc; 661 714 } 662 715 663 716 void s390_ipl_prepare_cpu(S390CPU *cpu)
+102 -1
hw/s390x/ipl.h
··· 1 1 /* 2 2 * s390 IPL device 3 3 * 4 - * Copyright 2015 IBM Corp. 4 + * Copyright 2015, 2020 IBM Corp. 5 5 * Author(s): Zhang Fan <bjfanzh@cn.ibm.com> 6 + * Janosch Frank <frankja@linux.ibm.com> 6 7 * 7 8 * This work is licensed under the terms of the GNU GPL, version 2 or (at 8 9 * your option) any later version. See the COPYING file in the top-level ··· 13 14 #define HW_S390_IPL_H 14 15 15 16 #include "cpu.h" 17 + #include "exec/address-spaces.h" 16 18 #include "hw/qdev-core.h" 19 + 20 + struct IPLBlockPVComp { 21 + uint64_t tweak_pref; 22 + uint64_t addr; 23 + uint64_t size; 24 + } QEMU_PACKED; 25 + typedef struct IPLBlockPVComp IPLBlockPVComp; 26 + 27 + struct IPLBlockPV { 28 + uint8_t reserved18[87]; /* 0x18 */ 29 + uint8_t version; /* 0x6f */ 30 + uint32_t reserved70; /* 0x70 */ 31 + uint32_t num_comp; /* 0x74 */ 32 + uint64_t pv_header_addr; /* 0x78 */ 33 + uint64_t pv_header_len; /* 0x80 */ 34 + struct IPLBlockPVComp components[]; 35 + } QEMU_PACKED; 36 + typedef struct IPLBlockPV IPLBlockPV; 17 37 18 38 struct IplBlockCcw { 19 39 uint8_t reserved0[85]; ··· 71 91 union { 72 92 IplBlockCcw ccw; 73 93 IplBlockFcp fcp; 94 + IPLBlockPV pv; 74 95 IplBlockQemuScsi scsi; 75 96 }; 76 97 } QEMU_PACKED; ··· 85 106 86 107 int s390_ipl_set_loadparm(uint8_t *loadparm); 87 108 void s390_ipl_update_diag308(IplParameterBlock *iplb); 109 + int s390_ipl_prepare_pv_header(void); 110 + int s390_ipl_pv_unpack(void); 88 111 void s390_ipl_prepare_cpu(S390CPU *cpu); 89 112 IplParameterBlock *s390_ipl_get_iplb(void); 113 + IplParameterBlock *s390_ipl_get_iplb_pv(void); 90 114 91 115 enum s390_reset { 92 116 /* default is a reset not triggered by a CPU e.g. issued by QMP */ ··· 94 118 S390_RESET_REIPL, 95 119 S390_RESET_MODIFIED_CLEAR, 96 120 S390_RESET_LOAD_NORMAL, 121 + S390_RESET_PV, 97 122 }; 98 123 void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type); 99 124 void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type); ··· 133 158 /*< private >*/ 134 159 DeviceState parent_obj; 135 160 IplParameterBlock iplb; 161 + IplParameterBlock iplb_pv; 136 162 QemuIplParameters qipl; 137 163 uint64_t start_addr; 138 164 uint64_t compat_start_addr; ··· 140 166 uint64_t compat_bios_start_addr; 141 167 bool enforce_bios; 142 168 bool iplb_valid; 169 + bool iplb_valid_pv; 143 170 bool netboot; 144 171 /* reset related properties don't have to be migrated or reset */ 145 172 enum s390_reset reset_type; ··· 159 186 typedef struct S390IPLState S390IPLState; 160 187 QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong"); 161 188 189 + #define DIAG_308_RC_OK 0x0001 190 + #define DIAG_308_RC_NO_CONF 0x0102 191 + #define DIAG_308_RC_INVALID 0x0402 192 + #define DIAG_308_RC_NO_PV_CONF 0x0902 193 + #define DIAG_308_RC_INVAL_FOR_PV 0x0a02 194 + 195 + #define DIAG308_RESET_MOD_CLR 0 196 + #define DIAG308_RESET_LOAD_NORM 1 197 + #define DIAG308_LOAD_CLEAR 3 198 + #define DIAG308_LOAD_NORMAL_DUMP 4 199 + #define DIAG308_SET 5 200 + #define DIAG308_STORE 6 201 + #define DIAG308_PV_SET 8 202 + #define DIAG308_PV_STORE 9 203 + #define DIAG308_PV_START 10 204 + 162 205 #define S390_IPL_TYPE_FCP 0x00 163 206 #define S390_IPL_TYPE_CCW 0x02 207 + #define S390_IPL_TYPE_PV 0x05 164 208 #define S390_IPL_TYPE_QEMU_SCSI 0xff 165 209 166 210 #define S390_IPLB_HEADER_LEN 8 211 + #define S390_IPLB_MIN_PV_LEN 148 167 212 #define S390_IPLB_MIN_CCW_LEN 200 168 213 #define S390_IPLB_MIN_FCP_LEN 384 169 214 #define S390_IPLB_MIN_QEMU_SCSI_LEN 200 ··· 171 216 static inline bool iplb_valid_len(IplParameterBlock *iplb) 172 217 { 173 218 return be32_to_cpu(iplb->len) <= sizeof(IplParameterBlock); 219 + } 220 + 221 + static inline bool ipl_valid_pv_components(IplParameterBlock *iplb) 222 + { 223 + IPLBlockPV *ipib_pv = &iplb->pv; 224 + int i; 225 + 226 + if (ipib_pv->num_comp == 0) { 227 + return false; 228 + } 229 + 230 + for (i = 0; i < ipib_pv->num_comp; i++) { 231 + /* Addr must be 4k aligned */ 232 + if (ipib_pv->components[i].addr & ~TARGET_PAGE_MASK) { 233 + return false; 234 + } 235 + 236 + /* Tweak prefix is monotonically increasing with each component */ 237 + if (i < ipib_pv->num_comp - 1 && 238 + ipib_pv->components[i].tweak_pref >= 239 + ipib_pv->components[i + 1].tweak_pref) { 240 + return false; 241 + } 242 + } 243 + return true; 244 + } 245 + 246 + static inline bool ipl_valid_pv_header(IplParameterBlock *iplb) 247 + { 248 + IPLBlockPV *ipib_pv = &iplb->pv; 249 + 250 + if (ipib_pv->pv_header_len > 2 * TARGET_PAGE_SIZE) { 251 + return false; 252 + } 253 + 254 + if (!address_space_access_valid(&address_space_memory, 255 + ipib_pv->pv_header_addr, 256 + ipib_pv->pv_header_len, 257 + false, 258 + MEMTXATTRS_UNSPECIFIED)) { 259 + return false; 260 + } 261 + 262 + return true; 263 + } 264 + 265 + static inline bool iplb_valid_pv(IplParameterBlock *iplb) 266 + { 267 + if (iplb->pbt != S390_IPL_TYPE_PV || 268 + be32_to_cpu(iplb->len) < S390_IPLB_MIN_PV_LEN) { 269 + return false; 270 + } 271 + if (!ipl_valid_pv_header(iplb)) { 272 + return false; 273 + } 274 + return ipl_valid_pv_components(iplb); 174 275 } 175 276 176 277 static inline bool iplb_valid(IplParameterBlock *iplb)
+113
hw/s390x/pv.c
··· 1 + /* 2 + * Protected Virtualization functions 3 + * 4 + * Copyright IBM Corp. 2020 5 + * Author(s): 6 + * Janosch Frank <frankja@linux.ibm.com> 7 + * 8 + * This work is licensed under the terms of the GNU GPL, version 2 or (at 9 + * your option) any later version. See the COPYING file in the top-level 10 + * directory. 11 + */ 12 + #include "qemu/osdep.h" 13 + 14 + #include <linux/kvm.h> 15 + 16 + #include "cpu.h" 17 + #include "qemu/error-report.h" 18 + #include "sysemu/kvm.h" 19 + #include "hw/s390x/ipl.h" 20 + #include "hw/s390x/pv.h" 21 + 22 + static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data) 23 + { 24 + struct kvm_pv_cmd pv_cmd = { 25 + .cmd = cmd, 26 + .data = (uint64_t)data, 27 + }; 28 + int rc; 29 + 30 + do { 31 + rc = kvm_vm_ioctl(kvm_state, KVM_S390_PV_COMMAND, &pv_cmd); 32 + } while (rc == -EINTR); 33 + 34 + if (rc) { 35 + error_report("KVM PV command %d (%s) failed: header rc %x rrc %x " 36 + "IOCTL rc: %d", cmd, cmdname, pv_cmd.rc, pv_cmd.rrc, 37 + rc); 38 + } 39 + return rc; 40 + } 41 + 42 + /* 43 + * This macro lets us pass the command as a string to the function so 44 + * we can print it on an error. 45 + */ 46 + #define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data); 47 + #define s390_pv_cmd_exit(cmd, data) \ 48 + { \ 49 + int rc; \ 50 + \ 51 + rc = __s390_pv_cmd(cmd, #cmd, data);\ 52 + if (rc) { \ 53 + exit(1); \ 54 + } \ 55 + } 56 + 57 + int s390_pv_vm_enable(void) 58 + { 59 + return s390_pv_cmd(KVM_PV_ENABLE, NULL); 60 + } 61 + 62 + void s390_pv_vm_disable(void) 63 + { 64 + s390_pv_cmd_exit(KVM_PV_DISABLE, NULL); 65 + } 66 + 67 + int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) 68 + { 69 + struct kvm_s390_pv_sec_parm args = { 70 + .origin = origin, 71 + .length = length, 72 + }; 73 + 74 + return s390_pv_cmd(KVM_PV_SET_SEC_PARMS, &args); 75 + } 76 + 77 + /* 78 + * Called for each component in the SE type IPL parameter block 0. 79 + */ 80 + int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak) 81 + { 82 + struct kvm_s390_pv_unp args = { 83 + .addr = addr, 84 + .size = size, 85 + .tweak = tweak, 86 + }; 87 + 88 + return s390_pv_cmd(KVM_PV_UNPACK, &args); 89 + } 90 + 91 + void s390_pv_perf_clear_reset(void) 92 + { 93 + s390_pv_cmd_exit(KVM_PV_PREP_RESET, NULL); 94 + } 95 + 96 + int s390_pv_verify(void) 97 + { 98 + return s390_pv_cmd(KVM_PV_VERIFY, NULL); 99 + } 100 + 101 + void s390_pv_unshare(void) 102 + { 103 + s390_pv_cmd_exit(KVM_PV_UNSHARE_ALL, NULL); 104 + } 105 + 106 + void s390_pv_inject_reset_error(CPUState *cs) 107 + { 108 + int r1 = (cs->kvm_run->s390_sieic.ipa & 0x00f0) >> 4; 109 + CPUS390XState *env = &S390_CPU(cs)->env; 110 + 111 + /* Report that we are unable to enter protected mode */ 112 + env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV; 113 + }
+133 -4
hw/s390x/s390-virtio-ccw.c
··· 1 1 /* 2 2 * virtio ccw machine 3 3 * 4 - * Copyright 2012 IBM Corp. 4 + * Copyright 2012, 2020 IBM Corp. 5 5 * Copyright (c) 2009 Alexander Graf <agraf@suse.de> 6 6 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> 7 + * Janosch Frank <frankja@linux.ibm.com> 7 8 * 8 9 * This work is licensed under the terms of the GNU GPL, version 2 or (at 9 10 * your option) any later version. See the COPYING file in the top-level ··· 42 43 #include "hw/qdev-properties.h" 43 44 #include "hw/s390x/tod.h" 44 45 #include "sysemu/sysemu.h" 46 + #include "sysemu/balloon.h" 47 + #include "hw/s390x/pv.h" 48 + #include "migration/blocker.h" 49 + 50 + static Error *pv_mig_blocker; 45 51 46 52 S390CPU *s390_cpu_addr2state(uint16_t cpu_addr) 47 53 { ··· 317 323 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); 318 324 } 319 325 326 + static void s390_machine_unprotect(S390CcwMachineState *ms) 327 + { 328 + s390_pv_vm_disable(); 329 + ms->pv = false; 330 + migrate_del_blocker(pv_mig_blocker); 331 + error_free_or_abort(&pv_mig_blocker); 332 + qemu_balloon_inhibit(false); 333 + } 334 + 335 + static int s390_machine_protect(S390CcwMachineState *ms) 336 + { 337 + Error *local_err = NULL; 338 + int rc; 339 + 340 + /* 341 + * Ballooning on protected VMs needs support in the guest for 342 + * sharing and unsharing balloon pages. Block ballooning for 343 + * now, until we have a solution to make at least Linux guests 344 + * either support it or fail gracefully. 345 + */ 346 + qemu_balloon_inhibit(true); 347 + error_setg(&pv_mig_blocker, 348 + "protected VMs are currently not migrateable."); 349 + rc = migrate_add_blocker(pv_mig_blocker, &local_err); 350 + if (rc) { 351 + qemu_balloon_inhibit(false); 352 + error_report_err(local_err); 353 + error_free_or_abort(&pv_mig_blocker); 354 + return rc; 355 + } 356 + 357 + /* Create SE VM */ 358 + rc = s390_pv_vm_enable(); 359 + if (rc) { 360 + qemu_balloon_inhibit(false); 361 + migrate_del_blocker(pv_mig_blocker); 362 + error_free_or_abort(&pv_mig_blocker); 363 + return rc; 364 + } 365 + 366 + ms->pv = true; 367 + 368 + /* Set SE header and unpack */ 369 + rc = s390_ipl_prepare_pv_header(); 370 + if (rc) { 371 + goto out_err; 372 + } 373 + 374 + /* Decrypt image */ 375 + rc = s390_ipl_pv_unpack(); 376 + if (rc) { 377 + goto out_err; 378 + } 379 + 380 + /* Verify integrity */ 381 + rc = s390_pv_verify(); 382 + if (rc) { 383 + goto out_err; 384 + } 385 + return rc; 386 + 387 + out_err: 388 + s390_machine_unprotect(ms); 389 + return rc; 390 + } 391 + 392 + static void s390_pv_prepare_reset(S390CcwMachineState *ms) 393 + { 394 + CPUState *cs; 395 + 396 + if (!s390_is_pv()) { 397 + return; 398 + } 399 + /* Unsharing requires all cpus to be stopped */ 400 + CPU_FOREACH(cs) { 401 + s390_cpu_set_state(S390_CPU_STATE_STOPPED, S390_CPU(cs)); 402 + } 403 + s390_pv_unshare(); 404 + s390_pv_perf_clear_reset(); 405 + } 406 + 320 407 static void s390_machine_reset(MachineState *machine) 321 408 { 409 + S390CcwMachineState *ms = S390_CCW_MACHINE(machine); 322 410 enum s390_reset reset_type; 323 411 CPUState *cs, *t; 412 + S390CPU *cpu; 324 413 325 414 /* get the reset parameters, reset them once done */ 326 415 s390_ipl_get_reset_request(&cs, &reset_type); 327 416 328 417 /* all CPUs are paused and synchronized at this point */ 329 418 s390_cmma_reset(); 419 + 420 + cpu = S390_CPU(cs); 330 421 331 422 switch (reset_type) { 332 423 case S390_RESET_EXTERNAL: 333 424 case S390_RESET_REIPL: 425 + if (s390_is_pv()) { 426 + s390_machine_unprotect(ms); 427 + } 428 + 334 429 qemu_devices_reset(); 335 430 s390_crypto_reset(); 336 431 ··· 338 433 run_on_cpu(cs, s390_do_cpu_ipl, RUN_ON_CPU_NULL); 339 434 break; 340 435 case S390_RESET_MODIFIED_CLEAR: 436 + /* 437 + * Susbsystem reset needs to be done before we unshare memory 438 + * and lose access to VIRTIO structures in guest memory. 439 + */ 440 + subsystem_reset(); 441 + s390_crypto_reset(); 442 + s390_pv_prepare_reset(ms); 341 443 CPU_FOREACH(t) { 342 444 run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL); 343 445 } 344 - subsystem_reset(); 345 - s390_crypto_reset(); 346 446 run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL); 347 447 break; 348 448 case S390_RESET_LOAD_NORMAL: 449 + /* 450 + * Susbsystem reset needs to be done before we unshare memory 451 + * and lose access to VIRTIO structures in guest memory. 452 + */ 453 + subsystem_reset(); 454 + s390_pv_prepare_reset(ms); 349 455 CPU_FOREACH(t) { 350 456 if (t == cs) { 351 457 continue; 352 458 } 353 459 run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL); 354 460 } 355 - subsystem_reset(); 356 461 run_on_cpu(cs, s390_do_cpu_initial_reset, RUN_ON_CPU_NULL); 462 + run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL); 463 + break; 464 + case S390_RESET_PV: /* Subcode 10 */ 465 + subsystem_reset(); 466 + s390_crypto_reset(); 467 + 468 + CPU_FOREACH(t) { 469 + if (t == cs) { 470 + continue; 471 + } 472 + run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL); 473 + } 474 + run_on_cpu(cs, s390_do_cpu_reset, RUN_ON_CPU_NULL); 475 + 476 + if (s390_machine_protect(ms)) { 477 + s390_pv_inject_reset_error(cs); 478 + /* 479 + * Continue after the diag308 so the guest knows something 480 + * went wrong. 481 + */ 482 + s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); 483 + return; 484 + } 485 + 357 486 run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL); 358 487 break; 359 488 default:
+45 -11
hw/s390x/sclp.c
··· 33 33 return sclp; 34 34 } 35 35 36 + static inline bool sclp_command_code_valid(uint32_t code) 37 + { 38 + switch (code & SCLP_CMD_CODE_MASK) { 39 + case SCLP_CMDW_READ_SCP_INFO: 40 + case SCLP_CMDW_READ_SCP_INFO_FORCED: 41 + case SCLP_CMDW_READ_CPU_INFO: 42 + case SCLP_CMDW_CONFIGURE_IOA: 43 + case SCLP_CMDW_DECONFIGURE_IOA: 44 + case SCLP_CMD_READ_EVENT_DATA: 45 + case SCLP_CMD_WRITE_EVENT_DATA: 46 + case SCLP_CMD_WRITE_EVENT_MASK: 47 + return true; 48 + } 49 + return false; 50 + } 51 + 36 52 static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int *count) 37 53 { 38 54 MachineState *ms = MACHINE(qdev_get_machine()); ··· 193 209 } 194 210 } 195 211 212 + /* 213 + * We only need the address to have something valid for the 214 + * service_interrupt call. 215 + */ 216 + #define SCLP_PV_DUMMY_ADDR 0x4000 217 + int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb, 218 + uint32_t code) 219 + { 220 + SCLPDevice *sclp = get_sclp_device(); 221 + SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp); 222 + SCCB work_sccb; 223 + hwaddr sccb_len = sizeof(SCCB); 224 + 225 + s390_cpu_pv_mem_read(env_archcpu(env), 0, &work_sccb, sccb_len); 226 + 227 + if (!sclp_command_code_valid(code)) { 228 + work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND); 229 + goto out_write; 230 + } 231 + 232 + sclp_c->execute(sclp, &work_sccb, code); 233 + out_write: 234 + s390_cpu_pv_mem_write(env_archcpu(env), 0, &work_sccb, 235 + be16_to_cpu(work_sccb.h.length)); 236 + sclp_c->service_interrupt(sclp, SCLP_PV_DUMMY_ADDR); 237 + return 0; 238 + } 239 + 196 240 int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code) 197 241 { 198 242 SCLPDevice *sclp = get_sclp_device(); ··· 225 269 return -PGM_SPECIFICATION; 226 270 } 227 271 228 - switch (code & SCLP_CMD_CODE_MASK) { 229 - case SCLP_CMDW_READ_SCP_INFO: 230 - case SCLP_CMDW_READ_SCP_INFO_FORCED: 231 - case SCLP_CMDW_READ_CPU_INFO: 232 - case SCLP_CMDW_CONFIGURE_IOA: 233 - case SCLP_CMDW_DECONFIGURE_IOA: 234 - case SCLP_CMD_READ_EVENT_DATA: 235 - case SCLP_CMD_WRITE_EVENT_DATA: 236 - case SCLP_CMD_WRITE_EVENT_MASK: 237 - break; 238 - default: 272 + if (!sclp_command_code_valid(code)) { 239 273 work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND); 240 274 goto out_write; 241 275 }
+58
include/hw/s390x/pv.h
··· 1 + /* 2 + * Protected Virtualization header 3 + * 4 + * Copyright IBM Corp. 2020 5 + * Author(s): 6 + * Janosch Frank <frankja@linux.ibm.com> 7 + * 8 + * This work is licensed under the terms of the GNU GPL, version 2 or (at 9 + * your option) any later version. See the COPYING file in the top-level 10 + * directory. 11 + */ 12 + #ifndef HW_S390_PV_H 13 + #define HW_S390_PV_H 14 + 15 + #ifdef CONFIG_KVM 16 + #include "cpu.h" 17 + #include "hw/s390x/s390-virtio-ccw.h" 18 + 19 + static inline bool s390_is_pv(void) 20 + { 21 + static S390CcwMachineState *ccw; 22 + Object *obj; 23 + 24 + if (ccw) { 25 + return ccw->pv; 26 + } 27 + 28 + /* we have to bail out for the "none" machine */ 29 + obj = object_dynamic_cast(qdev_get_machine(), 30 + TYPE_S390_CCW_MACHINE); 31 + if (!obj) { 32 + return false; 33 + } 34 + ccw = S390_CCW_MACHINE(obj); 35 + return ccw->pv; 36 + } 37 + 38 + int s390_pv_vm_enable(void); 39 + void s390_pv_vm_disable(void); 40 + int s390_pv_set_sec_parms(uint64_t origin, uint64_t length); 41 + int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak); 42 + void s390_pv_perf_clear_reset(void); 43 + int s390_pv_verify(void); 44 + void s390_pv_unshare(void); 45 + void s390_pv_inject_reset_error(CPUState *cs); 46 + #else /* CONFIG_KVM */ 47 + static inline bool s390_is_pv(void) { return false; } 48 + static inline int s390_pv_vm_enable(void) { return 0; } 49 + static inline void s390_pv_vm_disable(void) {} 50 + static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) { return 0; } 51 + static inline int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak) { return 0; } 52 + static inline void s390_pv_perf_clear_reset(void) {} 53 + static inline int s390_pv_verify(void) { return 0; } 54 + static inline void s390_pv_unshare(void) {} 55 + static inline void s390_pv_inject_reset_error(CPUState *cs) {}; 56 + #endif /* CONFIG_KVM */ 57 + 58 + #endif /* HW_S390_PV_H */
+1
include/hw/s390x/s390-virtio-ccw.h
··· 28 28 /*< public >*/ 29 29 bool aes_key_wrap; 30 30 bool dea_key_wrap; 31 + bool pv; 31 32 uint8_t loadparm[8]; 32 33 } S390CcwMachineState; 33 34
+2
include/hw/s390x/sclp.h
··· 217 217 void sclp_service_interrupt(uint32_t sccb); 218 218 void raise_irq_cpu_hotplug(void); 219 219 int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code); 220 + int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb, 221 + uint32_t code); 220 222 221 223 #endif
+9 -1
include/standard-headers/linux/ethtool.h
··· 596 596 * @ETH_SS_LINK_MODES: link mode names 597 597 * @ETH_SS_MSG_CLASSES: debug message class names 598 598 * @ETH_SS_WOL_MODES: wake-on-lan modes 599 + * @ETH_SS_SOF_TIMESTAMPING: SOF_TIMESTAMPING_* flags 600 + * @ETH_SS_TS_TX_TYPES: timestamping Tx types 601 + * @ETH_SS_TS_RX_FILTERS: timestamping Rx filters 599 602 */ 600 603 enum ethtool_stringset { 601 604 ETH_SS_TEST = 0, ··· 610 613 ETH_SS_LINK_MODES, 611 614 ETH_SS_MSG_CLASSES, 612 615 ETH_SS_WOL_MODES, 616 + ETH_SS_SOF_TIMESTAMPING, 617 + ETH_SS_TS_TX_TYPES, 618 + ETH_SS_TS_RX_FILTERS, 613 619 614 620 /* add new constants above here */ 615 621 ETH_SS_COUNT ··· 1330 1336 ETHTOOL_FEC_OFF_BIT, 1331 1337 ETHTOOL_FEC_RS_BIT, 1332 1338 ETHTOOL_FEC_BASER_BIT, 1339 + ETHTOOL_FEC_LLRS_BIT, 1333 1340 }; 1334 1341 1335 1342 #define ETHTOOL_FEC_NONE (1 << ETHTOOL_FEC_NONE_BIT) ··· 1337 1344 #define ETHTOOL_FEC_OFF (1 << ETHTOOL_FEC_OFF_BIT) 1338 1345 #define ETHTOOL_FEC_RS (1 << ETHTOOL_FEC_RS_BIT) 1339 1346 #define ETHTOOL_FEC_BASER (1 << ETHTOOL_FEC_BASER_BIT) 1347 + #define ETHTOOL_FEC_LLRS (1 << ETHTOOL_FEC_LLRS_BIT) 1340 1348 1341 1349 /* CMDs currently supported */ 1342 1350 #define ETHTOOL_GSET 0x00000001 /* DEPRECATED, Get settings. ··· 1521 1529 ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT = 71, 1522 1530 ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT = 72, 1523 1531 ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT = 73, 1524 - 1532 + ETHTOOL_LINK_MODE_FEC_LLRS_BIT = 74, 1525 1533 /* must be last entry */ 1526 1534 __ETHTOOL_LINK_MODE_MASK_NBITS 1527 1535 };
+4 -1
include/standard-headers/linux/input-event-codes.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 1 + /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ 2 2 /* 3 3 * Input event codes 4 4 * ··· 651 651 #define KEY_ONSCREEN_KEYBOARD 0x278 652 652 /* Electronic privacy screen control */ 653 653 #define KEY_PRIVACY_SCREEN_TOGGLE 0x279 654 + 655 + /* Select an area of screen to be copied */ 656 + #define KEY_SELECTIVE_SCREENSHOT 0x27a 654 657 655 658 /* 656 659 * Some keyboards have keys which do not have a defined meaning, these keys
+2
include/standard-headers/linux/pci_regs.h
··· 605 605 #define PCI_EXP_SLTCTL_PWR_OFF 0x0400 /* Power Off */ 606 606 #define PCI_EXP_SLTCTL_EIC 0x0800 /* Electromechanical Interlock Control */ 607 607 #define PCI_EXP_SLTCTL_DLLSCE 0x1000 /* Data Link Layer State Changed Enable */ 608 + #define PCI_EXP_SLTCTL_IBPD_DISABLE 0x4000 /* In-band PD disable */ 608 609 #define PCI_EXP_SLTSTA 26 /* Slot Status */ 609 610 #define PCI_EXP_SLTSTA_ABP 0x0001 /* Attention Button Pressed */ 610 611 #define PCI_EXP_SLTSTA_PFD 0x0002 /* Power Fault Detected */ ··· 680 681 #define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ 681 682 #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52 /* v2 endpoints with link end here */ 682 683 #define PCI_EXP_SLTCAP2 52 /* Slot Capabilities 2 */ 684 + #define PCI_EXP_SLTCAP2_IBPD 0x00000001 /* In-band PD Disable Supported */ 683 685 #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ 684 686 #define PCI_EXP_SLTSTA2 58 /* Slot Status 2 */ 685 687
+8
include/standard-headers/linux/vhost_types.h
··· 119 119 unsigned short reserved; 120 120 }; 121 121 122 + /* VHOST_VDPA specific definitions */ 123 + 124 + struct vhost_vdpa_config { 125 + uint32_t off; 126 + uint32_t len; 127 + uint8_t buf[0]; 128 + }; 129 + 122 130 /* Feature bits */ 123 131 /* Log all write descriptors. Can be changed while device is active. */ 124 132 #define VHOST_F_LOG_ALL 26
+10 -2
include/standard-headers/linux/virtio_balloon.h
··· 36 36 #define VIRTIO_BALLOON_F_DEFLATE_ON_OOM 2 /* Deflate balloon on OOM */ 37 37 #define VIRTIO_BALLOON_F_FREE_PAGE_HINT 3 /* VQ to report free pages */ 38 38 #define VIRTIO_BALLOON_F_PAGE_POISON 4 /* Guest is using page poisoning */ 39 + #define VIRTIO_BALLOON_F_REPORTING 5 /* Page reporting virtqueue */ 39 40 40 41 /* Size of a PFN in the balloon interface. */ 41 42 #define VIRTIO_BALLOON_PFN_SHIFT 12 ··· 47 48 uint32_t num_pages; 48 49 /* Number of pages we've actually got in balloon. */ 49 50 uint32_t actual; 50 - /* Free page report command id, readonly by guest */ 51 - uint32_t free_page_report_cmd_id; 51 + /* 52 + * Free page hint command id, readonly by guest. 53 + * Was previously named free_page_report_cmd_id so we 54 + * need to carry that name for legacy support. 55 + */ 56 + union { 57 + uint32_t free_page_hint_cmd_id; 58 + uint32_t free_page_report_cmd_id; /* deprecated */ 59 + }; 52 60 /* Stores PAGE_POISON if page poisoning is in use */ 53 61 uint32_t poison_val; 54 62 };
+1
include/standard-headers/linux/virtio_ids.h
··· 46 46 #define VIRTIO_ID_IOMMU 23 /* virtio IOMMU */ 47 47 #define VIRTIO_ID_FS 26 /* virtio filesystem */ 48 48 #define VIRTIO_ID_PMEM 27 /* virtio pmem */ 49 + #define VIRTIO_ID_MAC80211_HWSIM 29 /* virtio mac80211-hwsim */ 49 50 50 51 #endif /* _LINUX_VIRTIO_IDS_H */
+98 -4
include/standard-headers/linux/virtio_net.h
··· 57 57 * Steering */ 58 58 #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ 59 59 60 + #define VIRTIO_NET_F_HASH_REPORT 57 /* Supports hash report */ 61 + #define VIRTIO_NET_F_RSS 60 /* Supports RSS RX steering */ 62 + #define VIRTIO_NET_F_RSC_EXT 61 /* extended coalescing info */ 60 63 #define VIRTIO_NET_F_STANDBY 62 /* Act as standby for another device 61 64 * with the same MAC. 62 65 */ ··· 69 72 #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ 70 73 #define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */ 71 74 75 + /* supported/enabled hash types */ 76 + #define VIRTIO_NET_RSS_HASH_TYPE_IPv4 (1 << 0) 77 + #define VIRTIO_NET_RSS_HASH_TYPE_TCPv4 (1 << 1) 78 + #define VIRTIO_NET_RSS_HASH_TYPE_UDPv4 (1 << 2) 79 + #define VIRTIO_NET_RSS_HASH_TYPE_IPv6 (1 << 3) 80 + #define VIRTIO_NET_RSS_HASH_TYPE_TCPv6 (1 << 4) 81 + #define VIRTIO_NET_RSS_HASH_TYPE_UDPv6 (1 << 5) 82 + #define VIRTIO_NET_RSS_HASH_TYPE_IP_EX (1 << 6) 83 + #define VIRTIO_NET_RSS_HASH_TYPE_TCP_EX (1 << 7) 84 + #define VIRTIO_NET_RSS_HASH_TYPE_UDP_EX (1 << 8) 85 + 72 86 struct virtio_net_config { 73 87 /* The config defining mac address (if VIRTIO_NET_F_MAC) */ 74 88 uint8_t mac[ETH_ALEN]; ··· 92 106 * Any other value stands for unknown. 93 107 */ 94 108 uint8_t duplex; 109 + /* maximum size of RSS key */ 110 + uint8_t rss_max_key_size; 111 + /* maximum number of indirection table entries */ 112 + uint16_t rss_max_indirection_table_length; 113 + /* bitmask of supported VIRTIO_NET_RSS_HASH_ types */ 114 + uint32_t supported_hash_types; 95 115 } QEMU_PACKED; 96 116 97 117 /* ··· 104 124 struct virtio_net_hdr_v1 { 105 125 #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* Use csum_start, csum_offset */ 106 126 #define VIRTIO_NET_HDR_F_DATA_VALID 2 /* Csum is valid */ 127 + #define VIRTIO_NET_HDR_F_RSC_INFO 4 /* rsc info in csum_ fields */ 107 128 uint8_t flags; 108 129 #define VIRTIO_NET_HDR_GSO_NONE 0 /* Not a GSO frame */ 109 130 #define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */ ··· 113 134 uint8_t gso_type; 114 135 __virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */ 115 136 __virtio16 gso_size; /* Bytes to append to hdr_len per frame */ 116 - __virtio16 csum_start; /* Position to start checksumming from */ 117 - __virtio16 csum_offset; /* Offset after that to place checksum */ 137 + union { 138 + struct { 139 + __virtio16 csum_start; 140 + __virtio16 csum_offset; 141 + }; 142 + /* Checksum calculation */ 143 + struct { 144 + /* Position to start checksumming from */ 145 + __virtio16 start; 146 + /* Offset after that to place checksum */ 147 + __virtio16 offset; 148 + } csum; 149 + /* Receive Segment Coalescing */ 150 + struct { 151 + /* Number of coalesced segments */ 152 + uint16_t segments; 153 + /* Number of duplicated acks */ 154 + uint16_t dup_acks; 155 + } rsc; 156 + }; 118 157 __virtio16 num_buffers; /* Number of merged rx buffers */ 119 158 }; 120 159 160 + struct virtio_net_hdr_v1_hash { 161 + struct virtio_net_hdr_v1 hdr; 162 + uint32_t hash_value; 163 + #define VIRTIO_NET_HASH_REPORT_NONE 0 164 + #define VIRTIO_NET_HASH_REPORT_IPv4 1 165 + #define VIRTIO_NET_HASH_REPORT_TCPv4 2 166 + #define VIRTIO_NET_HASH_REPORT_UDPv4 3 167 + #define VIRTIO_NET_HASH_REPORT_IPv6 4 168 + #define VIRTIO_NET_HASH_REPORT_TCPv6 5 169 + #define VIRTIO_NET_HASH_REPORT_UDPv6 6 170 + #define VIRTIO_NET_HASH_REPORT_IPv6_EX 7 171 + #define VIRTIO_NET_HASH_REPORT_TCPv6_EX 8 172 + #define VIRTIO_NET_HASH_REPORT_UDPv6_EX 9 173 + uint16_t hash_report; 174 + uint16_t padding; 175 + }; 176 + 121 177 #ifndef VIRTIO_NET_NO_LEGACY 122 178 /* This header comes first in the scatter-gather list. 123 179 * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, it must ··· 228 284 229 285 /* 230 286 * Control Receive Flow Steering 231 - * 287 + */ 288 + #define VIRTIO_NET_CTRL_MQ 4 289 + /* 232 290 * The command VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 233 291 * enables Receive Flow Steering, specifying the number of the transmit and 234 292 * receive queues that will be used. After the command is consumed and acked by ··· 241 299 __virtio16 virtqueue_pairs; 242 300 }; 243 301 244 - #define VIRTIO_NET_CTRL_MQ 4 245 302 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0 246 303 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1 247 304 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000 305 + 306 + /* 307 + * The command VIRTIO_NET_CTRL_MQ_RSS_CONFIG has the same effect as 308 + * VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET does and additionally configures 309 + * the receive steering to use a hash calculated for incoming packet 310 + * to decide on receive virtqueue to place the packet. The command 311 + * also provides parameters to calculate a hash and receive virtqueue. 312 + */ 313 + struct virtio_net_rss_config { 314 + uint32_t hash_types; 315 + uint16_t indirection_table_mask; 316 + uint16_t unclassified_queue; 317 + uint16_t indirection_table[1/* + indirection_table_mask */]; 318 + uint16_t max_tx_vq; 319 + uint8_t hash_key_length; 320 + uint8_t hash_key_data[/* hash_key_length */]; 321 + }; 322 + 323 + #define VIRTIO_NET_CTRL_MQ_RSS_CONFIG 1 324 + 325 + /* 326 + * The command VIRTIO_NET_CTRL_MQ_HASH_CONFIG requests the device 327 + * to include in the virtio header of the packet the value of the 328 + * calculated hash and the report type of hash. It also provides 329 + * parameters for hash calculation. The command requires feature 330 + * VIRTIO_NET_F_HASH_REPORT to be negotiated to extend the 331 + * layout of virtio header as defined in virtio_net_hdr_v1_hash. 332 + */ 333 + struct virtio_net_hash_config { 334 + uint32_t hash_types; 335 + /* for compatibility with virtio_net_rss_config */ 336 + uint16_t reserved[4]; 337 + uint8_t hash_key_length; 338 + uint8_t hash_key_data[/* hash_key_length */]; 339 + }; 340 + 341 + #define VIRTIO_NET_CTRL_MQ_HASH_CONFIG 2 248 342 249 343 /* 250 344 * Control network offloads
+2
linux-headers/COPYING
··· 16 16 Documentation/process/license-rules.rst 17 17 18 18 for more details. 19 + 20 + All contributions to the Linux Kernel are subject to this COPYING file.
+1
linux-headers/asm-x86/kvm.h
··· 390 390 #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 391 391 #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 392 392 #define KVM_STATE_NESTED_EVMCS 0x00000004 393 + #define KVM_STATE_NESTED_MTF_PENDING 0x00000008 393 394 394 395 #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 395 396 #define KVM_STATE_NESTED_SMM_VMXON 0x00000002
+1
linux-headers/asm-x86/unistd_32.h
··· 429 429 #define __NR_openat2 437 430 430 #define __NR_pidfd_getfd 438 431 431 432 + 432 433 #endif /* _ASM_X86_UNISTD_32_H */
+1
linux-headers/asm-x86/unistd_64.h
··· 351 351 #define __NR_openat2 437 352 352 #define __NR_pidfd_getfd 438 353 353 354 + 354 355 #endif /* _ASM_X86_UNISTD_64_H */
+1
linux-headers/asm-x86/unistd_x32.h
··· 340 340 #define __NR_preadv2 (__X32_SYSCALL_BIT + 546) 341 341 #define __NR_pwritev2 (__X32_SYSCALL_BIT + 547) 342 342 343 + 343 344 #endif /* _ASM_X86_UNISTD_X32_H */
+45 -2
linux-headers/linux/kvm.h
··· 474 474 __u32 size; /* amount of bytes */ 475 475 __u32 op; /* type of operation */ 476 476 __u64 buf; /* buffer in userspace */ 477 - __u8 ar; /* the access register number */ 478 - __u8 reserved[31]; /* should be set to 0 */ 477 + union { 478 + __u8 ar; /* the access register number */ 479 + __u32 sida_offset; /* offset into the sida */ 480 + __u8 reserved[32]; /* should be set to 0 */ 481 + }; 479 482 }; 480 483 /* types for kvm_s390_mem_op->op */ 481 484 #define KVM_S390_MEMOP_LOGICAL_READ 0 482 485 #define KVM_S390_MEMOP_LOGICAL_WRITE 1 486 + #define KVM_S390_MEMOP_SIDA_READ 2 487 + #define KVM_S390_MEMOP_SIDA_WRITE 3 483 488 /* flags for kvm_s390_mem_op->flags */ 484 489 #define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0) 485 490 #define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1) ··· 1010 1015 #define KVM_CAP_ARM_NISV_TO_USER 177 1011 1016 #define KVM_CAP_ARM_INJECT_EXT_DABT 178 1012 1017 #define KVM_CAP_S390_VCPU_RESETS 179 1018 + #define KVM_CAP_S390_PROTECTED 180 1019 + #define KVM_CAP_PPC_SECURE_GUEST 181 1013 1020 1014 1021 #ifdef KVM_CAP_IRQ_ROUTING 1015 1022 ··· 1478 1485 #define KVM_S390_NORMAL_RESET _IO(KVMIO, 0xc3) 1479 1486 #define KVM_S390_CLEAR_RESET _IO(KVMIO, 0xc4) 1480 1487 1488 + struct kvm_s390_pv_sec_parm { 1489 + __u64 origin; 1490 + __u64 length; 1491 + }; 1492 + 1493 + struct kvm_s390_pv_unp { 1494 + __u64 addr; 1495 + __u64 size; 1496 + __u64 tweak; 1497 + }; 1498 + 1499 + enum pv_cmd_id { 1500 + KVM_PV_ENABLE, 1501 + KVM_PV_DISABLE, 1502 + KVM_PV_SET_SEC_PARMS, 1503 + KVM_PV_UNPACK, 1504 + KVM_PV_VERIFY, 1505 + KVM_PV_PREP_RESET, 1506 + KVM_PV_UNSHARE_ALL, 1507 + }; 1508 + 1509 + struct kvm_pv_cmd { 1510 + __u32 cmd; /* Command to be executed */ 1511 + __u16 rc; /* Ultravisor return code */ 1512 + __u16 rrc; /* Ultravisor return reason code */ 1513 + __u64 data; /* Data or address */ 1514 + __u32 flags; /* flags for future extensions. Must be 0 for now */ 1515 + __u32 reserved[3]; 1516 + }; 1517 + 1518 + /* Available with KVM_CAP_S390_PROTECTED */ 1519 + #define KVM_S390_PV_COMMAND _IOWR(KVMIO, 0xc5, struct kvm_pv_cmd) 1520 + 1481 1521 /* Secure Encrypted Virtualization command */ 1482 1522 enum sev_cmd_id { 1483 1523 /* Guest initialization commands */ ··· 1627 1667 1628 1668 #define KVM_HYPERV_CONN_ID_MASK 0x00ffffff 1629 1669 #define KVM_HYPERV_EVENTFD_DEASSIGN (1 << 0) 1670 + 1671 + #define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (1 << 0) 1672 + #define KVM_DIRTY_LOG_INITIALLY_SET (1 << 1) 1630 1673 1631 1674 #endif /* __LINUX_KVM_H */
+3 -2
linux-headers/linux/mman.h
··· 5 5 #include <asm/mman.h> 6 6 #include <asm-generic/hugetlb_encode.h> 7 7 8 - #define MREMAP_MAYMOVE 1 9 - #define MREMAP_FIXED 2 8 + #define MREMAP_MAYMOVE 1 9 + #define MREMAP_FIXED 2 10 + #define MREMAP_DONTUNMAP 4 10 11 11 12 #define OVERCOMMIT_GUESS 0 12 13 #define OVERCOMMIT_ALWAYS 1
+33 -7
linux-headers/linux/userfaultfd.h
··· 19 19 * means the userland is reading). 20 20 */ 21 21 #define UFFD_API ((__u64)0xAA) 22 - #define UFFD_API_FEATURES (UFFD_FEATURE_EVENT_FORK | \ 22 + #define UFFD_API_FEATURES (UFFD_FEATURE_PAGEFAULT_FLAG_WP | \ 23 + UFFD_FEATURE_EVENT_FORK | \ 23 24 UFFD_FEATURE_EVENT_REMAP | \ 24 25 UFFD_FEATURE_EVENT_REMOVE | \ 25 26 UFFD_FEATURE_EVENT_UNMAP | \ ··· 34 35 #define UFFD_API_RANGE_IOCTLS \ 35 36 ((__u64)1 << _UFFDIO_WAKE | \ 36 37 (__u64)1 << _UFFDIO_COPY | \ 37 - (__u64)1 << _UFFDIO_ZEROPAGE) 38 + (__u64)1 << _UFFDIO_ZEROPAGE | \ 39 + (__u64)1 << _UFFDIO_WRITEPROTECT) 38 40 #define UFFD_API_RANGE_IOCTLS_BASIC \ 39 41 ((__u64)1 << _UFFDIO_WAKE | \ 40 42 (__u64)1 << _UFFDIO_COPY) ··· 52 54 #define _UFFDIO_WAKE (0x02) 53 55 #define _UFFDIO_COPY (0x03) 54 56 #define _UFFDIO_ZEROPAGE (0x04) 57 + #define _UFFDIO_WRITEPROTECT (0x06) 55 58 #define _UFFDIO_API (0x3F) 56 59 57 60 /* userfaultfd ioctl ids */ ··· 68 71 struct uffdio_copy) 69 72 #define UFFDIO_ZEROPAGE _IOWR(UFFDIO, _UFFDIO_ZEROPAGE, \ 70 73 struct uffdio_zeropage) 74 + #define UFFDIO_WRITEPROTECT _IOWR(UFFDIO, _UFFDIO_WRITEPROTECT, \ 75 + struct uffdio_writeprotect) 71 76 72 77 /* read() structure */ 73 78 struct uffd_msg { ··· 203 208 __u64 dst; 204 209 __u64 src; 205 210 __u64 len; 211 + #define UFFDIO_COPY_MODE_DONTWAKE ((__u64)1<<0) 206 212 /* 207 - * There will be a wrprotection flag later that allows to map 208 - * pages wrprotected on the fly. And such a flag will be 209 - * available if the wrprotection ioctl are implemented for the 210 - * range according to the uffdio_register.ioctls. 213 + * UFFDIO_COPY_MODE_WP will map the page write protected on 214 + * the fly. UFFDIO_COPY_MODE_WP is available only if the 215 + * write protected ioctl is implemented for the range 216 + * according to the uffdio_register.ioctls. 211 217 */ 212 - #define UFFDIO_COPY_MODE_DONTWAKE ((__u64)1<<0) 218 + #define UFFDIO_COPY_MODE_WP ((__u64)1<<1) 213 219 __u64 mode; 214 220 215 221 /* ··· 229 235 * the copy_from_user will not read the last 8 bytes. 230 236 */ 231 237 __s64 zeropage; 238 + }; 239 + 240 + struct uffdio_writeprotect { 241 + struct uffdio_range range; 242 + /* 243 + * UFFDIO_WRITEPROTECT_MODE_WP: set the flag to write protect a range, 244 + * unset the flag to undo protection of a range which was previously 245 + * write protected. 246 + * 247 + * UFFDIO_WRITEPROTECT_MODE_DONTWAKE: set the flag to avoid waking up 248 + * any wait thread after the operation succeeds. 249 + * 250 + * NOTE: Write protecting a region (WP=1) is unrelated to page faults, 251 + * therefore DONTWAKE flag is meaningless with WP=1. Removing write 252 + * protection (WP=0) in response to a page fault wakes the faulting 253 + * task unless DONTWAKE is set. 254 + */ 255 + #define UFFDIO_WRITEPROTECT_MODE_WP ((__u64)1<<0) 256 + #define UFFDIO_WRITEPROTECT_MODE_DONTWAKE ((__u64)1<<1) 257 + __u64 mode; 232 258 }; 233 259 234 260 #endif /* _LINUX_USERFAULTFD_H */
+37
linux-headers/linux/vfio.h
··· 707 707 708 708 #define VFIO_DEVICE_IOEVENTFD _IO(VFIO_TYPE, VFIO_BASE + 16) 709 709 710 + /** 711 + * VFIO_DEVICE_FEATURE - _IORW(VFIO_TYPE, VFIO_BASE + 17, 712 + * struct vfio_device_feature) 713 + * 714 + * Get, set, or probe feature data of the device. The feature is selected 715 + * using the FEATURE_MASK portion of the flags field. Support for a feature 716 + * can be probed by setting both the FEATURE_MASK and PROBE bits. A probe 717 + * may optionally include the GET and/or SET bits to determine read vs write 718 + * access of the feature respectively. Probing a feature will return success 719 + * if the feature is supported and all of the optionally indicated GET/SET 720 + * methods are supported. The format of the data portion of the structure is 721 + * specific to the given feature. The data portion is not required for 722 + * probing. GET and SET are mutually exclusive, except for use with PROBE. 723 + * 724 + * Return 0 on success, -errno on failure. 725 + */ 726 + struct vfio_device_feature { 727 + __u32 argsz; 728 + __u32 flags; 729 + #define VFIO_DEVICE_FEATURE_MASK (0xffff) /* 16-bit feature index */ 730 + #define VFIO_DEVICE_FEATURE_GET (1 << 16) /* Get feature into data[] */ 731 + #define VFIO_DEVICE_FEATURE_SET (1 << 17) /* Set feature from data[] */ 732 + #define VFIO_DEVICE_FEATURE_PROBE (1 << 18) /* Probe feature support */ 733 + __u8 data[]; 734 + }; 735 + 736 + #define VFIO_DEVICE_FEATURE _IO(VFIO_TYPE, VFIO_BASE + 17) 737 + 738 + /* 739 + * Provide support for setting a PCI VF Token, which is used as a shared 740 + * secret between PF and VF drivers. This feature may only be set on a 741 + * PCI SR-IOV PF when SR-IOV is enabled on the PF and there are no existing 742 + * open VFs. Data provided when setting this feature is a 16-byte array 743 + * (__u8 b[16]), representing a UUID. 744 + */ 745 + #define VFIO_DEVICE_FEATURE_PCI_VF_TOKEN (0) 746 + 710 747 /* -------- API for Type1 VFIO IOMMU -------- */ 711 748 712 749 /**
+24
linux-headers/linux/vhost.h
··· 116 116 #define VHOST_VSOCK_SET_GUEST_CID _IOW(VHOST_VIRTIO, 0x60, __u64) 117 117 #define VHOST_VSOCK_SET_RUNNING _IOW(VHOST_VIRTIO, 0x61, int) 118 118 119 + /* VHOST_VDPA specific defines */ 120 + 121 + /* Get the device id. The device ids follow the same definition of 122 + * the device id defined in virtio-spec. 123 + */ 124 + #define VHOST_VDPA_GET_DEVICE_ID _IOR(VHOST_VIRTIO, 0x70, __u32) 125 + /* Get and set the status. The status bits follow the same definition 126 + * of the device status defined in virtio-spec. 127 + */ 128 + #define VHOST_VDPA_GET_STATUS _IOR(VHOST_VIRTIO, 0x71, __u8) 129 + #define VHOST_VDPA_SET_STATUS _IOW(VHOST_VIRTIO, 0x72, __u8) 130 + /* Get and set the device config. The device config follows the same 131 + * definition of the device config defined in virtio-spec. 132 + */ 133 + #define VHOST_VDPA_GET_CONFIG _IOR(VHOST_VIRTIO, 0x73, \ 134 + struct vhost_vdpa_config) 135 + #define VHOST_VDPA_SET_CONFIG _IOW(VHOST_VIRTIO, 0x74, \ 136 + struct vhost_vdpa_config) 137 + /* Enable/disable the ring. */ 138 + #define VHOST_VDPA_SET_VRING_ENABLE _IOW(VHOST_VIRTIO, 0x75, \ 139 + struct vhost_vring_state) 140 + /* Get the max ring size. */ 141 + #define VHOST_VDPA_GET_VRING_NUM _IOR(VHOST_VIRTIO, 0x76, __u16) 142 + 119 143 #endif
+18 -9
target/s390x/cpu.c
··· 37 37 #include "sysemu/hw_accel.h" 38 38 #include "hw/qdev-properties.h" 39 39 #ifndef CONFIG_USER_ONLY 40 + #include "hw/s390x/pv.h" 40 41 #include "hw/boards.h" 41 42 #include "sysemu/arch_init.h" 42 43 #include "sysemu/sysemu.h" ··· 76 77 static void s390_cpu_load_normal(CPUState *s) 77 78 { 78 79 S390CPU *cpu = S390_CPU(s); 79 - uint64_t spsw = ldq_phys(s->as, 0); 80 + uint64_t spsw; 80 81 81 - cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL; 82 - /* 83 - * Invert short psw indication, so SIE will report a specification 84 - * exception if it was not set. 85 - */ 86 - cpu->env.psw.mask ^= PSW_MASK_SHORTPSW; 87 - cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR; 88 - 82 + if (!s390_is_pv()) { 83 + spsw = ldq_phys(s->as, 0); 84 + cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL; 85 + /* 86 + * Invert short psw indication, so SIE will report a specification 87 + * exception if it was not set. 88 + */ 89 + cpu->env.psw.mask ^= PSW_MASK_SHORTPSW; 90 + cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR; 91 + } else { 92 + /* 93 + * Firmware requires us to set the load state before we set 94 + * the cpu to operating on protected guests. 95 + */ 96 + s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu); 97 + } 89 98 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); 90 99 } 91 100 #endif
+6 -1
target/s390x/cpu.h
··· 823 823 #define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len) \ 824 824 s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true) 825 825 void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra); 826 - 826 + int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf, 827 + int len, bool is_write); 828 + #define s390_cpu_pv_mem_read(cpu, offset, dest, len) \ 829 + s390_cpu_pv_mem_rw(cpu, offset, dest, len, false) 830 + #define s390_cpu_pv_mem_write(cpu, offset, dest, len) \ 831 + s390_cpu_pv_mem_rw(cpu, offset, dest, len, true) 827 832 828 833 /* sigp.c */ 829 834 int s390_cpu_restart(S390CPU *cpu);
+1
target/s390x/cpu_features_def.inc.h
··· 107 107 DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH, "vxpdeh", STFL, 152, "Vector-Packed-Decimal-Enhancement Facility") 108 108 DEF_FEAT(MSA_EXT_9, "msa9-base", STFL, 155, "Message-security-assist-extension-9 facility (excluding subfunctions)") 109 109 DEF_FEAT(ETOKEN, "etoken", STFL, 156, "Etoken facility") 110 + DEF_FEAT(UNPACK, "unpack", STFL, 161, "Unpack facility") 110 111 111 112 /* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */ 112 113 DEF_FEAT(SIE_GSLS, "gsls", SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility")
+57 -18
target/s390x/diag.c
··· 20 20 #include "sysemu/cpus.h" 21 21 #include "hw/s390x/ipl.h" 22 22 #include "hw/s390x/s390-virtio-ccw.h" 23 + #include "hw/s390x/pv.h" 24 + #include "kvm_s390x.h" 23 25 24 26 int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3) 25 27 { ··· 49 51 return diag288_class->handle_timer(diag288, func, timeout); 50 52 } 51 53 52 - #define DIAG_308_RC_OK 0x0001 53 - #define DIAG_308_RC_NO_CONF 0x0102 54 - #define DIAG_308_RC_INVALID 0x0402 55 - 56 - #define DIAG308_RESET_MOD_CLR 0 57 - #define DIAG308_RESET_LOAD_NORM 1 58 - #define DIAG308_LOAD_CLEAR 3 59 - #define DIAG308_LOAD_NORMAL_DUMP 4 60 - #define DIAG308_SET 5 61 - #define DIAG308_STORE 6 62 - 63 54 static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr, 64 55 uintptr_t ra, bool write) 65 56 { 57 + /* Handled by the Ultravisor */ 58 + if (s390_is_pv()) { 59 + return 0; 60 + } 66 61 if ((r1 & 1) || (addr & ~TARGET_PAGE_MASK)) { 67 62 s390_program_interrupt(env, PGM_SPECIFICATION, ra); 68 63 return -1; ··· 78 73 79 74 void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra) 80 75 { 76 + bool valid; 81 77 CPUState *cs = env_cpu(env); 78 + S390CPU *cpu = S390_CPU(cs); 82 79 uint64_t addr = env->regs[r1]; 83 80 uint64_t subcode = env->regs[r3]; 84 81 IplParameterBlock *iplb; ··· 93 90 return; 94 91 } 95 92 93 + if (subcode >= DIAG308_PV_SET && !s390_has_feat(S390_FEAT_UNPACK)) { 94 + s390_program_interrupt(env, PGM_SPECIFICATION, ra); 95 + return; 96 + } 97 + 96 98 switch (subcode) { 97 99 case DIAG308_RESET_MOD_CLR: 98 100 s390_ipl_reset_request(cs, S390_RESET_MODIFIED_CLEAR); ··· 105 107 s390_ipl_reset_request(cs, S390_RESET_REIPL); 106 108 break; 107 109 case DIAG308_SET: 110 + case DIAG308_PV_SET: 108 111 if (diag308_parm_check(env, r1, addr, ra, false)) { 109 112 return; 110 113 } 111 114 iplb = g_new0(IplParameterBlock, 1); 112 - cpu_physical_memory_read(addr, iplb, sizeof(iplb->len)); 115 + if (!s390_is_pv()) { 116 + cpu_physical_memory_read(addr, iplb, sizeof(iplb->len)); 117 + } else { 118 + s390_cpu_pv_mem_read(cpu, 0, iplb, sizeof(iplb->len)); 119 + } 120 + 113 121 if (!iplb_valid_len(iplb)) { 114 122 env->regs[r1 + 1] = DIAG_308_RC_INVALID; 115 123 goto out; 116 124 } 117 125 118 - cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len)); 126 + if (!s390_is_pv()) { 127 + cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len)); 128 + } else { 129 + s390_cpu_pv_mem_read(cpu, 0, iplb, be32_to_cpu(iplb->len)); 130 + } 119 131 120 - if (!iplb_valid(iplb)) { 132 + valid = subcode == DIAG308_PV_SET ? iplb_valid_pv(iplb) : iplb_valid(iplb); 133 + if (!valid) { 121 134 env->regs[r1 + 1] = DIAG_308_RC_INVALID; 122 135 goto out; 123 136 } ··· 128 141 g_free(iplb); 129 142 return; 130 143 case DIAG308_STORE: 144 + case DIAG308_PV_STORE: 131 145 if (diag308_parm_check(env, r1, addr, ra, true)) { 132 146 return; 133 147 } 134 - iplb = s390_ipl_get_iplb(); 135 - if (iplb) { 148 + if (subcode == DIAG308_PV_STORE) { 149 + iplb = s390_ipl_get_iplb_pv(); 150 + } else { 151 + iplb = s390_ipl_get_iplb(); 152 + } 153 + if (!iplb) { 154 + env->regs[r1 + 1] = DIAG_308_RC_NO_CONF; 155 + return; 156 + } 157 + 158 + if (!s390_is_pv()) { 136 159 cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len)); 137 - env->regs[r1 + 1] = DIAG_308_RC_OK; 138 160 } else { 139 - env->regs[r1 + 1] = DIAG_308_RC_NO_CONF; 161 + s390_cpu_pv_mem_write(cpu, 0, iplb, be32_to_cpu(iplb->len)); 140 162 } 163 + env->regs[r1 + 1] = DIAG_308_RC_OK; 141 164 return; 165 + case DIAG308_PV_START: 166 + iplb = s390_ipl_get_iplb_pv(); 167 + if (!iplb) { 168 + env->regs[r1 + 1] = DIAG_308_RC_NO_PV_CONF; 169 + return; 170 + } 171 + 172 + if (kvm_s390_get_hpage_1m()) { 173 + error_report("Protected VMs can currently not be backed with " 174 + "huge pages"); 175 + env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV; 176 + return; 177 + } 178 + 179 + s390_ipl_reset_request(cs, S390_RESET_PV); 180 + break; 142 181 default: 143 182 s390_program_interrupt(env, PGM_SPECIFICATION, ra); 144 183 break;
+1
target/s390x/gen-features.c
··· 562 562 S390_FEAT_GROUP_MSA_EXT_9, 563 563 S390_FEAT_GROUP_MSA_EXT_9_PCKMO, 564 564 S390_FEAT_ETOKEN, 565 + S390_FEAT_UNPACK, 565 566 }; 566 567 567 568 /* Default features (in order of release)
+6
target/s390x/helper.c
··· 25 25 #include "qemu/timer.h" 26 26 #include "qemu/qemu-print.h" 27 27 #include "hw/s390x/ioinst.h" 28 + #include "hw/s390x/pv.h" 28 29 #include "sysemu/hw_accel.h" 29 30 #include "sysemu/runstate.h" 30 31 #ifndef CONFIG_USER_ONLY ··· 245 246 SigpSaveArea *sa; 246 247 hwaddr len = sizeof(*sa); 247 248 int i; 249 + 250 + /* For PVMs storing will occur when this cpu enters SIE again */ 251 + if (s390_is_pv()) { 252 + return 0; 253 + } 248 254 249 255 sa = cpu_physical_memory_map(addr, &len, true); 250 256 if (!sa) {
+73 -23
target/s390x/ioinst.c
··· 16 16 #include "hw/s390x/ioinst.h" 17 17 #include "trace.h" 18 18 #include "hw/s390x/s390-pci-bus.h" 19 + #include "hw/s390x/pv.h" 20 + 21 + /* All I/O instructions but chsc use the s format */ 22 + static uint64_t get_address_from_regs(CPUS390XState *env, uint32_t ipb, 23 + uint8_t *ar) 24 + { 25 + /* 26 + * Addresses for protected guests are all offsets into the 27 + * satellite block which holds the IO control structures. Those 28 + * control structures are always starting at offset 0 and are 29 + * always aligned and accessible. So we can return 0 here which 30 + * will pass the following address checks. 31 + */ 32 + if (s390_is_pv()) { 33 + *ar = 0; 34 + return 0; 35 + } 36 + return decode_basedisp_s(env, ipb, ar); 37 + } 19 38 20 39 int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid, 21 40 int *schid) ··· 114 133 CPUS390XState *env = &cpu->env; 115 134 uint8_t ar; 116 135 117 - addr = decode_basedisp_s(env, ipb, &ar); 136 + addr = get_address_from_regs(env, ipb, &ar); 118 137 if (addr & 3) { 119 138 s390_program_interrupt(env, PGM_SPECIFICATION, ra); 120 139 return; 121 140 } 122 - if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) { 141 + if (s390_is_pv()) { 142 + s390_cpu_pv_mem_read(cpu, addr, &schib, sizeof(schib)); 143 + } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) { 123 144 s390_cpu_virt_mem_handle_exc(cpu, ra); 124 145 return; 125 146 } ··· 171 192 CPUS390XState *env = &cpu->env; 172 193 uint8_t ar; 173 194 174 - addr = decode_basedisp_s(env, ipb, &ar); 195 + addr = get_address_from_regs(env, ipb, &ar); 175 196 if (addr & 3) { 176 197 s390_program_interrupt(env, PGM_SPECIFICATION, ra); 177 198 return; 178 199 } 179 - if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) { 200 + if (s390_is_pv()) { 201 + s390_cpu_pv_mem_read(cpu, addr, &orig_orb, sizeof(orb)); 202 + } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) { 180 203 s390_cpu_virt_mem_handle_exc(cpu, ra); 181 204 return; 182 205 } ··· 203 226 CPUS390XState *env = &cpu->env; 204 227 uint8_t ar; 205 228 206 - addr = decode_basedisp_s(env, ipb, &ar); 229 + addr = get_address_from_regs(env, ipb, &ar); 207 230 if (addr & 3) { 208 231 s390_program_interrupt(env, PGM_SPECIFICATION, ra); 209 232 return; ··· 212 235 cc = css_do_stcrw(&crw); 213 236 /* 0 - crw stored, 1 - zeroes stored */ 214 237 215 - if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) { 238 + if (s390_is_pv()) { 239 + s390_cpu_pv_mem_write(cpu, addr, &crw, sizeof(crw)); 216 240 setcc(cpu, cc); 217 241 } else { 218 - if (cc == 0) { 219 - /* Write failed: requeue CRW since STCRW is suppressing */ 220 - css_undo_stcrw(&crw); 242 + if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) { 243 + setcc(cpu, cc); 244 + } else { 245 + if (cc == 0) { 246 + /* Write failed: requeue CRW since STCRW is suppressing */ 247 + css_undo_stcrw(&crw); 248 + } 249 + s390_cpu_virt_mem_handle_exc(cpu, ra); 221 250 } 222 - s390_cpu_virt_mem_handle_exc(cpu, ra); 223 251 } 224 252 } 225 253 ··· 234 262 CPUS390XState *env = &cpu->env; 235 263 uint8_t ar; 236 264 237 - addr = decode_basedisp_s(env, ipb, &ar); 265 + addr = get_address_from_regs(env, ipb, &ar); 238 266 if (addr & 3) { 239 267 s390_program_interrupt(env, PGM_SPECIFICATION, ra); 240 268 return; 241 269 } 242 270 243 271 if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) { 272 + /* 273 + * The Ultravisor checks schid bit 16 to be one and bits 0-12 274 + * to be 0 and injects a operand exception itself. 275 + * 276 + * Hence we should never end up here. 277 + */ 278 + g_assert(!s390_is_pv()); 244 279 /* 245 280 * As operand exceptions have a lower priority than access exceptions, 246 281 * we check whether the memory area is writeable (injecting the ··· 273 308 } 274 309 } 275 310 if (cc != 3) { 276 - if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib, 277 - sizeof(schib)) != 0) { 311 + if (s390_is_pv()) { 312 + s390_cpu_pv_mem_write(cpu, addr, &schib, sizeof(schib)); 313 + } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib, 314 + sizeof(schib)) != 0) { 278 315 s390_cpu_virt_mem_handle_exc(cpu, ra); 279 316 return; 280 317 } 281 318 } else { 282 319 /* Access exceptions have a higher priority than cc3 */ 283 - if (s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) { 320 + if (!s390_is_pv() && 321 + s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) { 284 322 s390_cpu_virt_mem_handle_exc(cpu, ra); 285 323 return; 286 324 } ··· 303 341 return -EIO; 304 342 } 305 343 trace_ioinst_sch_id("tsch", cssid, ssid, schid); 306 - addr = decode_basedisp_s(env, ipb, &ar); 344 + addr = get_address_from_regs(env, ipb, &ar); 307 345 if (addr & 3) { 308 346 s390_program_interrupt(env, PGM_SPECIFICATION, ra); 309 347 return -EIO; ··· 317 355 } 318 356 /* 0 - status pending, 1 - not status pending, 3 - not operational */ 319 357 if (cc != 3) { 320 - if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) { 358 + if (s390_is_pv()) { 359 + s390_cpu_pv_mem_write(cpu, addr, &irb, irb_len); 360 + } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) { 321 361 s390_cpu_virt_mem_handle_exc(cpu, ra); 322 362 return -EFAULT; 323 363 } ··· 325 365 } else { 326 366 irb_len = sizeof(irb) - sizeof(irb.emw); 327 367 /* Access exceptions have a higher priority than cc3 */ 328 - if (s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) { 368 + if (!s390_is_pv() && 369 + s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) { 329 370 s390_cpu_virt_mem_handle_exc(cpu, ra); 330 371 return -EFAULT; 331 372 } ··· 601 642 { 602 643 ChscReq *req; 603 644 ChscResp *res; 604 - uint64_t addr; 645 + uint64_t addr = 0; 605 646 int reg; 606 647 uint16_t len; 607 648 uint16_t command; ··· 610 651 611 652 trace_ioinst("chsc"); 612 653 reg = (ipb >> 20) & 0x00f; 613 - addr = env->regs[reg]; 654 + if (!s390_is_pv()) { 655 + addr = env->regs[reg]; 656 + } 614 657 /* Page boundary? */ 615 658 if (addr & 0xfff) { 616 659 s390_program_interrupt(env, PGM_SPECIFICATION, ra); ··· 621 664 * present CHSC sub-handlers ... if we ever need more, we should take 622 665 * care of req->len here first. 623 666 */ 624 - if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) { 667 + if (s390_is_pv()) { 668 + s390_cpu_pv_mem_read(cpu, addr, buf, sizeof(ChscReq)); 669 + } else if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) { 625 670 s390_cpu_virt_mem_handle_exc(cpu, ra); 626 671 return; 627 672 } ··· 654 699 break; 655 700 } 656 701 657 - if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res, 658 - be16_to_cpu(res->len))) { 702 + if (s390_is_pv()) { 703 + s390_cpu_pv_mem_write(cpu, addr + len, res, be16_to_cpu(res->len)); 659 704 setcc(cpu, 0); /* Command execution complete */ 660 705 } else { 661 - s390_cpu_virt_mem_handle_exc(cpu, ra); 706 + if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res, 707 + be16_to_cpu(res->len))) { 708 + setcc(cpu, 0); /* Command execution complete */ 709 + } else { 710 + s390_cpu_virt_mem_handle_exc(cpu, ra); 711 + } 662 712 } 663 713 } 664 714
+5
target/s390x/kvm-stub.c
··· 39 39 return 0; 40 40 } 41 41 42 + int kvm_s390_get_hpage_1m(void) 43 + { 44 + return 0; 45 + } 46 + 42 47 int kvm_s390_get_ri(void) 43 48 { 44 49 return 0;
+72 -7
target/s390x/kvm.c
··· 50 50 #include "exec/memattrs.h" 51 51 #include "hw/s390x/s390-virtio-ccw.h" 52 52 #include "hw/s390x/s390-virtio-hcall.h" 53 + #include "hw/s390x/pv.h" 53 54 54 55 #ifndef DEBUG_KVM 55 56 #define DEBUG_KVM 0 ··· 115 116 #define ICPT_CPU_STOP 0x28 116 117 #define ICPT_OPEREXC 0x2c 117 118 #define ICPT_IO 0x40 119 + #define ICPT_PV_INSTR 0x68 120 + #define ICPT_PV_INSTR_NOTIFICATION 0x6c 118 121 119 122 #define NR_LOCAL_IRQS 32 120 123 /* ··· 152 155 static int cap_gs; 153 156 static int cap_hpage_1m; 154 157 static int cap_vcpu_resets; 158 + static int cap_protected; 155 159 156 160 static int active_cmma; 157 161 ··· 321 325 cap_hpage_1m = 1; 322 326 } 323 327 328 + int kvm_s390_get_hpage_1m(void) 329 + { 330 + return cap_hpage_1m; 331 + } 332 + 324 333 static void ccw_machine_class_foreach(ObjectClass *oc, void *opaque) 325 334 { 326 335 MachineClass *mc = MACHINE_CLASS(oc); ··· 344 353 cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP); 345 354 cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ); 346 355 cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS); 356 + cap_protected = kvm_check_extension(s, KVM_CAP_S390_PROTECTED); 347 357 348 358 if (!kvm_check_extension(s, KVM_CAP_S390_GMAP) 349 359 || !kvm_check_extension(s, KVM_CAP_S390_COW)) { ··· 844 854 return ret; 845 855 } 846 856 857 + int kvm_s390_mem_op_pv(S390CPU *cpu, uint64_t offset, void *hostbuf, 858 + int len, bool is_write) 859 + { 860 + struct kvm_s390_mem_op mem_op = { 861 + .sida_offset = offset, 862 + .size = len, 863 + .op = is_write ? KVM_S390_MEMOP_SIDA_WRITE 864 + : KVM_S390_MEMOP_SIDA_READ, 865 + .buf = (uint64_t)hostbuf, 866 + }; 867 + int ret; 868 + 869 + if (!cap_mem_op || !cap_protected) { 870 + return -ENOSYS; 871 + } 872 + 873 + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op); 874 + if (ret < 0) { 875 + error_report("KVM_S390_MEM_OP failed: %s", strerror(-ret)); 876 + abort(); 877 + } 878 + return ret; 879 + } 880 + 847 881 /* 848 882 * Legacy layout for s390: 849 883 * Older S390 KVM requires the topmost vma of the RAM to be ··· 1199 1233 sccb = env->regs[ipbh0 & 0xf]; 1200 1234 code = env->regs[(ipbh0 & 0xf0) >> 4]; 1201 1235 1202 - r = sclp_service_call(env, sccb, code); 1203 - if (r < 0) { 1204 - kvm_s390_program_interrupt(cpu, -r); 1205 - return; 1236 + switch (run->s390_sieic.icptcode) { 1237 + case ICPT_PV_INSTR_NOTIFICATION: 1238 + g_assert(s390_is_pv()); 1239 + /* The notification intercepts are currently handled by KVM */ 1240 + error_report("unexpected SCLP PV notification"); 1241 + exit(1); 1242 + break; 1243 + case ICPT_PV_INSTR: 1244 + g_assert(s390_is_pv()); 1245 + sclp_service_call_protected(env, sccb, code); 1246 + /* Setting the CC is done by the Ultravisor. */ 1247 + break; 1248 + case ICPT_INSTRUCTION: 1249 + g_assert(!s390_is_pv()); 1250 + r = sclp_service_call(env, sccb, code); 1251 + if (r < 0) { 1252 + kvm_s390_program_interrupt(cpu, -r); 1253 + return; 1254 + } 1255 + setcc(cpu, r); 1206 1256 } 1207 - setcc(cpu, r); 1208 1257 } 1209 1258 1210 1259 static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) ··· 1693 1742 (long)cs->kvm_run->psw_addr); 1694 1743 switch (icpt_code) { 1695 1744 case ICPT_INSTRUCTION: 1745 + case ICPT_PV_INSTR: 1746 + case ICPT_PV_INSTR_NOTIFICATION: 1696 1747 r = handle_instruction(cpu, run); 1697 1748 break; 1698 1749 case ICPT_PROGRAM: ··· 1773 1824 SysIB_322 sysib; 1774 1825 int del, i; 1775 1826 1776 - if (s390_cpu_virt_mem_read(cpu, addr, ar, &sysib, sizeof(sysib))) { 1827 + if (s390_is_pv()) { 1828 + s390_cpu_pv_mem_read(cpu, 0, &sysib, sizeof(sysib)); 1829 + } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &sysib, sizeof(sysib))) { 1777 1830 return; 1778 1831 } 1779 1832 /* Shift the stack of Extended Names to prepare for our own data */ ··· 1826 1879 /* Insert UUID */ 1827 1880 memcpy(sysib.vm[0].uuid, &qemu_uuid, sizeof(sysib.vm[0].uuid)); 1828 1881 1829 - s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, sizeof(sysib)); 1882 + if (s390_is_pv()) { 1883 + s390_cpu_pv_mem_write(cpu, 0, &sysib, sizeof(sysib)); 1884 + } else { 1885 + s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, sizeof(sysib)); 1886 + } 1830 1887 } 1831 1888 1832 1889 static int handle_stsi(S390CPU *cpu) ··· 2366 2423 /* bpb needs kernel support for migration, VSIE and reset */ 2367 2424 if (!kvm_check_extension(kvm_state, KVM_CAP_S390_BPB)) { 2368 2425 clear_bit(S390_FEAT_BPB, model->features); 2426 + } 2427 + 2428 + /* 2429 + * If we have support for protected virtualization, indicate 2430 + * the protected virtualization IPL unpack facility. 2431 + */ 2432 + if (cap_protected) { 2433 + set_bit(S390_FEAT_UNPACK, model->features); 2369 2434 } 2370 2435 2371 2436 /* We emulate a zPCI bus and AEN, therefore we don't need HW support */
+3
target/s390x/kvm_s390x.h
··· 19 19 void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code); 20 20 int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf, 21 21 int len, bool is_write); 22 + int kvm_s390_mem_op_pv(S390CPU *cpu, vaddr addr, void *hostbuf, int len, 23 + bool is_write); 22 24 void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code); 23 25 int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state); 24 26 void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu); 25 27 int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu); 28 + int kvm_s390_get_hpage_1m(void); 26 29 int kvm_s390_get_ri(void); 27 30 int kvm_s390_get_gs(void); 28 31 int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_clock);
+14
target/s390x/mmu_helper.c
··· 474 474 return 0; 475 475 } 476 476 477 + int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf, 478 + int len, bool is_write) 479 + { 480 + int ret; 481 + 482 + if (kvm_enabled()) { 483 + ret = kvm_s390_mem_op_pv(cpu, offset, hostbuf, len, is_write); 484 + } else { 485 + /* Protected Virtualization is a KVM/Hardware only feature */ 486 + g_assert_not_reached(); 487 + } 488 + return ret; 489 + } 490 + 477 491 /** 478 492 * s390_cpu_virt_mem_rw: 479 493 * @laddr: the logical start address