~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/include/asm/guest-state-buffer.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * Interface based on include/net/netlink.h
  4  */
  5 #ifndef _ASM_POWERPC_GUEST_STATE_BUFFER_H
  6 #define _ASM_POWERPC_GUEST_STATE_BUFFER_H
  7 
  8 #include "asm/hvcall.h"
  9 #include <linux/gfp.h>
 10 #include <linux/bitmap.h>
 11 #include <asm/plpar_wrappers.h>
 12 
 13 /**************************************************************************
 14  * Guest State Buffer Constants
 15  **************************************************************************/
 16 /* Element without a value and any length */
 17 #define KVMPPC_GSID_BLANK                       0x0000
 18 /* Size required for the L0's internal VCPU representation */
 19 #define KVMPPC_GSID_HOST_STATE_SIZE             0x0001
 20  /* Minimum size for the H_GUEST_RUN_VCPU output buffer */
 21 #define KVMPPC_GSID_RUN_OUTPUT_MIN_SIZE         0x0002
 22  /* "Logical" PVR value as defined in the PAPR */
 23 #define KVMPPC_GSID_LOGICAL_PVR                 0x0003
 24  /* L0 relative timebase offset */
 25 #define KVMPPC_GSID_TB_OFFSET                   0x0004
 26  /* Partition Scoped Page Table Info */
 27 #define KVMPPC_GSID_PARTITION_TABLE             0x0005
 28  /* Process Table Info */
 29 #define KVMPPC_GSID_PROCESS_TABLE               0x0006
 30 
 31 /* H_GUEST_RUN_VCPU input buffer Info */
 32 #define KVMPPC_GSID_RUN_INPUT                   0x0C00
 33 /* H_GUEST_RUN_VCPU output buffer Info */
 34 #define KVMPPC_GSID_RUN_OUTPUT                  0x0C01
 35 #define KVMPPC_GSID_VPA                         0x0C02
 36 
 37 #define KVMPPC_GSID_GPR(x)                      (0x1000 + (x))
 38 #define KVMPPC_GSID_HDEC_EXPIRY_TB              0x1020
 39 #define KVMPPC_GSID_NIA                         0x1021
 40 #define KVMPPC_GSID_MSR                         0x1022
 41 #define KVMPPC_GSID_LR                          0x1023
 42 #define KVMPPC_GSID_XER                         0x1024
 43 #define KVMPPC_GSID_CTR                         0x1025
 44 #define KVMPPC_GSID_CFAR                        0x1026
 45 #define KVMPPC_GSID_SRR0                        0x1027
 46 #define KVMPPC_GSID_SRR1                        0x1028
 47 #define KVMPPC_GSID_DAR                         0x1029
 48 #define KVMPPC_GSID_DEC_EXPIRY_TB               0x102A
 49 #define KVMPPC_GSID_VTB                         0x102B
 50 #define KVMPPC_GSID_LPCR                        0x102C
 51 #define KVMPPC_GSID_HFSCR                       0x102D
 52 #define KVMPPC_GSID_FSCR                        0x102E
 53 #define KVMPPC_GSID_FPSCR                       0x102F
 54 #define KVMPPC_GSID_DAWR0                       0x1030
 55 #define KVMPPC_GSID_DAWR1                       0x1031
 56 #define KVMPPC_GSID_CIABR                       0x1032
 57 #define KVMPPC_GSID_PURR                        0x1033
 58 #define KVMPPC_GSID_SPURR                       0x1034
 59 #define KVMPPC_GSID_IC                          0x1035
 60 #define KVMPPC_GSID_SPRG0                       0x1036
 61 #define KVMPPC_GSID_SPRG1                       0x1037
 62 #define KVMPPC_GSID_SPRG2                       0x1038
 63 #define KVMPPC_GSID_SPRG3                       0x1039
 64 #define KVMPPC_GSID_PPR                         0x103A
 65 #define KVMPPC_GSID_MMCR(x)                     (0x103B + (x))
 66 #define KVMPPC_GSID_MMCRA                       0x103F
 67 #define KVMPPC_GSID_SIER(x)                     (0x1040 + (x))
 68 #define KVMPPC_GSID_BESCR                       0x1043
 69 #define KVMPPC_GSID_EBBHR                       0x1044
 70 #define KVMPPC_GSID_EBBRR                       0x1045
 71 #define KVMPPC_GSID_AMR                         0x1046
 72 #define KVMPPC_GSID_IAMR                        0x1047
 73 #define KVMPPC_GSID_AMOR                        0x1048
 74 #define KVMPPC_GSID_UAMOR                       0x1049
 75 #define KVMPPC_GSID_SDAR                        0x104A
 76 #define KVMPPC_GSID_SIAR                        0x104B
 77 #define KVMPPC_GSID_DSCR                        0x104C
 78 #define KVMPPC_GSID_TAR                         0x104D
 79 #define KVMPPC_GSID_DEXCR                       0x104E
 80 #define KVMPPC_GSID_HDEXCR                      0x104F
 81 #define KVMPPC_GSID_HASHKEYR                    0x1050
 82 #define KVMPPC_GSID_HASHPKEYR                   0x1051
 83 #define KVMPPC_GSID_CTRL                        0x1052
 84 #define KVMPPC_GSID_DPDES                       0x1053
 85 
 86 #define KVMPPC_GSID_CR                          0x2000
 87 #define KVMPPC_GSID_PIDR                        0x2001
 88 #define KVMPPC_GSID_DSISR                       0x2002
 89 #define KVMPPC_GSID_VSCR                        0x2003
 90 #define KVMPPC_GSID_VRSAVE                      0x2004
 91 #define KVMPPC_GSID_DAWRX0                      0x2005
 92 #define KVMPPC_GSID_DAWRX1                      0x2006
 93 #define KVMPPC_GSID_PMC(x)                      (0x2007 + (x))
 94 #define KVMPPC_GSID_WORT                        0x200D
 95 #define KVMPPC_GSID_PSPB                        0x200E
 96 
 97 #define KVMPPC_GSID_VSRS(x)                     (0x3000 + (x))
 98 
 99 #define KVMPPC_GSID_HDAR                        0xF000
100 #define KVMPPC_GSID_HDSISR                      0xF001
101 #define KVMPPC_GSID_HEIR                        0xF002
102 #define KVMPPC_GSID_ASDR                        0xF003
103 
104 #define KVMPPC_GSE_GUESTWIDE_START KVMPPC_GSID_BLANK
105 #define KVMPPC_GSE_GUESTWIDE_END KVMPPC_GSID_PROCESS_TABLE
106 #define KVMPPC_GSE_GUESTWIDE_COUNT \
107         (KVMPPC_GSE_GUESTWIDE_END - KVMPPC_GSE_GUESTWIDE_START + 1)
108 
109 #define KVMPPC_GSE_META_START KVMPPC_GSID_RUN_INPUT
110 #define KVMPPC_GSE_META_END KVMPPC_GSID_VPA
111 #define KVMPPC_GSE_META_COUNT (KVMPPC_GSE_META_END - KVMPPC_GSE_META_START + 1)
112 
113 #define KVMPPC_GSE_DW_REGS_START KVMPPC_GSID_GPR(0)
114 #define KVMPPC_GSE_DW_REGS_END KVMPPC_GSID_DPDES
115 #define KVMPPC_GSE_DW_REGS_COUNT \
116         (KVMPPC_GSE_DW_REGS_END - KVMPPC_GSE_DW_REGS_START + 1)
117 
118 #define KVMPPC_GSE_W_REGS_START KVMPPC_GSID_CR
119 #define KVMPPC_GSE_W_REGS_END KVMPPC_GSID_PSPB
120 #define KVMPPC_GSE_W_REGS_COUNT \
121         (KVMPPC_GSE_W_REGS_END - KVMPPC_GSE_W_REGS_START + 1)
122 
123 #define KVMPPC_GSE_VSRS_START KVMPPC_GSID_VSRS(0)
124 #define KVMPPC_GSE_VSRS_END KVMPPC_GSID_VSRS(63)
125 #define KVMPPC_GSE_VSRS_COUNT (KVMPPC_GSE_VSRS_END - KVMPPC_GSE_VSRS_START + 1)
126 
127 #define KVMPPC_GSE_INTR_REGS_START KVMPPC_GSID_HDAR
128 #define KVMPPC_GSE_INTR_REGS_END KVMPPC_GSID_ASDR
129 #define KVMPPC_GSE_INTR_REGS_COUNT \
130         (KVMPPC_GSE_INTR_REGS_END - KVMPPC_GSE_INTR_REGS_START + 1)
131 
132 #define KVMPPC_GSE_IDEN_COUNT                                 \
133         (KVMPPC_GSE_GUESTWIDE_COUNT + KVMPPC_GSE_META_COUNT + \
134          KVMPPC_GSE_DW_REGS_COUNT + KVMPPC_GSE_W_REGS_COUNT + \
135          KVMPPC_GSE_VSRS_COUNT + KVMPPC_GSE_INTR_REGS_COUNT)
136 
137 /**
138  * Ranges of guest state buffer elements
139  */
140 enum {
141         KVMPPC_GS_CLASS_GUESTWIDE = 0x01,
142         KVMPPC_GS_CLASS_META = 0x02,
143         KVMPPC_GS_CLASS_DWORD_REG = 0x04,
144         KVMPPC_GS_CLASS_WORD_REG = 0x08,
145         KVMPPC_GS_CLASS_VECTOR = 0x10,
146         KVMPPC_GS_CLASS_INTR = 0x20,
147 };
148 
149 /**
150  * Types of guest state buffer elements
151  */
152 enum {
153         KVMPPC_GSE_BE32,
154         KVMPPC_GSE_BE64,
155         KVMPPC_GSE_VEC128,
156         KVMPPC_GSE_PARTITION_TABLE,
157         KVMPPC_GSE_PROCESS_TABLE,
158         KVMPPC_GSE_BUFFER,
159         __KVMPPC_GSE_TYPE_MAX,
160 };
161 
162 /**
163  * Flags for guest state elements
164  */
165 enum {
166         KVMPPC_GS_FLAGS_WIDE = 0x01,
167 };
168 
169 /**
170  * struct kvmppc_gs_part_table - deserialized partition table information
171  * element
172  * @address: start of the partition table
173  * @ea_bits: number of bits in the effective address
174  * @gpd_size: root page directory size
175  */
176 struct kvmppc_gs_part_table {
177         u64 address;
178         u64 ea_bits;
179         u64 gpd_size;
180 };
181 
182 /**
183  * struct kvmppc_gs_proc_table - deserialized process table information element
184  * @address: start of the process table
185  * @gpd_size: process table size
186  */
187 struct kvmppc_gs_proc_table {
188         u64 address;
189         u64 gpd_size;
190 };
191 
192 /**
193  * struct kvmppc_gs_buff_info - deserialized meta guest state buffer information
194  * @address: start of the guest state buffer
195  * @size: size of the guest state buffer
196  */
197 struct kvmppc_gs_buff_info {
198         u64 address;
199         u64 size;
200 };
201 
202 /**
203  * struct kvmppc_gs_header - serialized guest state buffer header
204  * @nelem: count of guest state elements in the buffer
205  * @data: start of the stream of elements in the buffer
206  */
207 struct kvmppc_gs_header {
208         __be32 nelems;
209         char data[];
210 } __packed;
211 
212 /**
213  * struct kvmppc_gs_elem - serialized guest state buffer element
214  * @iden: Guest State ID
215  * @len: length of data
216  * @data: the guest state buffer element's value
217  */
218 struct kvmppc_gs_elem {
219         __be16 iden;
220         __be16 len;
221         char data[];
222 } __packed;
223 
224 /**
225  * struct kvmppc_gs_buff - a guest state buffer with metadata.
226  * @capacity: total length of the buffer
227  * @len: current length of the elements and header
228  * @guest_id: guest id associated with the buffer
229  * @vcpu_id: vcpu_id associated with the buffer
230  * @hdr: the serialised guest state buffer
231  */
232 struct kvmppc_gs_buff {
233         size_t capacity;
234         size_t len;
235         unsigned long guest_id;
236         unsigned long vcpu_id;
237         struct kvmppc_gs_header *hdr;
238 };
239 
240 /**
241  * struct kvmppc_gs_bitmap - a bitmap for element ids
242  * @bitmap: a bitmap large enough for all Guest State IDs
243  */
244 struct kvmppc_gs_bitmap {
245         /* private: */
246         DECLARE_BITMAP(bitmap, KVMPPC_GSE_IDEN_COUNT);
247 };
248 
249 /**
250  * struct kvmppc_gs_parser - a map of element ids to locations in a buffer
251  * @iterator: bitmap used for iterating
252  * @gses: contains the pointers to elements
253  *
254  * A guest state parser is used for deserialising a guest state buffer.
255  * Given a buffer, it then allows looking up guest state elements using
256  * a guest state id.
257  */
258 struct kvmppc_gs_parser {
259         /* private: */
260         struct kvmppc_gs_bitmap iterator;
261         struct kvmppc_gs_elem *gses[KVMPPC_GSE_IDEN_COUNT];
262 };
263 
264 enum {
265         GSM_GUEST_WIDE = 0x1,
266         GSM_SEND = 0x2,
267         GSM_RECEIVE = 0x4,
268         GSM_GSB_OWNER = 0x8,
269 };
270 
271 struct kvmppc_gs_msg;
272 
273 /**
274  * struct kvmppc_gs_msg_ops - guest state message behavior
275  * @get_size: maximum size required for the message data
276  * @fill_info: serializes to the guest state buffer format
277  * @refresh_info: dserializes from the guest state buffer format
278  */
279 struct kvmppc_gs_msg_ops {
280         size_t (*get_size)(struct kvmppc_gs_msg *gsm);
281         int (*fill_info)(struct kvmppc_gs_buff *gsb, struct kvmppc_gs_msg *gsm);
282         int (*refresh_info)(struct kvmppc_gs_msg *gsm,
283                             struct kvmppc_gs_buff *gsb);
284 };
285 
286 /**
287  * struct kvmppc_gs_msg - a guest state message
288  * @bitmap: the guest state ids that should be included
289  * @ops: modify message behavior for reading and writing to buffers
290  * @flags: guest wide or thread wide
291  * @data: location where buffer data will be written to or from.
292  *
293  * A guest state message is allows flexibility in sending in receiving data
294  * in a guest state buffer format.
295  */
296 struct kvmppc_gs_msg {
297         struct kvmppc_gs_bitmap bitmap;
298         struct kvmppc_gs_msg_ops *ops;
299         unsigned long flags;
300         void *data;
301 };
302 
303 /**************************************************************************
304  * Guest State IDs
305  **************************************************************************/
306 
307 u16 kvmppc_gsid_size(u16 iden);
308 unsigned long kvmppc_gsid_flags(u16 iden);
309 u64 kvmppc_gsid_mask(u16 iden);
310 
311 /**************************************************************************
312  * Guest State Buffers
313  **************************************************************************/
314 struct kvmppc_gs_buff *kvmppc_gsb_new(size_t size, unsigned long guest_id,
315                                       unsigned long vcpu_id, gfp_t flags);
316 void kvmppc_gsb_free(struct kvmppc_gs_buff *gsb);
317 void *kvmppc_gsb_put(struct kvmppc_gs_buff *gsb, size_t size);
318 int kvmppc_gsb_send(struct kvmppc_gs_buff *gsb, unsigned long flags);
319 int kvmppc_gsb_recv(struct kvmppc_gs_buff *gsb, unsigned long flags);
320 
321 /**
322  * kvmppc_gsb_header() - the header of a guest state buffer
323  * @gsb: guest state buffer
324  *
325  * Returns a pointer to the buffer header.
326  */
327 static inline struct kvmppc_gs_header *
328 kvmppc_gsb_header(struct kvmppc_gs_buff *gsb)
329 {
330         return gsb->hdr;
331 }
332 
333 /**
334  * kvmppc_gsb_data() - the elements of a guest state buffer
335  * @gsb: guest state buffer
336  *
337  * Returns a pointer to the first element of the buffer data.
338  */
339 static inline struct kvmppc_gs_elem *kvmppc_gsb_data(struct kvmppc_gs_buff *gsb)
340 {
341         return (struct kvmppc_gs_elem *)kvmppc_gsb_header(gsb)->data;
342 }
343 
344 /**
345  * kvmppc_gsb_len() - the current length of a guest state buffer
346  * @gsb: guest state buffer
347  *
348  * Returns the length including the header of a buffer.
349  */
350 static inline size_t kvmppc_gsb_len(struct kvmppc_gs_buff *gsb)
351 {
352         return gsb->len;
353 }
354 
355 /**
356  * kvmppc_gsb_capacity() - the capacity of a guest state buffer
357  * @gsb: guest state buffer
358  *
359  * Returns the capacity of a buffer.
360  */
361 static inline size_t kvmppc_gsb_capacity(struct kvmppc_gs_buff *gsb)
362 {
363         return gsb->capacity;
364 }
365 
366 /**
367  * kvmppc_gsb_paddress() - the physical address of buffer
368  * @gsb: guest state buffer
369  *
370  * Returns the physical address of the buffer.
371  */
372 static inline u64 kvmppc_gsb_paddress(struct kvmppc_gs_buff *gsb)
373 {
374         return __pa(kvmppc_gsb_header(gsb));
375 }
376 
377 /**
378  * kvmppc_gsb_nelems() - the number of elements in a buffer
379  * @gsb: guest state buffer
380  *
381  * Returns the number of elements in a buffer
382  */
383 static inline u32 kvmppc_gsb_nelems(struct kvmppc_gs_buff *gsb)
384 {
385         return be32_to_cpu(kvmppc_gsb_header(gsb)->nelems);
386 }
387 
388 /**
389  * kvmppc_gsb_reset() - empty a guest state buffer
390  * @gsb: guest state buffer
391  *
392  * Reset the number of elements and length of buffer to empty.
393  */
394 static inline void kvmppc_gsb_reset(struct kvmppc_gs_buff *gsb)
395 {
396         kvmppc_gsb_header(gsb)->nelems = cpu_to_be32(0);
397         gsb->len = sizeof(struct kvmppc_gs_header);
398 }
399 
400 /**
401  * kvmppc_gsb_data_len() - the length of a buffer excluding the header
402  * @gsb: guest state buffer
403  *
404  * Returns the length of a buffer excluding the header
405  */
406 static inline size_t kvmppc_gsb_data_len(struct kvmppc_gs_buff *gsb)
407 {
408         return gsb->len - sizeof(struct kvmppc_gs_header);
409 }
410 
411 /**
412  * kvmppc_gsb_data_cap() - the capacity of a buffer excluding the header
413  * @gsb: guest state buffer
414  *
415  * Returns the capacity of a buffer excluding the header
416  */
417 static inline size_t kvmppc_gsb_data_cap(struct kvmppc_gs_buff *gsb)
418 {
419         return gsb->capacity - sizeof(struct kvmppc_gs_header);
420 }
421 
422 /**
423  * kvmppc_gsb_for_each_elem - iterate over the elements in a buffer
424  * @i: loop counter
425  * @pos: set to current element
426  * @gsb: guest state buffer
427  * @rem: initialized to buffer capacity, holds bytes currently remaining in
428  *  stream
429  */
430 #define kvmppc_gsb_for_each_elem(i, pos, gsb, rem)               \
431         kvmppc_gse_for_each_elem(i, kvmppc_gsb_nelems(gsb), pos, \
432                                  kvmppc_gsb_data(gsb),           \
433                                  kvmppc_gsb_data_cap(gsb), rem)
434 
435 /**************************************************************************
436  * Guest State Elements
437  **************************************************************************/
438 
439 /**
440  * kvmppc_gse_iden() - guest state ID of element
441  * @gse: guest state element
442  *
443  * Return the guest state ID in host endianness.
444  */
445 static inline u16 kvmppc_gse_iden(const struct kvmppc_gs_elem *gse)
446 {
447         return be16_to_cpu(gse->iden);
448 }
449 
450 /**
451  * kvmppc_gse_len() - length of guest state element data
452  * @gse: guest state element
453  *
454  * Returns the length of guest state element data
455  */
456 static inline u16 kvmppc_gse_len(const struct kvmppc_gs_elem *gse)
457 {
458         return be16_to_cpu(gse->len);
459 }
460 
461 /**
462  * kvmppc_gse_total_len() - total length of guest state element
463  * @gse: guest state element
464  *
465  * Returns the length of the data plus the ID and size header.
466  */
467 static inline u16 kvmppc_gse_total_len(const struct kvmppc_gs_elem *gse)
468 {
469         return be16_to_cpu(gse->len) + sizeof(*gse);
470 }
471 
472 /**
473  * kvmppc_gse_total_size() - space needed for a given data length
474  * @size: data length
475  *
476  * Returns size plus the space needed for the ID and size header.
477  */
478 static inline u16 kvmppc_gse_total_size(u16 size)
479 {
480         return sizeof(struct kvmppc_gs_elem) + size;
481 }
482 
483 /**
484  * kvmppc_gse_data() - pointer to data of a guest state element
485  * @gse: guest state element
486  *
487  * Returns a pointer to the beginning of guest state element data.
488  */
489 static inline void *kvmppc_gse_data(const struct kvmppc_gs_elem *gse)
490 {
491         return (void *)gse->data;
492 }
493 
494 /**
495  * kvmppc_gse_ok() - checks space exists for guest state element
496  * @gse: guest state element
497  * @remaining: bytes of space remaining
498  *
499  * Returns true if the guest state element can fit in remaining space.
500  */
501 static inline bool kvmppc_gse_ok(const struct kvmppc_gs_elem *gse,
502                                  int remaining)
503 {
504         return remaining >= kvmppc_gse_total_len(gse);
505 }
506 
507 /**
508  * kvmppc_gse_next() - iterate to the next guest state element in a stream
509  * @gse: stream of guest state elements
510  * @remaining: length of the guest element stream
511  *
512  * Returns the next guest state element in a stream of elements. The length of
513  * the stream is updated in remaining.
514  */
515 static inline struct kvmppc_gs_elem *
516 kvmppc_gse_next(const struct kvmppc_gs_elem *gse, int *remaining)
517 {
518         int len = sizeof(*gse) + kvmppc_gse_len(gse);
519 
520         *remaining -= len;
521         return (struct kvmppc_gs_elem *)(gse->data + kvmppc_gse_len(gse));
522 }
523 
524 /**
525  * kvmppc_gse_for_each_elem - iterate over a stream of guest state elements
526  * @i: loop counter
527  * @max: number of elements
528  * @pos: set to current element
529  * @head: head of elements
530  * @len: length of the stream
531  * @rem: initialized to len, holds bytes currently remaining elements
532  */
533 #define kvmppc_gse_for_each_elem(i, max, pos, head, len, rem)                  \
534         for (i = 0, pos = head, rem = len; kvmppc_gse_ok(pos, rem) && i < max; \
535              pos = kvmppc_gse_next(pos, &(rem)), i++)
536 
537 int __kvmppc_gse_put(struct kvmppc_gs_buff *gsb, u16 iden, u16 size,
538                      const void *data);
539 int kvmppc_gse_parse(struct kvmppc_gs_parser *gsp, struct kvmppc_gs_buff *gsb);
540 
541 /**
542  * kvmppc_gse_put_be32() - add a be32 guest state element to a buffer
543  * @gsb: guest state buffer to add element to
544  * @iden: guest state ID
545  * @val: big endian value
546  */
547 static inline int kvmppc_gse_put_be32(struct kvmppc_gs_buff *gsb, u16 iden,
548                                       __be32 val)
549 {
550         __be32 tmp;
551 
552         tmp = val;
553         return __kvmppc_gse_put(gsb, iden, sizeof(__be32), &tmp);
554 }
555 
556 /**
557  * kvmppc_gse_put_u32() - add a host endian 32bit int guest state element to a
558  * buffer
559  * @gsb: guest state buffer to add element to
560  * @iden: guest state ID
561  * @val: host endian value
562  */
563 static inline int kvmppc_gse_put_u32(struct kvmppc_gs_buff *gsb, u16 iden,
564                                      u32 val)
565 {
566         __be32 tmp;
567 
568         val &= kvmppc_gsid_mask(iden);
569         tmp = cpu_to_be32(val);
570         return kvmppc_gse_put_be32(gsb, iden, tmp);
571 }
572 
573 /**
574  * kvmppc_gse_put_be64() - add a be64 guest state element to a buffer
575  * @gsb: guest state buffer to add element to
576  * @iden: guest state ID
577  * @val: big endian value
578  */
579 static inline int kvmppc_gse_put_be64(struct kvmppc_gs_buff *gsb, u16 iden,
580                                       __be64 val)
581 {
582         __be64 tmp;
583 
584         tmp = val;
585         return __kvmppc_gse_put(gsb, iden, sizeof(__be64), &tmp);
586 }
587 
588 /**
589  * kvmppc_gse_put_u64() - add a host endian 64bit guest state element to a
590  * buffer
591  * @gsb: guest state buffer to add element to
592  * @iden: guest state ID
593  * @val: host endian value
594  */
595 static inline int kvmppc_gse_put_u64(struct kvmppc_gs_buff *gsb, u16 iden,
596                                      u64 val)
597 {
598         __be64 tmp;
599 
600         val &= kvmppc_gsid_mask(iden);
601         tmp = cpu_to_be64(val);
602         return kvmppc_gse_put_be64(gsb, iden, tmp);
603 }
604 
605 /**
606  * __kvmppc_gse_put_reg() - add a register type guest state element to a buffer
607  * @gsb: guest state buffer to add element to
608  * @iden: guest state ID
609  * @val: host endian value
610  *
611  * Adds a register type guest state element. Uses the guest state ID for
612  * determining the length of the guest element. If the guest state ID has
613  * bits that can not be set they will be cleared.
614  */
615 static inline int __kvmppc_gse_put_reg(struct kvmppc_gs_buff *gsb, u16 iden,
616                                        u64 val)
617 {
618         val &= kvmppc_gsid_mask(iden);
619         if (kvmppc_gsid_size(iden) == sizeof(u64))
620                 return kvmppc_gse_put_u64(gsb, iden, val);
621 
622         if (kvmppc_gsid_size(iden) == sizeof(u32)) {
623                 u32 tmp;
624 
625                 tmp = (u32)val;
626                 if (tmp != val)
627                         return -EINVAL;
628 
629                 return kvmppc_gse_put_u32(gsb, iden, tmp);
630         }
631         return -EINVAL;
632 }
633 
634 /**
635  * kvmppc_gse_put_vector128() - add a vector guest state element to a buffer
636  * @gsb: guest state buffer to add element to
637  * @iden: guest state ID
638  * @val: 16 byte vector value
639  */
640 static inline int kvmppc_gse_put_vector128(struct kvmppc_gs_buff *gsb, u16 iden,
641                                            vector128 *val)
642 {
643         __be64 tmp[2] = { 0 };
644         union {
645                 __vector128 v;
646                 u64 dw[2];
647         } u;
648 
649         u.v = *val;
650         tmp[0] = cpu_to_be64(u.dw[TS_FPROFFSET]);
651 #ifdef CONFIG_VSX
652         tmp[1] = cpu_to_be64(u.dw[TS_VSRLOWOFFSET]);
653 #endif
654         return __kvmppc_gse_put(gsb, iden, sizeof(tmp), &tmp);
655 }
656 
657 /**
658  * kvmppc_gse_put_part_table() - add a partition table guest state element to a
659  * buffer
660  * @gsb: guest state buffer to add element to
661  * @iden: guest state ID
662  * @val: partition table value
663  */
664 static inline int kvmppc_gse_put_part_table(struct kvmppc_gs_buff *gsb,
665                                             u16 iden,
666                                             struct kvmppc_gs_part_table val)
667 {
668         __be64 tmp[3];
669 
670         tmp[0] = cpu_to_be64(val.address);
671         tmp[1] = cpu_to_be64(val.ea_bits);
672         tmp[2] = cpu_to_be64(val.gpd_size);
673         return __kvmppc_gse_put(gsb, KVMPPC_GSID_PARTITION_TABLE, sizeof(tmp),
674                                 &tmp);
675 }
676 
677 /**
678  * kvmppc_gse_put_proc_table() - add a process table guest state element to a
679  * buffer
680  * @gsb: guest state buffer to add element to
681  * @iden: guest state ID
682  * @val: process table value
683  */
684 static inline int kvmppc_gse_put_proc_table(struct kvmppc_gs_buff *gsb,
685                                             u16 iden,
686                                             struct kvmppc_gs_proc_table val)
687 {
688         __be64 tmp[2];
689 
690         tmp[0] = cpu_to_be64(val.address);
691         tmp[1] = cpu_to_be64(val.gpd_size);
692         return __kvmppc_gse_put(gsb, KVMPPC_GSID_PROCESS_TABLE, sizeof(tmp),
693                                 &tmp);
694 }
695 
696 /**
697  * kvmppc_gse_put_buff_info() - adds a GSB description guest state element to a
698  * buffer
699  * @gsb: guest state buffer to add element to
700  * @iden: guest state ID
701  * @val: guest state buffer description value
702  */
703 static inline int kvmppc_gse_put_buff_info(struct kvmppc_gs_buff *gsb, u16 iden,
704                                            struct kvmppc_gs_buff_info val)
705 {
706         __be64 tmp[2];
707 
708         tmp[0] = cpu_to_be64(val.address);
709         tmp[1] = cpu_to_be64(val.size);
710         return __kvmppc_gse_put(gsb, iden, sizeof(tmp), &tmp);
711 }
712 
713 int __kvmppc_gse_put(struct kvmppc_gs_buff *gsb, u16 iden, u16 size,
714                      const void *data);
715 
716 /**
717  * kvmppc_gse_get_be32() - return the data of a be32 element
718  * @gse: guest state element
719  */
720 static inline __be32 kvmppc_gse_get_be32(const struct kvmppc_gs_elem *gse)
721 {
722         if (WARN_ON(kvmppc_gse_len(gse) != sizeof(__be32)))
723                 return 0;
724         return *(__be32 *)kvmppc_gse_data(gse);
725 }
726 
727 /**
728  * kvmppc_gse_get_u32() - return the data of a be32 element in host endianness
729  * @gse: guest state element
730  */
731 static inline u32 kvmppc_gse_get_u32(const struct kvmppc_gs_elem *gse)
732 {
733         return be32_to_cpu(kvmppc_gse_get_be32(gse));
734 }
735 
736 /**
737  * kvmppc_gse_get_be64() - return the data of a be64 element
738  * @gse: guest state element
739  */
740 static inline __be64 kvmppc_gse_get_be64(const struct kvmppc_gs_elem *gse)
741 {
742         if (WARN_ON(kvmppc_gse_len(gse) != sizeof(__be64)))
743                 return 0;
744         return *(__be64 *)kvmppc_gse_data(gse);
745 }
746 
747 /**
748  * kvmppc_gse_get_u64() - return the data of a be64 element in host endianness
749  * @gse: guest state element
750  */
751 static inline u64 kvmppc_gse_get_u64(const struct kvmppc_gs_elem *gse)
752 {
753         return be64_to_cpu(kvmppc_gse_get_be64(gse));
754 }
755 
756 /**
757  * kvmppc_gse_get_vector128() - return the data of a vector element
758  * @gse: guest state element
759  */
760 static inline void kvmppc_gse_get_vector128(const struct kvmppc_gs_elem *gse,
761                                             vector128 *v)
762 {
763         union {
764                 __vector128 v;
765                 u64 dw[2];
766         } u = { 0 };
767         __be64 *src;
768 
769         if (WARN_ON(kvmppc_gse_len(gse) != sizeof(__vector128)))
770                 *v = u.v;
771 
772         src = (__be64 *)kvmppc_gse_data(gse);
773         u.dw[TS_FPROFFSET] = be64_to_cpu(src[0]);
774 #ifdef CONFIG_VSX
775         u.dw[TS_VSRLOWOFFSET] = be64_to_cpu(src[1]);
776 #endif
777         *v = u.v;
778 }
779 
780 /**************************************************************************
781  * Guest State Bitmap
782  **************************************************************************/
783 
784 bool kvmppc_gsbm_test(struct kvmppc_gs_bitmap *gsbm, u16 iden);
785 void kvmppc_gsbm_set(struct kvmppc_gs_bitmap *gsbm, u16 iden);
786 void kvmppc_gsbm_clear(struct kvmppc_gs_bitmap *gsbm, u16 iden);
787 u16 kvmppc_gsbm_next(struct kvmppc_gs_bitmap *gsbm, u16 prev);
788 
789 /**
790  * kvmppc_gsbm_zero - zero the entire bitmap
791  * @gsbm: guest state buffer bitmap
792  */
793 static inline void kvmppc_gsbm_zero(struct kvmppc_gs_bitmap *gsbm)
794 {
795         bitmap_zero(gsbm->bitmap, KVMPPC_GSE_IDEN_COUNT);
796 }
797 
798 /**
799  * kvmppc_gsbm_fill - fill the entire bitmap
800  * @gsbm: guest state buffer bitmap
801  */
802 static inline void kvmppc_gsbm_fill(struct kvmppc_gs_bitmap *gsbm)
803 {
804         bitmap_fill(gsbm->bitmap, KVMPPC_GSE_IDEN_COUNT);
805         clear_bit(0, gsbm->bitmap);
806 }
807 
808 /**
809  * kvmppc_gsbm_for_each - iterate the present guest state IDs
810  * @gsbm: guest state buffer bitmap
811  * @iden: current guest state ID
812  */
813 #define kvmppc_gsbm_for_each(gsbm, iden)                  \
814         for (iden = kvmppc_gsbm_next(gsbm, 0); iden != 0; \
815              iden = kvmppc_gsbm_next(gsbm, iden))
816 
817 /**************************************************************************
818  * Guest State Parser
819  **************************************************************************/
820 
821 void kvmppc_gsp_insert(struct kvmppc_gs_parser *gsp, u16 iden,
822                        struct kvmppc_gs_elem *gse);
823 struct kvmppc_gs_elem *kvmppc_gsp_lookup(struct kvmppc_gs_parser *gsp,
824                                          u16 iden);
825 
826 /**
827  * kvmppc_gsp_for_each - iterate the <guest state IDs, guest state element>
828  * pairs
829  * @gsp: guest state buffer bitmap
830  * @iden: current guest state ID
831  * @gse: guest state element
832  */
833 #define kvmppc_gsp_for_each(gsp, iden, gse)                              \
834         for (iden = kvmppc_gsbm_next(&(gsp)->iterator, 0),               \
835             gse = kvmppc_gsp_lookup((gsp), iden);                        \
836              iden != 0; iden = kvmppc_gsbm_next(&(gsp)->iterator, iden), \
837             gse = kvmppc_gsp_lookup((gsp), iden))
838 
839 /**************************************************************************
840  * Guest State Message
841  **************************************************************************/
842 
843 /**
844  * kvmppc_gsm_for_each - iterate the guest state IDs included in a guest state
845  * message
846  * @gsp: guest state buffer bitmap
847  * @iden: current guest state ID
848  * @gse: guest state element
849  */
850 #define kvmppc_gsm_for_each(gsm, iden)                            \
851         for (iden = kvmppc_gsbm_next(&gsm->bitmap, 0); iden != 0; \
852              iden = kvmppc_gsbm_next(&gsm->bitmap, iden))
853 
854 int kvmppc_gsm_init(struct kvmppc_gs_msg *mgs, struct kvmppc_gs_msg_ops *ops,
855                     void *data, unsigned long flags);
856 
857 struct kvmppc_gs_msg *kvmppc_gsm_new(struct kvmppc_gs_msg_ops *ops, void *data,
858                                      unsigned long flags, gfp_t gfp_flags);
859 void kvmppc_gsm_free(struct kvmppc_gs_msg *gsm);
860 size_t kvmppc_gsm_size(struct kvmppc_gs_msg *gsm);
861 int kvmppc_gsm_fill_info(struct kvmppc_gs_msg *gsm, struct kvmppc_gs_buff *gsb);
862 int kvmppc_gsm_refresh_info(struct kvmppc_gs_msg *gsm,
863                             struct kvmppc_gs_buff *gsb);
864 
865 /**
866  * kvmppc_gsm_include - indicate a guest state ID should be included when
867  * serializing
868  * @gsm: guest state message
869  * @iden: guest state ID
870  */
871 static inline void kvmppc_gsm_include(struct kvmppc_gs_msg *gsm, u16 iden)
872 {
873         kvmppc_gsbm_set(&gsm->bitmap, iden);
874 }
875 
876 /**
877  * kvmppc_gsm_includes - check if a guest state ID will be included when
878  * serializing
879  * @gsm: guest state message
880  * @iden: guest state ID
881  */
882 static inline bool kvmppc_gsm_includes(struct kvmppc_gs_msg *gsm, u16 iden)
883 {
884         return kvmppc_gsbm_test(&gsm->bitmap, iden);
885 }
886 
887 /**
888  * kvmppc_gsm_includes - indicate all guest state IDs should be included when
889  * serializing
890  * @gsm: guest state message
891  * @iden: guest state ID
892  */
893 static inline void kvmppc_gsm_include_all(struct kvmppc_gs_msg *gsm)
894 {
895         kvmppc_gsbm_fill(&gsm->bitmap);
896 }
897 
898 /**
899  * kvmppc_gsm_include - clear the guest state IDs that should be included when
900  * serializing
901  * @gsm: guest state message
902  */
903 static inline void kvmppc_gsm_reset(struct kvmppc_gs_msg *gsm)
904 {
905         kvmppc_gsbm_zero(&gsm->bitmap);
906 }
907 
908 /**
909  * kvmppc_gsb_receive_data - flexibly update values from a guest state buffer
910  * @gsb: guest state buffer
911  * @gsm: guest state message
912  *
913  * Requests updated values for the guest state values included in the guest
914  * state message. The guest state message will then deserialize the guest state
915  * buffer.
916  */
917 static inline int kvmppc_gsb_receive_data(struct kvmppc_gs_buff *gsb,
918                                           struct kvmppc_gs_msg *gsm)
919 {
920         int rc;
921 
922         kvmppc_gsb_reset(gsb);
923         rc = kvmppc_gsm_fill_info(gsm, gsb);
924         if (rc < 0)
925                 return rc;
926 
927         rc = kvmppc_gsb_recv(gsb, gsm->flags);
928         if (rc < 0)
929                 return rc;
930 
931         rc = kvmppc_gsm_refresh_info(gsm, gsb);
932         if (rc < 0)
933                 return rc;
934         return 0;
935 }
936 
937 /**
938  * kvmppc_gsb_recv - receive a single guest state ID
939  * @gsb: guest state buffer
940  * @gsm: guest state message
941  * @iden: guest state identity
942  */
943 static inline int kvmppc_gsb_receive_datum(struct kvmppc_gs_buff *gsb,
944                                            struct kvmppc_gs_msg *gsm, u16 iden)
945 {
946         int rc;
947 
948         kvmppc_gsm_include(gsm, iden);
949         rc = kvmppc_gsb_receive_data(gsb, gsm);
950         if (rc < 0)
951                 return rc;
952         kvmppc_gsm_reset(gsm);
953         return 0;
954 }
955 
956 /**
957  * kvmppc_gsb_send_data - flexibly send values from a guest state buffer
958  * @gsb: guest state buffer
959  * @gsm: guest state message
960  *
961  * Sends the guest state values included in the guest state message.
962  */
963 static inline int kvmppc_gsb_send_data(struct kvmppc_gs_buff *gsb,
964                                        struct kvmppc_gs_msg *gsm)
965 {
966         int rc;
967 
968         kvmppc_gsb_reset(gsb);
969         rc = kvmppc_gsm_fill_info(gsm, gsb);
970         if (rc < 0)
971                 return rc;
972         rc = kvmppc_gsb_send(gsb, gsm->flags);
973 
974         return rc;
975 }
976 
977 /**
978  * kvmppc_gsb_recv - send a single guest state ID
979  * @gsb: guest state buffer
980  * @gsm: guest state message
981  * @iden: guest state identity
982  */
983 static inline int kvmppc_gsb_send_datum(struct kvmppc_gs_buff *gsb,
984                                         struct kvmppc_gs_msg *gsm, u16 iden)
985 {
986         int rc;
987 
988         kvmppc_gsm_include(gsm, iden);
989         rc = kvmppc_gsb_send_data(gsb, gsm);
990         if (rc < 0)
991                 return rc;
992         kvmppc_gsm_reset(gsm);
993         return 0;
994 }
995 
996 #endif /* _ASM_POWERPC_GUEST_STATE_BUFFER_H */
997 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php