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 <vaib...@linux.ibm.com>
---
 arch/powerpc/include/asm/guest-state-buffer.h | 35 ++++++++++++++---
 arch/powerpc/include/asm/hvcall.h             | 13 ++++---
 arch/powerpc/kvm/book3s_hv_nestedv2.c         |  6 +++
 arch/powerpc/kvm/guest-state-buffer.c         | 39 +++++++++++++++++++
 4 files changed, 81 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/guest-state-buffer.h 
b/arch/powerpc/include/asm/guest-state-buffer.h
index d107abe1468f..acd61eb36d59 100644
--- a/arch/powerpc/include/asm/guest-state-buffer.h
+++ b/arch/powerpc/include/asm/guest-state-buffer.h
@@ -28,6 +28,21 @@
  /* Process Table Info */
 #define KVMPPC_GSID_PROCESS_TABLE              0x0006
 
+/* Guest Management Heap Size */
+#define KVMPPC_GSID_L0_GUEST_HEAP              0x0800
+
+/* Guest Management Heap Max Size */
+#define KVMPPC_GSID_L0_GUEST_HEAP_MAX          0x0801
+
+/* Guest Pagetable Size */
+#define KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE      0x0802
+
+/* Guest Pagetable Max Size */
+#define KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX  0x0803
+
+/* Guest Pagetable Reclaim in bytes */
+#define KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM   0x0804
+
 /* H_GUEST_RUN_VCPU input buffer Info */
 #define KVMPPC_GSID_RUN_INPUT                  0x0C00
 /* H_GUEST_RUN_VCPU output buffer Info */
@@ -106,6 +121,11 @@
 #define KVMPPC_GSE_GUESTWIDE_COUNT \
        (KVMPPC_GSE_GUESTWIDE_END - KVMPPC_GSE_GUESTWIDE_START + 1)
 
+#define KVMPPC_GSE_HOSTWIDE_START KVMPPC_GSID_L0_GUEST_HEAP
+#define KVMPPC_GSE_HOSTWIDE_END KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM
+#define KVMPPC_GSE_HOSTWIDE_COUNT \
+       (KVMPPC_GSE_HOSTWIDE_END - KVMPPC_GSE_HOSTWIDE_START + 1)
+
 #define KVMPPC_GSE_META_START KVMPPC_GSID_RUN_INPUT
 #define KVMPPC_GSE_META_END KVMPPC_GSID_VPA
 #define KVMPPC_GSE_META_COUNT (KVMPPC_GSE_META_END - KVMPPC_GSE_META_START + 1)
@@ -130,7 +150,8 @@
        (KVMPPC_GSE_INTR_REGS_END - KVMPPC_GSE_INTR_REGS_START + 1)
 
 #define KVMPPC_GSE_IDEN_COUNT                                 \
-       (KVMPPC_GSE_GUESTWIDE_COUNT + KVMPPC_GSE_META_COUNT + \
+       (KVMPPC_GSE_HOSTWIDE_COUNT + \
+        KVMPPC_GSE_GUESTWIDE_COUNT + KVMPPC_GSE_META_COUNT + \
         KVMPPC_GSE_DW_REGS_COUNT + KVMPPC_GSE_W_REGS_COUNT + \
         KVMPPC_GSE_VSRS_COUNT + KVMPPC_GSE_INTR_REGS_COUNT)
 
@@ -139,10 +160,11 @@
  */
 enum {
        KVMPPC_GS_CLASS_GUESTWIDE = 0x01,
-       KVMPPC_GS_CLASS_META = 0x02,
-       KVMPPC_GS_CLASS_DWORD_REG = 0x04,
-       KVMPPC_GS_CLASS_WORD_REG = 0x08,
-       KVMPPC_GS_CLASS_VECTOR = 0x10,
+       KVMPPC_GS_CLASS_HOSTWIDE = 0x02,
+       KVMPPC_GS_CLASS_META = 0x04,
+       KVMPPC_GS_CLASS_DWORD_REG = 0x08,
+       KVMPPC_GS_CLASS_WORD_REG = 0x10,
+       KVMPPC_GS_CLASS_VECTOR = 0x18,
        KVMPPC_GS_CLASS_INTR = 0x20,
 };
 
@@ -164,6 +186,7 @@ enum {
  */
 enum {
        KVMPPC_GS_FLAGS_WIDE = 0x01,
+       KVMPPC_GS_FLAGS_HOST_WIDE = 0x02,
 };
 
 /**
@@ -287,7 +310,7 @@ struct kvmppc_gs_msg_ops {
  * struct kvmppc_gs_msg - a guest state message
  * @bitmap: the guest state ids that should be included
  * @ops: modify message behavior for reading and writing to buffers
- * @flags: guest wide or thread wide
+ * @flags: host wide, guest wide or thread wide
  * @data: location where buffer data will be written to or from.
  *
  * A guest state message is allows flexibility in sending in receiving data
diff --git a/arch/powerpc/include/asm/hvcall.h 
b/arch/powerpc/include/asm/hvcall.h
index 65d1f291393d..1c12713538a4 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -489,14 +489,15 @@
 #define H_RPTI_PAGE_ALL (-1UL)
 
 /* Flags for H_GUEST_{S,G}_STATE */
-#define H_GUEST_FLAGS_WIDE     (1UL<<(63-0))
+#define H_GUEST_FLAGS_WIDE     (1UL << (63 - 0))
+#define H_GUEST_FLAGS_HOST_WIDE        (1UL << (63 - 1))
 
 /* Flag values used for H_{S,G}SET_GUEST_CAPABILITIES */
-#define H_GUEST_CAP_COPY_MEM   (1UL<<(63-0))
-#define H_GUEST_CAP_POWER9     (1UL<<(63-1))
-#define H_GUEST_CAP_POWER10    (1UL<<(63-2))
-#define H_GUEST_CAP_POWER11    (1UL<<(63-3))
-#define H_GUEST_CAP_BITMAP2    (1UL<<(63-63))
+#define H_GUEST_CAP_COPY_MEM   (1UL << (63 - 0))
+#define H_GUEST_CAP_POWER9     (1UL << (63 - 1))
+#define H_GUEST_CAP_POWER10    (1UL << (63 - 2))
+#define H_GUEST_CAP_POWER11    (1UL << (63 - 3))
+#define H_GUEST_CAP_BITMAP2    (1UL << (63 - 63))
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
diff --git a/arch/powerpc/kvm/book3s_hv_nestedv2.c 
b/arch/powerpc/kvm/book3s_hv_nestedv2.c
index e5c7ce1fb761..87691cf86cae 100644
--- a/arch/powerpc/kvm/book3s_hv_nestedv2.c
+++ b/arch/powerpc/kvm/book3s_hv_nestedv2.c
@@ -123,6 +123,12 @@ static size_t gs_msg_ops_vcpu_get_size(struct 
kvmppc_gs_msg *gsm)
                case KVMPPC_GSID_PROCESS_TABLE:
                case KVMPPC_GSID_RUN_INPUT:
                case KVMPPC_GSID_RUN_OUTPUT:
+                 /* Host wide counters */
+               case KVMPPC_GSID_L0_GUEST_HEAP:
+               case KVMPPC_GSID_L0_GUEST_HEAP_MAX:
+               case KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE:
+               case KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX:
+               case KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM:
                        break;
                default:
                        size += kvmppc_gse_total_size(kvmppc_gsid_size(iden));
diff --git a/arch/powerpc/kvm/guest-state-buffer.c 
b/arch/powerpc/kvm/guest-state-buffer.c
index b80dbc58621f..871cf60ddeb6 100644
--- a/arch/powerpc/kvm/guest-state-buffer.c
+++ b/arch/powerpc/kvm/guest-state-buffer.c
@@ -92,6 +92,10 @@ static int kvmppc_gsid_class(u16 iden)
            (iden <= KVMPPC_GSE_GUESTWIDE_END))
                return KVMPPC_GS_CLASS_GUESTWIDE;
 
+       if ((iden >= KVMPPC_GSE_HOSTWIDE_START) &&
+           (iden <= KVMPPC_GSE_HOSTWIDE_END))
+               return KVMPPC_GS_CLASS_HOSTWIDE;
+
        if ((iden >= KVMPPC_GSE_META_START) && (iden <= KVMPPC_GSE_META_END))
                return KVMPPC_GS_CLASS_META;
 
@@ -118,6 +122,21 @@ static int kvmppc_gsid_type(u16 iden)
        int type = -1;
 
        switch (kvmppc_gsid_class(iden)) {
+       case KVMPPC_GS_CLASS_HOSTWIDE:
+               switch (iden) {
+               case KVMPPC_GSID_L0_GUEST_HEAP:
+                       fallthrough;
+               case KVMPPC_GSID_L0_GUEST_HEAP_MAX:
+                       fallthrough;
+               case KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE:
+                       fallthrough;
+               case KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX:
+                       fallthrough;
+               case KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM:
+                       type = KVMPPC_GSE_BE64;
+                       break;
+               }
+               break;
        case KVMPPC_GS_CLASS_GUESTWIDE:
                switch (iden) {
                case KVMPPC_GSID_HOST_STATE_SIZE:
@@ -187,6 +206,9 @@ unsigned long kvmppc_gsid_flags(u16 iden)
        case KVMPPC_GS_CLASS_GUESTWIDE:
                flags = KVMPPC_GS_FLAGS_WIDE;
                break;
+       case KVMPPC_GS_CLASS_HOSTWIDE:
+               flags = KVMPPC_GS_FLAGS_HOST_WIDE;
+               break;
        case KVMPPC_GS_CLASS_META:
        case KVMPPC_GS_CLASS_DWORD_REG:
        case KVMPPC_GS_CLASS_WORD_REG:
@@ -310,6 +332,13 @@ static inline int kvmppc_gse_flatten_iden(u16 iden)
 
        bit += KVMPPC_GSE_GUESTWIDE_COUNT;
 
+       if (class == KVMPPC_GS_CLASS_HOSTWIDE) {
+               bit += iden - KVMPPC_GSE_HOSTWIDE_START;
+               return bit;
+       }
+
+       bit += KVMPPC_GSE_HOSTWIDE_COUNT;
+
        if (class == KVMPPC_GS_CLASS_META) {
                bit += iden - KVMPPC_GSE_META_START;
                return bit;
@@ -356,6 +385,12 @@ static inline u16 kvmppc_gse_unflatten_iden(int bit)
        }
        bit -= KVMPPC_GSE_GUESTWIDE_COUNT;
 
+       if (bit < KVMPPC_GSE_HOSTWIDE_COUNT) {
+               iden = KVMPPC_GSE_HOSTWIDE_START + bit;
+               return iden;
+       }
+       bit -= KVMPPC_GSE_HOSTWIDE_COUNT;
+
        if (bit < KVMPPC_GSE_META_COUNT) {
                iden = KVMPPC_GSE_META_START + bit;
                return iden;
@@ -588,6 +623,8 @@ int kvmppc_gsb_send(struct kvmppc_gs_buff *gsb, unsigned 
long flags)
 
        if (flags & KVMPPC_GS_FLAGS_WIDE)
                hflags |= H_GUEST_FLAGS_WIDE;
+       if (flags & KVMPPC_GS_FLAGS_HOST_WIDE)
+               hflags |= H_GUEST_FLAGS_HOST_WIDE;
 
        rc = plpar_guest_set_state(hflags, gsb->guest_id, gsb->vcpu_id,
                                   __pa(gsb->hdr), gsb->capacity, &i);
@@ -613,6 +650,8 @@ int kvmppc_gsb_recv(struct kvmppc_gs_buff *gsb, unsigned 
long flags)
 
        if (flags & KVMPPC_GS_FLAGS_WIDE)
                hflags |= H_GUEST_FLAGS_WIDE;
+       if (flags & KVMPPC_GS_FLAGS_HOST_WIDE)
+               hflags |= H_GUEST_FLAGS_HOST_WIDE;
 
        rc = plpar_guest_get_state(hflags, gsb->guest_id, gsb->vcpu_id,
                                   __pa(gsb->hdr), gsb->capacity, &i);
-- 
2.47.1


Reply via email to