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

kvm powerpc/book3s-apiv2: Add support for Hostwide GSB elements

Add support for adding and parsing Hostwide elements to the
Guest-state-buffer data structure used in apiv2. These elements are used to
share meta-information pertaining to entire L1-Lpar and this
meta-information is maintained by L0-PowerVM hypervisor. Example of this
include the amount of the page-table memory currently used by L0-PowerVM
for hosting the Shadow-Pagetable of all active L2-Guests. More of the are
documented in kernel-documentation at [1]. The Hostwide GSB elements are
currently only support with H_GUEST_SET_STATE hcall with a special flag
namely 'KVMPPC_GS_FLAGS_HOST_WIDE'.

The patch introduces new defs for the 5 new Hostwide GSB elements including
their GSIDs as well as introduces a new class of GSB elements namely
'KVMPPC_GS_CLASS_HOSTWIDE' to indicate to GSB construction/parsing
infrastructure in 'kvm/guest-state-buffer.c'. Also
gs_msg_ops_vcpu_get_size(), kvmppc_gsid_type() and
kvmppc_gse_{flatten,unflatten}_iden() are updated to appropriately indicate
the needed size for these Hostwide GSB elements as well as how to
flatten/unflatten their GSIDs so that they can be marked as available in
GSB bitmap.

[1] Documention/arch/powerpc/kvm-nested.rst

Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20250416162740.93143-3-vaibhav@linux.ibm.com

authored by

Vaibhav Jain and committed by
Madhavan Srinivasan
5317f75f cb58d39f

+81 -12
+29 -6
arch/powerpc/include/asm/guest-state-buffer.h
··· 28 28 /* Process Table Info */ 29 29 #define KVMPPC_GSID_PROCESS_TABLE 0x0006 30 30 31 + /* Guest Management Heap Size */ 32 + #define KVMPPC_GSID_L0_GUEST_HEAP 0x0800 33 + 34 + /* Guest Management Heap Max Size */ 35 + #define KVMPPC_GSID_L0_GUEST_HEAP_MAX 0x0801 36 + 37 + /* Guest Pagetable Size */ 38 + #define KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE 0x0802 39 + 40 + /* Guest Pagetable Max Size */ 41 + #define KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX 0x0803 42 + 43 + /* Guest Pagetable Reclaim in bytes */ 44 + #define KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM 0x0804 45 + 31 46 /* H_GUEST_RUN_VCPU input buffer Info */ 32 47 #define KVMPPC_GSID_RUN_INPUT 0x0C00 33 48 /* H_GUEST_RUN_VCPU output buffer Info */ ··· 121 106 #define KVMPPC_GSE_GUESTWIDE_COUNT \ 122 107 (KVMPPC_GSE_GUESTWIDE_END - KVMPPC_GSE_GUESTWIDE_START + 1) 123 108 109 + #define KVMPPC_GSE_HOSTWIDE_START KVMPPC_GSID_L0_GUEST_HEAP 110 + #define KVMPPC_GSE_HOSTWIDE_END KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM 111 + #define KVMPPC_GSE_HOSTWIDE_COUNT \ 112 + (KVMPPC_GSE_HOSTWIDE_END - KVMPPC_GSE_HOSTWIDE_START + 1) 113 + 124 114 #define KVMPPC_GSE_META_START KVMPPC_GSID_RUN_INPUT 125 115 #define KVMPPC_GSE_META_END KVMPPC_GSID_VPA 126 116 #define KVMPPC_GSE_META_COUNT (KVMPPC_GSE_META_END - KVMPPC_GSE_META_START + 1) ··· 150 130 (KVMPPC_GSE_INTR_REGS_END - KVMPPC_GSE_INTR_REGS_START + 1) 151 131 152 132 #define KVMPPC_GSE_IDEN_COUNT \ 153 - (KVMPPC_GSE_GUESTWIDE_COUNT + KVMPPC_GSE_META_COUNT + \ 133 + (KVMPPC_GSE_HOSTWIDE_COUNT + \ 134 + KVMPPC_GSE_GUESTWIDE_COUNT + KVMPPC_GSE_META_COUNT + \ 154 135 KVMPPC_GSE_DW_REGS_COUNT + KVMPPC_GSE_W_REGS_COUNT + \ 155 136 KVMPPC_GSE_VSRS_COUNT + KVMPPC_GSE_INTR_REGS_COUNT) 156 137 ··· 160 139 */ 161 140 enum { 162 141 KVMPPC_GS_CLASS_GUESTWIDE = 0x01, 163 - KVMPPC_GS_CLASS_META = 0x02, 164 - KVMPPC_GS_CLASS_DWORD_REG = 0x04, 165 - KVMPPC_GS_CLASS_WORD_REG = 0x08, 166 - KVMPPC_GS_CLASS_VECTOR = 0x10, 142 + KVMPPC_GS_CLASS_HOSTWIDE = 0x02, 143 + KVMPPC_GS_CLASS_META = 0x04, 144 + KVMPPC_GS_CLASS_DWORD_REG = 0x08, 145 + KVMPPC_GS_CLASS_WORD_REG = 0x10, 146 + KVMPPC_GS_CLASS_VECTOR = 0x18, 167 147 KVMPPC_GS_CLASS_INTR = 0x20, 168 148 }; 169 149 ··· 186 164 */ 187 165 enum { 188 166 KVMPPC_GS_FLAGS_WIDE = 0x01, 167 + KVMPPC_GS_FLAGS_HOST_WIDE = 0x02, 189 168 }; 190 169 191 170 /** ··· 310 287 * struct kvmppc_gs_msg - a guest state message 311 288 * @bitmap: the guest state ids that should be included 312 289 * @ops: modify message behavior for reading and writing to buffers 313 - * @flags: guest wide or thread wide 290 + * @flags: host wide, guest wide or thread wide 314 291 * @data: location where buffer data will be written to or from. 315 292 * 316 293 * A guest state message is allows flexibility in sending in receiving data
+7 -6
arch/powerpc/include/asm/hvcall.h
··· 490 490 #define H_RPTI_PAGE_ALL (-1UL) 491 491 492 492 /* Flags for H_GUEST_{S,G}_STATE */ 493 - #define H_GUEST_FLAGS_WIDE (1UL<<(63-0)) 493 + #define H_GUEST_FLAGS_WIDE (1UL << (63 - 0)) 494 + #define H_GUEST_FLAGS_HOST_WIDE (1UL << (63 - 1)) 494 495 495 496 /* Flag values used for H_{S,G}SET_GUEST_CAPABILITIES */ 496 - #define H_GUEST_CAP_COPY_MEM (1UL<<(63-0)) 497 - #define H_GUEST_CAP_POWER9 (1UL<<(63-1)) 498 - #define H_GUEST_CAP_POWER10 (1UL<<(63-2)) 499 - #define H_GUEST_CAP_POWER11 (1UL<<(63-3)) 500 - #define H_GUEST_CAP_BITMAP2 (1UL<<(63-63)) 497 + #define H_GUEST_CAP_COPY_MEM (1UL << (63 - 0)) 498 + #define H_GUEST_CAP_POWER9 (1UL << (63 - 1)) 499 + #define H_GUEST_CAP_POWER10 (1UL << (63 - 2)) 500 + #define H_GUEST_CAP_POWER11 (1UL << (63 - 3)) 501 + #define H_GUEST_CAP_BITMAP2 (1UL << (63 - 63)) 501 502 502 503 /* 503 504 * Defines for H_HTM - Macros for hardware trace macro (HTM) function.
+6
arch/powerpc/kvm/book3s_hv_nestedv2.c
··· 123 123 case KVMPPC_GSID_PROCESS_TABLE: 124 124 case KVMPPC_GSID_RUN_INPUT: 125 125 case KVMPPC_GSID_RUN_OUTPUT: 126 + /* Host wide counters */ 127 + case KVMPPC_GSID_L0_GUEST_HEAP: 128 + case KVMPPC_GSID_L0_GUEST_HEAP_MAX: 129 + case KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE: 130 + case KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX: 131 + case KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM: 126 132 break; 127 133 default: 128 134 size += kvmppc_gse_total_size(kvmppc_gsid_size(iden));
+39
arch/powerpc/kvm/guest-state-buffer.c
··· 92 92 (iden <= KVMPPC_GSE_GUESTWIDE_END)) 93 93 return KVMPPC_GS_CLASS_GUESTWIDE; 94 94 95 + if ((iden >= KVMPPC_GSE_HOSTWIDE_START) && 96 + (iden <= KVMPPC_GSE_HOSTWIDE_END)) 97 + return KVMPPC_GS_CLASS_HOSTWIDE; 98 + 95 99 if ((iden >= KVMPPC_GSE_META_START) && (iden <= KVMPPC_GSE_META_END)) 96 100 return KVMPPC_GS_CLASS_META; 97 101 ··· 122 118 int type = -1; 123 119 124 120 switch (kvmppc_gsid_class(iden)) { 121 + case KVMPPC_GS_CLASS_HOSTWIDE: 122 + switch (iden) { 123 + case KVMPPC_GSID_L0_GUEST_HEAP: 124 + fallthrough; 125 + case KVMPPC_GSID_L0_GUEST_HEAP_MAX: 126 + fallthrough; 127 + case KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE: 128 + fallthrough; 129 + case KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX: 130 + fallthrough; 131 + case KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM: 132 + type = KVMPPC_GSE_BE64; 133 + break; 134 + } 135 + break; 125 136 case KVMPPC_GS_CLASS_GUESTWIDE: 126 137 switch (iden) { 127 138 case KVMPPC_GSID_HOST_STATE_SIZE: ··· 205 186 switch (kvmppc_gsid_class(iden)) { 206 187 case KVMPPC_GS_CLASS_GUESTWIDE: 207 188 flags = KVMPPC_GS_FLAGS_WIDE; 189 + break; 190 + case KVMPPC_GS_CLASS_HOSTWIDE: 191 + flags = KVMPPC_GS_FLAGS_HOST_WIDE; 208 192 break; 209 193 case KVMPPC_GS_CLASS_META: 210 194 case KVMPPC_GS_CLASS_DWORD_REG: ··· 332 310 333 311 bit += KVMPPC_GSE_GUESTWIDE_COUNT; 334 312 313 + if (class == KVMPPC_GS_CLASS_HOSTWIDE) { 314 + bit += iden - KVMPPC_GSE_HOSTWIDE_START; 315 + return bit; 316 + } 317 + 318 + bit += KVMPPC_GSE_HOSTWIDE_COUNT; 319 + 335 320 if (class == KVMPPC_GS_CLASS_META) { 336 321 bit += iden - KVMPPC_GSE_META_START; 337 322 return bit; ··· 384 355 return iden; 385 356 } 386 357 bit -= KVMPPC_GSE_GUESTWIDE_COUNT; 358 + 359 + if (bit < KVMPPC_GSE_HOSTWIDE_COUNT) { 360 + iden = KVMPPC_GSE_HOSTWIDE_START + bit; 361 + return iden; 362 + } 363 + bit -= KVMPPC_GSE_HOSTWIDE_COUNT; 387 364 388 365 if (bit < KVMPPC_GSE_META_COUNT) { 389 366 iden = KVMPPC_GSE_META_START + bit; ··· 623 588 624 589 if (flags & KVMPPC_GS_FLAGS_WIDE) 625 590 hflags |= H_GUEST_FLAGS_WIDE; 591 + if (flags & KVMPPC_GS_FLAGS_HOST_WIDE) 592 + hflags |= H_GUEST_FLAGS_HOST_WIDE; 626 593 627 594 rc = plpar_guest_set_state(hflags, gsb->guest_id, gsb->vcpu_id, 628 595 __pa(gsb->hdr), gsb->capacity, &i); ··· 650 613 651 614 if (flags & KVMPPC_GS_FLAGS_WIDE) 652 615 hflags |= H_GUEST_FLAGS_WIDE; 616 + if (flags & KVMPPC_GS_FLAGS_HOST_WIDE) 617 + hflags |= H_GUEST_FLAGS_HOST_WIDE; 653 618 654 619 rc = plpar_guest_get_state(hflags, gsb->guest_id, gsb->vcpu_id, 655 620 __pa(gsb->hdr), gsb->capacity, &i);