* PAPR nested hypervisor host implementation for spapr TCG

* excp_helper.c code cleanups and improvements
 * Move more ops to decodetree
 * Deprecate pseries-2.12 machines and P9 and P10 DD1.0 CPUs
 * Document running Linux on AmigaNG
 * Update dt feature advertising POWER CPUs.
 * Add P10 PMU SPRs
 * Improve pnv topology calculation for SMT8 CPUs.
 * Various bug fixes.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEETkN92lZhb0MpsKeVZ7MCdqhiHK4FAmXwiT8ACgkQZ7MCdqhi
 HK7C/w//XxEO2bQTFPLFDTrP/voq7pcX8XeQNVyXCkXYjvsbu05oQow50k+Y5UAE
 US4MFjt8jFz0vuIKuKyoA3kG41zDSOzoX4TQXMM+tyTWbuFF3KAyfizb1xE6SYAN
 xJEGvmiXv/EgoSBD7BTKQp1tMPdIGZLwSdYiA0lmOo7YaMCgYAXaujW5hnNjQecT
 873sN+10pHtQY++mINtD9Nfb6AcDGMWw0b+bykqIXhNRkI8IGOS4WF4vAuMBrwfe
 UM00wDnNRb86Dk14bv2XVNDr6/i0VRtUMwM4yiptrQ1TQx18LZaPSQFYjQfPaan7
 LwN4QkMFnBX54yJ7Npvjvu8BCBF47kwOVu4CIAFJ4sIm0WfTmozDpPttwcZ5w7Ve
 iXDOB9ECAB4pQ2rCgbSNG8MYUZgoHHOuThqolOP0Vh9NHRRJxpdw6CyAbmCGftc0
 lvRDPFiKp8xmCNJ/j3XzoUdHoG7NMwpUmHv9ruGU18SdQ8hyJN9AcQGWYrB4v0RV
 /hs2RAbwntG7ahkcwd8uy5aFw88Wph/uGXPXc49EWj7i49vHeIV2y5+gtthMywje
 qqjFXkistXuF+JHVnyoYmqqCyXaHX5CEwtawMv4EQeaJs76bLhMeMTKKl9rRp8qB
 DtbIZphO8iMsocrBnje48sA5HR0PM+H4HTjw10i8R0fLlWitaIY=
 =XnY5
 -----END PGP SIGNATURE-----

Merge tag 'pull-ppc-for-9.0-2-20240313' of https://gitlab.com/npiggin/qemu into staging

* PAPR nested hypervisor host implementation for spapr TCG
* excp_helper.c code cleanups and improvements
* Move more ops to decodetree
* Deprecate pseries-2.12 machines and P9 and P10 DD1.0 CPUs
* Document running Linux on AmigaNG
* Update dt feature advertising POWER CPUs.
* Add P10 PMU SPRs
* Improve pnv topology calculation for SMT8 CPUs.
* Various bug fixes.

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEETkN92lZhb0MpsKeVZ7MCdqhiHK4FAmXwiT8ACgkQZ7MCdqhi
# HK7C/w//XxEO2bQTFPLFDTrP/voq7pcX8XeQNVyXCkXYjvsbu05oQow50k+Y5UAE
# US4MFjt8jFz0vuIKuKyoA3kG41zDSOzoX4TQXMM+tyTWbuFF3KAyfizb1xE6SYAN
# xJEGvmiXv/EgoSBD7BTKQp1tMPdIGZLwSdYiA0lmOo7YaMCgYAXaujW5hnNjQecT
# 873sN+10pHtQY++mINtD9Nfb6AcDGMWw0b+bykqIXhNRkI8IGOS4WF4vAuMBrwfe
# UM00wDnNRb86Dk14bv2XVNDr6/i0VRtUMwM4yiptrQ1TQx18LZaPSQFYjQfPaan7
# LwN4QkMFnBX54yJ7Npvjvu8BCBF47kwOVu4CIAFJ4sIm0WfTmozDpPttwcZ5w7Ve
# iXDOB9ECAB4pQ2rCgbSNG8MYUZgoHHOuThqolOP0Vh9NHRRJxpdw6CyAbmCGftc0
# lvRDPFiKp8xmCNJ/j3XzoUdHoG7NMwpUmHv9ruGU18SdQ8hyJN9AcQGWYrB4v0RV
# /hs2RAbwntG7ahkcwd8uy5aFw88Wph/uGXPXc49EWj7i49vHeIV2y5+gtthMywje
# qqjFXkistXuF+JHVnyoYmqqCyXaHX5CEwtawMv4EQeaJs76bLhMeMTKKl9rRp8qB
# DtbIZphO8iMsocrBnje48sA5HR0PM+H4HTjw10i8R0fLlWitaIY=
# =XnY5
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 12 Mar 2024 16:56:31 GMT
# gpg:                using RSA key 4E437DDA56616F4329B0A79567B30276A8621CAE
# gpg: Good signature from "Nicholas Piggin <npiggin@gmail.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 4E43 7DDA 5661 6F43 29B0  A795 67B3 0276 A862 1CAE

* tag 'pull-ppc-for-9.0-2-20240313' of https://gitlab.com/npiggin/qemu: (38 commits)
  spapr: nested: Introduce cap-nested-papr for Nested PAPR API
  spapr: nested: Introduce H_GUEST_RUN_VCPU hcall.
  spapr: nested: Use correct source for parttbl info for nested PAPR API.
  spapr: nested: Introduce H_GUEST_[GET|SET]_STATE hcalls.
  spapr: nested: Initialize the GSB elements lookup table.
  spapr: nested: Extend nested_ppc_state for nested PAPR API
  spapr: nested: Introduce H_GUEST_CREATE_VCPU hcall.
  spapr: nested: Introduce H_GUEST_[CREATE|DELETE] hcalls.
  spapr: nested: Introduce H_GUEST_[GET|SET]_CAPABILITIES hcalls.
  spapr: nested: Document Nested PAPR API
  spapr: nested: keep nested-hv related code restricted to its API.
  spapr: nested: Introduce SpaprMachineStateNested to store related info.
  spapr: nested: move nested part of spapr_get_pate into spapr_nested.c
  spapr: nested: register nested-hv api hcalls only for cap-nested-hv
  target/ppc: Remove interrupt handler wrapper functions
  target/ppc: Clean up ifdefs in excp_helper.c, part 3
  target/ppc: Clean up ifdefs in excp_helper.c, part 2
  target/ppc: Clean up ifdefs in excp_helper.c, part 1
  target/ppc: Add gen_exception_err_nip() function
  target/ppc: Readability improvements in exception handlers
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2024-03-13 12:37:27 +00:00
commit 51e31f2140
28 changed files with 2883 additions and 563 deletions

View file

@ -133,7 +133,7 @@ static int get_cpus_node(void *fdt)
* device tree, used in XSCOM to address cores and in interrupt
* servers.
*/
static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
{
PowerPCCPU *cpu = pc->threads[0];
CPUState *cs = CPU(cpu);
@ -141,32 +141,31 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
int smt_threads = CPU_CORE(pc)->nr_threads;
CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
PnvChipClass *pnv_cc = PNV_CHIP_GET_CLASS(chip);
g_autofree uint32_t *servers_prop = g_new(uint32_t, smt_threads);
int i;
uint32_t pir;
uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
0xffffffff, 0xffffffff};
uint32_t tbfreq = PNV_TIMEBASE_FREQ;
uint32_t cpufreq = 1000000000;
uint32_t page_sizes_prop[64];
size_t page_sizes_prop_size;
const uint8_t pa_features[] = { 24, 0,
0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xf0,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
int offset;
char *nodename;
int cpus_offset = get_cpus_node(fdt);
nodename = g_strdup_printf("%s@%x", dc->fw_name, pc->pir);
pir = pnv_cc->chip_pir(chip, pc->hwid, 0);
nodename = g_strdup_printf("%s@%x", dc->fw_name, pir);
offset = fdt_add_subnode(fdt, cpus_offset, nodename);
_FDT(offset);
g_free(nodename);
_FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id", chip->chip_id)));
_FDT((fdt_setprop_cell(fdt, offset, "reg", pc->pir)));
_FDT((fdt_setprop_cell(fdt, offset, "ibm,pir", pc->pir)));
_FDT((fdt_setprop_cell(fdt, offset, "reg", pir)));
_FDT((fdt_setprop_cell(fdt, offset, "ibm,pir", pir)));
_FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
_FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));
@ -236,20 +235,21 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
page_sizes_prop, page_sizes_prop_size)));
}
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
pa_features, sizeof(pa_features))));
/* Build interrupt servers properties */
for (i = 0; i < smt_threads; i++) {
servers_prop[i] = cpu_to_be32(pc->pir + i);
servers_prop[i] = cpu_to_be32(pnv_cc->chip_pir(chip, pc->hwid, i));
}
_FDT((fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
servers_prop, sizeof(*servers_prop) * smt_threads)));
return offset;
}
static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t hwid,
uint32_t nr_threads)
{
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
uint32_t pir = pcc->chip_pir(chip, hwid, 0);
uint64_t addr = PNV_ICP_BASE(chip) | (pir << 12);
char *name;
const char compat[] = "IBM,power8-icp\0IBM,ppc-xicp";
@ -263,6 +263,7 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
rsize = sizeof(uint64_t) * 2 * nr_threads;
reg = g_malloc(rsize);
for (i = 0; i < nr_threads; i++) {
/* We know P8 PIR is linear with thread id */
reg[i * 2] = cpu_to_be64(addr | ((pir + i) * 0x1000));
reg[i * 2 + 1] = cpu_to_be64(0x1000);
}
@ -299,6 +300,17 @@ PnvChip *pnv_chip_add_phb(PnvChip *chip, PnvPHB *phb)
return chip;
}
/*
* Same as spapr pa_features_207 except pnv always enables CI largepages bit.
* HTM is always enabled because TCG does implement HTM, it's just a
* degenerate implementation.
*/
static const uint8_t pa_features_207[] = { 24, 0,
0xf6, 0x3f, 0xc7, 0xc0, 0x00, 0xf0,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
{
static const char compat[] = "ibm,power8-xscom\0ibm,xscom";
@ -311,11 +323,15 @@ static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
for (i = 0; i < chip->nr_cores; i++) {
PnvCore *pnv_core = chip->cores[i];
int offset;
pnv_dt_core(chip, pnv_core, fdt);
offset = pnv_dt_core(chip, pnv_core, fdt);
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
pa_features_207, sizeof(pa_features_207))));
/* Interrupt Control Presenters (ICP). One per core. */
pnv_dt_icp(chip, fdt, pnv_core->pir, CPU_CORE(pnv_core)->nr_threads);
pnv_dt_icp(chip, fdt, pnv_core->hwid, CPU_CORE(pnv_core)->nr_threads);
}
if (chip->ram_size) {
@ -323,6 +339,35 @@ static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
}
}
/*
* Same as spapr pa_features_300 except pnv always enables CI largepages bit.
*/
static const uint8_t pa_features_300[] = { 66, 0,
/* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: CILRG|fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
0xf6, 0x3f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
/* 6: DS207 */
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
/* 16: Vector */
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
/* 18: Vec. Scalar, 20: Vec. XOR, 22: HTM */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 18 - 23 */
/* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
/* 32: LE atomic, 34: EBB + ext EBB */
0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
/* 40: Radix MMU */
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
/* 42: PM, 44: PC RA, 46: SC vec'd */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
/* 48: SIMD, 50: QP BFP, 52: String */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
/* 54: DecFP, 56: DecI, 58: SHA */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
/* 60: NM atomic, 62: RNG */
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
};
static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
{
static const char compat[] = "ibm,power9-xscom\0ibm,xscom";
@ -335,8 +380,12 @@ static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
for (i = 0; i < chip->nr_cores; i++) {
PnvCore *pnv_core = chip->cores[i];
int offset;
pnv_dt_core(chip, pnv_core, fdt);
offset = pnv_dt_core(chip, pnv_core, fdt);
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
pa_features_300, sizeof(pa_features_300))));
}
if (chip->ram_size) {
@ -346,6 +395,40 @@ static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
pnv_dt_lpc(chip, fdt, 0, PNV9_LPCM_BASE(chip), PNV9_LPCM_SIZE);
}
/*
* Same as spapr pa_features_31 except pnv always enables CI largepages bit,
* always disables copy/paste.
*/
static const uint8_t pa_features_31[] = { 74, 0,
/* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: CILRG|fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
0xf6, 0x3f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
/* 6: DS207 */
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
/* 16: Vector */
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
/* 18: Vec. Scalar, 20: Vec. XOR */
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
/* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
/* 32: LE atomic, 34: EBB + ext EBB */
0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
/* 40: Radix MMU */
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
/* 42: PM, 44: PC RA, 46: SC vec'd */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
/* 48: SIMD, 50: QP BFP, 52: String */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
/* 54: DecFP, 56: DecI, 58: SHA */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
/* 60: NM atomic, 62: RNG */
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
/* 68: DEXCR[SBHE|IBRTPDUS|SRAPD|NPHIE|PHIE] */
0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 66 - 71 */
/* 72: [P]HASHST/[P]HASHCHK */
0x80, 0x00, /* 72 - 73 */
};
static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
{
static const char compat[] = "ibm,power10-xscom\0ibm,xscom";
@ -358,8 +441,12 @@ static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
for (i = 0; i < chip->nr_cores; i++) {
PnvCore *pnv_core = chip->cores[i];
int offset;
pnv_dt_core(chip, pnv_core, fdt);
offset = pnv_dt_core(chip, pnv_core, fdt);
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
pa_features_31, sizeof(pa_features_31))));
}
if (chip->ram_size) {
@ -995,9 +1082,10 @@ static void pnv_init(MachineState *machine)
* 25:28 Core number
* 29:31 Thread ID
*/
static uint32_t pnv_chip_core_pir_p8(PnvChip *chip, uint32_t core_id)
static uint32_t pnv_chip_pir_p8(PnvChip *chip, uint32_t core_id,
uint32_t thread_id)
{
return (chip->chip_id << 7) | (core_id << 3);
return (chip->chip_id << 7) | (core_id << 3) | thread_id;
}
static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu,
@ -1049,14 +1137,37 @@ static void pnv_chip_power8_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
*
* We only care about the lower bits. uint32_t is fine for the moment.
*/
static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
static uint32_t pnv_chip_pir_p9(PnvChip *chip, uint32_t core_id,
uint32_t thread_id)
{
return (chip->chip_id << 8) | (core_id << 2);
if (chip->nr_threads == 8) {
return (chip->chip_id << 8) | ((thread_id & 1) << 2) | (core_id << 3) |
(thread_id >> 1);
} else {
return (chip->chip_id << 8) | (core_id << 2) | thread_id;
}
}
static uint32_t pnv_chip_core_pir_p10(PnvChip *chip, uint32_t core_id)
/*
* 0:48 Reserved - Read as zeroes
* 49:52 Node ID
* 53:55 Chip ID
* 56 Reserved - Read as zero
* 57:59 Quad ID
* 60 Core Chiplet Pair ID
* 61:63 Thread/Core Chiplet ID t0-t2
*
* We only care about the lower bits. uint32_t is fine for the moment.
*/
static uint32_t pnv_chip_pir_p10(PnvChip *chip, uint32_t core_id,
uint32_t thread_id)
{
return (chip->chip_id << 8) | (core_id << 2);
if (chip->nr_threads == 8) {
return (chip->chip_id << 8) | ((core_id / 4) << 4) |
((core_id % 2) << 3) | thread_id;
} else {
return (chip->chip_id << 8) | (core_id << 2) | thread_id;
}
}
static void pnv_chip_power9_intc_create(PnvChip *chip, PowerPCCPU *cpu,
@ -1235,7 +1346,7 @@ static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
int core_hwid = CPU_CORE(pnv_core)->core_id;
for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
uint32_t pir = pcc->core_pir(chip, core_hwid) + j;
uint32_t pir = pcc->chip_pir(chip, core_hwid, j);
PnvICPState *icp = PNV_ICP(xics_icp_get(chip8->xics, pir));
memory_region_add_subregion(&chip8->icp_mmio, pir << 12,
@ -1348,7 +1459,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
k->chip_cfam_id = 0x221ef04980000000ull; /* P8 Murano DD2.1 */
k->cores_mask = POWER8E_CORE_MASK;
k->num_phbs = 3;
k->core_pir = pnv_chip_core_pir_p8;
k->chip_pir = pnv_chip_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->intc_reset = pnv_chip_power8_intc_reset;
k->intc_destroy = pnv_chip_power8_intc_destroy;
@ -1372,7 +1483,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
k->cores_mask = POWER8_CORE_MASK;
k->num_phbs = 3;
k->core_pir = pnv_chip_core_pir_p8;
k->chip_pir = pnv_chip_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->intc_reset = pnv_chip_power8_intc_reset;
k->intc_destroy = pnv_chip_power8_intc_destroy;
@ -1396,7 +1507,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
k->chip_cfam_id = 0x120d304980000000ull; /* P8 Naples DD1.0 */
k->cores_mask = POWER8_CORE_MASK;
k->num_phbs = 4;
k->core_pir = pnv_chip_core_pir_p8;
k->chip_pir = pnv_chip_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->intc_reset = pnv_chip_power8_intc_reset;
k->intc_destroy = pnv_chip_power8_intc_destroy;
@ -1669,7 +1780,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */
k->cores_mask = POWER9_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p9;
k->chip_pir = pnv_chip_pir_p9;
k->intc_create = pnv_chip_power9_intc_create;
k->intc_reset = pnv_chip_power9_intc_reset;
k->intc_destroy = pnv_chip_power9_intc_destroy;
@ -1981,7 +2092,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
k->chip_cfam_id = 0x120da04900008000ull; /* P10 DD1.0 (with NX) */
k->cores_mask = POWER10_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p10;
k->chip_pir = pnv_chip_pir_p10;
k->intc_create = pnv_chip_power10_intc_create;
k->intc_reset = pnv_chip_power10_intc_reset;
k->intc_destroy = pnv_chip_power10_intc_destroy;
@ -2071,8 +2182,8 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
chip->nr_threads, &error_fatal);
object_property_set_int(OBJECT(pnv_core), CPU_CORE_PROP_CORE_ID,
core_hwid, &error_fatal);
object_property_set_int(OBJECT(pnv_core), "pir",
pcc->core_pir(chip, core_hwid), &error_fatal);
object_property_set_int(OBJECT(pnv_core), "hwid", core_hwid,
&error_fatal);
object_property_set_int(OBJECT(pnv_core), "hrmor", pnv->fw_load_addr,
&error_fatal);
object_property_set_link(OBJECT(pnv_core), "chip", OBJECT(chip),

View file

@ -226,7 +226,7 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp,
int thread_index)
{
CPUPPCState *env = &cpu->env;
int core_pir;
int core_hwid;
ppc_spr_t *pir = &env->spr_cb[SPR_PIR];
ppc_spr_t *tir = &env->spr_cb[SPR_TIR];
Error *local_err = NULL;
@ -242,10 +242,10 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp,
return;
}
core_pir = object_property_get_uint(OBJECT(pc), "pir", &error_abort);
core_hwid = object_property_get_uint(OBJECT(pc), "hwid", &error_abort);
tir->default_value = thread_index;
pir->default_value = core_pir + thread_index;
pir->default_value = pcc->chip_pir(pc->chip, core_hwid, thread_index);
/* Set time-base frequency to 512 MHz */
cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ);
@ -342,7 +342,7 @@ static void pnv_core_unrealize(DeviceState *dev)
}
static Property pnv_core_properties[] = {
DEFINE_PROP_UINT32("pir", PnvCore, pir, 0),
DEFINE_PROP_UINT32("hwid", PnvCore, hwid, 0),
DEFINE_PROP_UINT64("hrmor", PnvCore, hrmor, 0),
DEFINE_PROP_LINK("chip", PnvCore, chip, TYPE_PNV_CHIP, PnvChip *),
DEFINE_PROP_END_OF_LIST(),

View file

@ -633,6 +633,16 @@ void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value)
((uint64_t)value << 32) | tb);
}
void cpu_ppc_increase_tb_by_offset(CPUPPCState *env, int64_t offset)
{
env->tb_env->tb_offset += offset;
}
void cpu_ppc_decrease_tb_by_offset(CPUPPCState *env, int64_t offset)
{
env->tb_env->tb_offset -= offset;
}
uint64_t cpu_ppc_load_vtb(CPUPPCState *env)
{
ppc_tb_t *tb_env = env->tb_env;

View file

@ -233,29 +233,40 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
PowerPCCPU *cpu,
void *fdt, int offset)
{
/*
* SSO (SAO) ordering is supported on KVM and thread=single hosts,
* but not MTTCG, so disable it. To advertise it, a cap would have
* to be added, or support implemented for MTTCG.
*
* Copy/paste is not supported by TCG, so it is not advertised. KVM
* can execute them but it has no accelerator drivers which are usable,
* so there isn't much need for it anyway.
*/
/* These should be kept in sync with pnv */
uint8_t pa_features_206[] = { 6, 0,
0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
0xf6, 0x1f, 0xc7, 0x00, 0x00, 0xc0 };
uint8_t pa_features_207[] = { 24, 0,
0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0,
0xf6, 0x1f, 0xc7, 0xc0, 0x00, 0xf0,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
uint8_t pa_features_300[] = { 66, 0,
/* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, SSO, 5: LE|CFAR|EB|LSQ */
0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, /* 0 - 5 */
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
0xf6, 0x1f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
/* 6: DS207 */
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
/* 16: Vector */
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
/* 18: Vec. Scalar, 20: Vec. XOR, 22: HTM */
/* 18: Vec. Scalar, 20: Vec. XOR */
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
/* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
/* 30: MMR, 32: LE atomic, 34: EBB + ext EBB */
0x80, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
/* 36: SPR SO, 38: Copy/Paste, 40: Radix MMU */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 36 - 41 */
/* 32: LE atomic, 34: EBB + ext EBB */
0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
/* 40: Radix MMU */
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
/* 42: PM, 44: PC RA, 46: SC vec'd */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
/* 48: SIMD, 50: QP BFP, 52: String */
@ -265,6 +276,36 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
/* 60: NM atomic, 62: RNG */
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
};
/* 3.1 removes SAO, HTM support */
uint8_t pa_features_31[] = { 74, 0,
/* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
0xf6, 0x1f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
/* 6: DS207 */
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
/* 16: Vector */
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
/* 18: Vec. Scalar, 20: Vec. XOR */
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
/* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
/* 32: LE atomic, 34: EBB + ext EBB */
0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
/* 40: Radix MMU */
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
/* 42: PM, 44: PC RA, 46: SC vec'd */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
/* 48: SIMD, 50: QP BFP, 52: String */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
/* 54: DecFP, 56: DecI, 58: SHA */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
/* 60: NM atomic, 62: RNG */
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
/* 68: DEXCR[SBHE|IBRTPDUS|SRAPD|NPHIE|PHIE] */
0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 66 - 71 */
/* 72: [P]HASHST/[P]HASHCHK */
0x80, 0x00, /* 72 - 73 */
};
uint8_t *pa_features = NULL;
size_t pa_size;
@ -280,6 +321,10 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
pa_features = pa_features_300;
pa_size = sizeof(pa_features_300);
}
if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_10, 0, cpu->compat_pvr)) {
pa_features = pa_features_31;
pa_size = sizeof(pa_features_31);
}
if (!pa_features) {
return;
}
@ -1362,7 +1407,6 @@ void spapr_init_all_lpcrs(target_ulong value, target_ulong mask)
}
}
static bool spapr_get_pate(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu,
target_ulong lpid, ppc_v3_pate_t *entry)
{
@ -1375,33 +1419,16 @@ static bool spapr_get_pate(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu,
/* Copy PATE1:GR into PATE0:HR */
entry->dw0 = spapr->patb_entry & PATE0_HR;
entry->dw1 = spapr->patb_entry;
return true;
} else {
uint64_t patb, pats;
assert(lpid != 0);
patb = spapr->nested_ptcr & PTCR_PATB;
pats = spapr->nested_ptcr & PTCR_PATS;
/* Check if partition table is properly aligned */
if (patb & MAKE_64BIT_MASK(0, pats + 12)) {
return false;
if (spapr_nested_api(spapr) == NESTED_API_KVM_HV) {
return spapr_get_pate_nested_hv(spapr, cpu, lpid, entry);
} else if (spapr_nested_api(spapr) == NESTED_API_PAPR) {
return spapr_get_pate_nested_papr(spapr, cpu, lpid, entry);
} else {
g_assert_not_reached();
}
/* Calculate number of entries */
pats = 1ull << (pats + 12 - 4);
if (pats <= lpid) {
return false;
}
/* Grab entry */
patb += 16 * lpid;
entry->dw0 = ldq_phys(CPU(cpu)->as, patb);
entry->dw1 = ldq_phys(CPU(cpu)->as, patb + 8);
}
return true;
}
#define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2))
@ -1689,6 +1716,7 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
pef_kvm_reset(machine->cgs, &error_fatal);
spapr_caps_apply(spapr);
spapr_nested_reset(spapr);
first_ppc_cpu = POWERPC_CPU(first_cpu);
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
@ -2138,6 +2166,7 @@ static const VMStateDescription vmstate_spapr = {
&vmstate_spapr_cap_fwnmi,
&vmstate_spapr_fwnmi,
&vmstate_spapr_cap_rpt_invalidate,
&vmstate_spapr_cap_nested_papr,
NULL
}
};
@ -4702,6 +4731,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_WORKAROUND;
smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */
smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
smc->default_caps.caps[SPAPR_CAP_NESTED_PAPR] = SPAPR_CAP_OFF;
smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_ON;

View file

@ -484,6 +484,50 @@ static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
error_append_hint(errp, "Try appending -machine cap-nested-hv=off "
"or use threads=1 with -smp\n");
}
if (spapr_nested_api(spapr) &&
spapr_nested_api(spapr) != NESTED_API_KVM_HV) {
error_setg(errp, "Nested-HV APIs are mutually exclusive");
error_append_hint(errp, "Please use either cap-nested-hv or "
"cap-nested-papr to proceed.\n");
return;
} else {
spapr->nested.api = NESTED_API_KVM_HV;
}
}
}
static void cap_nested_papr_apply(SpaprMachineState *spapr,
uint8_t val, Error **errp)
{
ERRP_GUARD();
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
CPUPPCState *env = &cpu->env;
if (!val) {
/* capability disabled by default */
return;
}
if (tcg_enabled()) {
if (!(env->insns_flags2 & PPC2_ISA300)) {
error_setg(errp, "Nested-PAPR only supported on POWER9 and later");
error_append_hint(errp,
"Try appending -machine cap-nested-papr=off\n");
return;
}
if (spapr_nested_api(spapr) &&
spapr_nested_api(spapr) != NESTED_API_PAPR) {
error_setg(errp, "Nested-HV APIs are mutually exclusive");
error_append_hint(errp, "Please use either cap-nested-hv or "
"cap-nested-papr to proceed.\n");
return;
} else {
spapr->nested.api = NESTED_API_PAPR;
}
} else if (kvm_enabled()) {
error_setg(errp, "KVM implementation does not support Nested-PAPR");
error_append_hint(errp,
"Try appending -machine cap-nested-papr=off\n");
}
}
@ -732,6 +776,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
.type = "bool",
.apply = cap_nested_kvm_hv_apply,
},
[SPAPR_CAP_NESTED_PAPR] = {
.name = "nested-papr",
.description = "Allow Nested HV (PAPR API)",
.index = SPAPR_CAP_NESTED_PAPR,
.get = spapr_cap_get_bool,
.set = spapr_cap_set_bool,
.type = "bool",
.apply = cap_nested_papr_apply,
},
[SPAPR_CAP_LARGE_DECREMENTER] = {
.name = "large-decr",
.description = "Allow Large Decrementer",
@ -916,6 +969,7 @@ SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC);
SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
SPAPR_CAP_MIG_STATE(hpt_maxpagesize, SPAPR_CAP_HPT_MAXPAGESIZE);
SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
SPAPR_CAP_MIG_STATE(nested_papr, SPAPR_CAP_NESTED_PAPR);
SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI);

View file

@ -39,9 +39,13 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
/*
* "PowerPC Processor binding to IEEE 1275" defines the initial MSR state
* as 32bit (MSR_SF=0) in "8.2.1. Initial Register Values".
* as 32bit (MSR_SF=0) with MSR_ME=1 and MSR_FP=1 in "8.2.1. Initial
* Register Values". This can also be found in "LoPAPR 1.1" "C.9.2.1
* Initial Register Values".
*/
env->msr &= ~(1ULL << MSR_SF);
env->msr |= (1ULL << MSR_ME) | (1ULL << MSR_FP);
env->spr[SPR_HIOR] = 0;
lpcr = env->spr[SPR_LPCR];
@ -394,10 +398,8 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power8e_v2.1"),
DEFINE_SPAPR_CPU_CORE_TYPE("power8nvl_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.2"),
DEFINE_SPAPR_CPU_CORE_TYPE("power10_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power10_v2.0"),
#ifdef CONFIG_KVM
DEFINE_SPAPR_CPU_CORE_TYPE("host"),

View file

@ -1525,6 +1525,28 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
*slot = fn;
}
void spapr_unregister_hypercall(target_ulong opcode)
{
spapr_hcall_fn *slot;
if (opcode <= MAX_HCALL_OPCODE) {
assert((opcode & 0x3) == 0);
slot = &papr_hypercall_table[opcode / 4];
} else if (opcode >= SVM_HCALL_BASE && opcode <= SVM_HCALL_MAX) {
/* we only have SVM-related hcall numbers assigned in multiples of 4 */
assert((opcode & 0x3) == 0);
slot = &svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4];
} else {
assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX));
slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];
}
*slot = NULL;
}
target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
target_ulong *args)
{
@ -1638,8 +1660,6 @@ static void hypercall_register_types(void)
spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support);
spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt);
spapr_register_nested();
}
type_init(hypercall_register_types)

File diff suppressed because it is too large Load diff