The main feature of FORM2 affinity support is the separation of NUMA distances from ibm,associativity information. This allows for a more flexible and straightforward NUMA distance assignment without relying on complex associations between several levels of NUMA via ibm,associativity matches. Another feature is its extensibility. This base support contains the facilities for NUMA distance assignment, but in the future more facilities will be added for latency, performance, bandwidth and so on. This patch implements the base FORM2 affinity support as follows: - the use of FORM2 associativity is indicated by using bit 2 of byte 5 of ibm,architecture-vec-5. A FORM2 aware guest can choose to use FORM1 or FORM2 affinity. Setting both forms will default to FORM2. We're not advertising FORM2 for pseries-6.1 and older machine versions to prevent guest visible changes in those; - ibm,associativity-reference-points has a new semantic. Instead of being used to calculate distances via NUMA levels, it's now used to indicate the primary domain index in the ibm,associativity domain of each resource. In our case it's set to {0x4}, matching the position where we already place logical_domain_id; - two new RTAS DT artifacts are introduced: ibm,numa-lookup-index-table and ibm,numa-distance-table. The index table is used to list all the NUMA logical domains of the platform, in ascending order, and allows for spartial NUMA configurations (although QEMU ATM doesn't support that). ibm,numa-distance-table is an array that contains all the distances from the first NUMA node to all other nodes, then the second NUMA node distances to all other nodes and so on; - get_max_dist_ref_points(), get_numa_assoc_size() and get_associativity() now checks for OV5_FORM2_AFFINITY and returns FORM2 values if the guest selected FORM2 affinity during CAS. Reviewed-by: Greg Kurz <groug@kaod.org> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> Message-Id: <20210920174947.556324-7-danielhb413@gmail.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
84 lines
3.2 KiB
C
84 lines
3.2 KiB
C
/*
|
|
* QEMU SPAPR Option/Architecture Vector Definitions
|
|
*
|
|
* Each architecture option is organized/documented by the following
|
|
* in LoPAPR 1.1, Table 244:
|
|
*
|
|
* <vector number>: the bit-vector in which the option is located
|
|
* <vector byte>: the byte offset of the vector entry
|
|
* <vector bit>: the bit offset within the vector entry
|
|
*
|
|
* where each vector entry can be one or more bytes.
|
|
*
|
|
* Firmware expects a somewhat literal encoding of this bit-vector
|
|
* structure, where each entry is stored in little-endian so that the
|
|
* byte ordering reflects that of the documentation, but where each bit
|
|
* offset is from "left-to-right" in the traditional representation of
|
|
* a byte value where the MSB is the left-most bit. Thus, each
|
|
* individual byte encodes the option bits in reverse order of the
|
|
* documented bit.
|
|
*
|
|
* These definitions/helpers attempt to abstract away this internal
|
|
* representation so that we can define/set/test for individual option
|
|
* bits using only the documented values. This is done mainly by relying
|
|
* on a bitmap to approximate the documented "bit-vector" structure and
|
|
* handling conversations to-from the internal representation under the
|
|
* covers.
|
|
*
|
|
* Copyright IBM Corp. 2016
|
|
*
|
|
* Authors:
|
|
* Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
* See the COPYING file in the top-level directory.
|
|
*/
|
|
|
|
#ifndef SPAPR_OVEC_H
|
|
#define SPAPR_OVEC_H
|
|
|
|
#include "cpu.h"
|
|
|
|
typedef struct SpaprOptionVector SpaprOptionVector;
|
|
|
|
#define OV_BIT(byte, bit) ((byte - 1) * BITS_PER_BYTE + bit)
|
|
|
|
/* option vector 1 */
|
|
#define OV1_PPC_3_00 OV_BIT(3, 0) /* guest supports PowerPC 3.00? */
|
|
|
|
/* option vector 5 */
|
|
#define OV5_DRCONF_MEMORY OV_BIT(2, 2)
|
|
#define OV5_FORM1_AFFINITY OV_BIT(5, 0)
|
|
#define OV5_FORM2_AFFINITY OV_BIT(5, 2)
|
|
#define OV5_HP_EVT OV_BIT(6, 5)
|
|
#define OV5_HPT_RESIZE OV_BIT(6, 7)
|
|
#define OV5_DRMEM_V2 OV_BIT(22, 0)
|
|
#define OV5_XIVE_BOTH OV_BIT(23, 0)
|
|
#define OV5_XIVE_EXPLOIT OV_BIT(23, 1) /* 1=exploitation 0=legacy */
|
|
|
|
/* ISA 3.00 MMU features: */
|
|
#define OV5_MMU_BOTH OV_BIT(24, 0) /* Radix and hash */
|
|
#define OV5_MMU_RADIX_300 OV_BIT(24, 1) /* 1=Radix only, 0=Hash only */
|
|
#define OV5_MMU_RADIX_GTSE OV_BIT(26, 1) /* Radix GTSE */
|
|
|
|
/* interfaces */
|
|
SpaprOptionVector *spapr_ovec_new(void);
|
|
SpaprOptionVector *spapr_ovec_clone(SpaprOptionVector *ov_orig);
|
|
void spapr_ovec_intersect(SpaprOptionVector *ov,
|
|
SpaprOptionVector *ov1,
|
|
SpaprOptionVector *ov2);
|
|
bool spapr_ovec_subset(SpaprOptionVector *ov1, SpaprOptionVector *ov2);
|
|
void spapr_ovec_cleanup(SpaprOptionVector *ov);
|
|
void spapr_ovec_set(SpaprOptionVector *ov, long bitnr);
|
|
void spapr_ovec_clear(SpaprOptionVector *ov, long bitnr);
|
|
bool spapr_ovec_test(SpaprOptionVector *ov, long bitnr);
|
|
bool spapr_ovec_empty(SpaprOptionVector *ov);
|
|
SpaprOptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector);
|
|
int spapr_dt_ovec(void *fdt, int fdt_offset,
|
|
SpaprOptionVector *ov, const char *name);
|
|
|
|
/* migration */
|
|
extern const VMStateDescription vmstate_spapr_ovec;
|
|
|
|
#endif /* SPAPR_OVEC_H */
|