Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge tag 'pull-ppc-20230626' of https://github.com/legoater/qemu int…
…o staging

ppc queue:

* New maintainers
* Nested implementation cleanups
* Various cleanups of the CPU implementation
* SMT support for pseries
* Improvements of the XIVE2 TIMA modeling
* Extra avocado tests for pseries

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmSZKF8ACgkQUaNDx8/7
# 7KGSiBAAlHC4S9J5ujzTIojaWY72d2ZinkC+WpBus9Wr91DqaUSUd/JbzDxQCvXh
# dBWEbcyQ+abb8M3OQ3fMq9TfD2/LhxxXb+uwHIJ+ylITBnsRVCQv/4/gi3EkpRid
# h4q3wYH8OYNfCQd/cWYXNgCSNj1nS9sRrEKFXaB0JeQWHzHxriJS/SoIhilqvUru
# LFEytWNb3bxRkEkt8oAetOa9+DNLowUQ9IdzswqGcib09po3b1k4+ThfcvzU9nAc
# ek31/h1W6cJbOJcgRO2dhWUZYp7cfmcnOa02E84tGFvvY/kYbjzPZZnoniSXD4uf
# YWFCoB3VxUoZ/YKCT/pDKHVdXmLLrfckNbo9vQNEcwmjr8m0Q3d1ewD5O9oNRpgN
# H0QMENfsdojztosOm3KPQ20aqNf1R7rQegYTiWf3B2fKZ6PIqnn3tBPxaEDkH7NC
# GTAKnBhF48lcHSF/4XOfGdmqhGgPRWX/Tv0wia7RY/A4NEfiIImIu+nYSGNBbu3y
# 7xlmtcumTlsRityOZnYI3bN5ubv++XPwU5NIJPACqvAbhif2rf1vQ9rMkkK785GL
# ciJ/5f6zXsLU7DfWP+qbTBizchQgigXnRZEEc7Seo6Bwtru22oxug0qQZ5QCgyXl
# Fg5Xuoq/6T4JC75pvxh1BjVlZc3Okzbfmsj+aZNrXO581HVJ2JI=
# =XLtJ
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 26 Jun 2023 07:55:43 AM CEST
# gpg:                using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1
# gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined]
# 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: A0F6 6548 F048 95EB FE6B  0B60 51A3 43C7 CFFB ECA1

* tag 'pull-ppc-20230626' of https://github.com/legoater/qemu: (30 commits)
  tests/avocado: ppc test VOF bios Linux boot
  pnv/xive2: Check TIMA special ops against a dedicated array for P10
  pnv/xive2: Add a get_config() method on the presenter class
  tests/avocado: Add ppc64 pseries multiprocessor boot tests
  tests/avocado: boot ppc64 pseries to Linux VFS mount
  spapr: TCG allow up to 8-thread SMT on POWER8 and newer CPUs
  hw/ppc/spapr: Test whether TCG is enabled with tcg_enabled()
  target/ppc: Add msgsnd/p and DPDES SMT support
  target/ppc: Add support for SMT CTRL register
  target/ppc: Add initial flags and helpers for SMT support
  target/ppc: Fix sc instruction handling of LEV field
  target/ppc: Better CTRL SPR implementation
  target/ppc: Add ISA v3.1 LEV indication in SRR1 for system call interrupts
  target/ppc: Implement HEIR SPR
  target/ppc: Add SRR1 prefix indication to interrupt handlers
  target/ppc: Change partition-scope translate interface
  target/ppc: Fix instruction loading endianness in alignment interrupt
  ppc/spapr: Move spapr nested HV to a new file
  ppc/spapr: load and store l2 state with helper functions
  ppc/spapr: Add a nested state struct
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Jun 26, 2023
2 parents 79dbd91 + 5eb63b8 commit f9925ab
Show file tree
Hide file tree
Showing 31 changed files with 1,085 additions and 518 deletions.
4 changes: 4 additions & 0 deletions MAINTAINERS
Expand Up @@ -302,6 +302,7 @@ M: Daniel Henrique Barboza <danielhb413@gmail.com>
R: Cédric Le Goater <clg@kaod.org>
R: David Gibson <david@gibson.dropbear.id.au>
R: Greg Kurz <groug@kaod.org>
R: Nicholas Piggin <npiggin@gmail.com>
L: qemu-ppc@nongnu.org
S: Odd Fixes
F: target/ppc/
Expand Down Expand Up @@ -1451,6 +1452,8 @@ F: tests/avocado/ppc_pseries.py

PowerNV (Non-Virtualized)
M: Cédric Le Goater <clg@kaod.org>
R: Frédéric Barrat <fbarrat@linux.ibm.com>
R: Nicholas Piggin <npiggin@gmail.com>
L: qemu-ppc@nongnu.org
S: Odd Fixes
F: docs/system/ppc/powernv.rst
Expand Down Expand Up @@ -2445,6 +2448,7 @@ T: git https://github.com/philmd/qemu.git fw_cfg-next

XIVE
M: Cédric Le Goater <clg@kaod.org>
R: Frédéric Barrat <fbarrat@linux.ibm.com>
L: qemu-ppc@nongnu.org
S: Odd Fixes
F: hw/*/*xive*
Expand Down
11 changes: 11 additions & 0 deletions hw/intc/pnv_xive.c
Expand Up @@ -479,6 +479,16 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
return count;
}

static uint32_t pnv_xive_presenter_get_config(XivePresenter *xptr)
{
uint32_t cfg = 0;

/* TIMA GEN1 is all P9 knows */
cfg |= XIVE_PRESENTER_GEN1_TIMA_OS;

return cfg;
}

static uint8_t pnv_xive_get_block_id(XiveRouter *xrtr)
{
return pnv_xive_block_id(PNV_XIVE(xrtr));
Expand Down Expand Up @@ -1991,6 +2001,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)

xnc->notify = pnv_xive_notify;
xpc->match_nvt = pnv_xive_match_nvt;
xpc->get_config = pnv_xive_presenter_get_config;
};

static const TypeInfo pnv_xive_info = {
Expand Down
44 changes: 12 additions & 32 deletions hw/intc/pnv_xive2.c
Expand Up @@ -501,6 +501,17 @@ static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format,
return count;
}

static uint32_t pnv_xive2_presenter_get_config(XivePresenter *xptr)
{
PnvXive2 *xive = PNV_XIVE2(xptr);
uint32_t cfg = 0;

if (xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS) {
cfg |= XIVE_PRESENTER_GEN1_TIMA_OS;
}
return cfg;
}

static uint8_t pnv_xive2_get_block_id(Xive2Router *xrtr)
{
return pnv_xive2_block_id(PNV_XIVE2(xrtr));
Expand Down Expand Up @@ -1645,36 +1656,14 @@ static const MemoryRegionOps pnv_xive2_ic_tm_indirect_ops = {
/*
* TIMA ops
*/

/*
* Special TIMA offsets to handle accesses in a POWER10 way.
*
* Only the CAM line updates done by the hypervisor should be handled
* specifically.
*/
#define HV_PAGE_OFFSET (XIVE_TM_HV_PAGE << TM_SHIFT)
#define HV_PUSH_OS_CTX_OFFSET (HV_PAGE_OFFSET | (TM_QW1_OS + TM_WORD2))
#define HV_PULL_OS_CTX_OFFSET (HV_PAGE_OFFSET | TM_SPC_PULL_OS_CTX)

static void pnv_xive2_tm_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
PnvXive2 *xive = pnv_xive2_tm_get_xive(cpu);
XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
XivePresenter *xptr = XIVE_PRESENTER(xive);
bool gen1_tima_os =
xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;

offset &= TM_ADDRESS_MASK;

/* TODO: should we switch the TM ops table instead ? */
if (!gen1_tima_os && offset == HV_PUSH_OS_CTX_OFFSET) {
xive2_tm_push_os_ctx(xptr, tctx, offset, value, size);
return;
}

/* Other TM ops are the same as XIVE1 */
xive_tctx_tm_write(xptr, tctx, offset, value, size);
}

Expand All @@ -1684,17 +1673,7 @@ static uint64_t pnv_xive2_tm_read(void *opaque, hwaddr offset, unsigned size)
PnvXive2 *xive = pnv_xive2_tm_get_xive(cpu);
XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
XivePresenter *xptr = XIVE_PRESENTER(xive);
bool gen1_tima_os =
xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;

offset &= TM_ADDRESS_MASK;

/* TODO: should we switch the TM ops table instead ? */
if (!gen1_tima_os && offset == HV_PULL_OS_CTX_OFFSET) {
return xive2_tm_pull_os_ctx(xptr, tctx, offset, size);
}

/* Other TM ops are the same as XIVE1 */
return xive_tctx_tm_read(xptr, tctx, offset, size);
}

Expand Down Expand Up @@ -1987,6 +1966,7 @@ static void pnv_xive2_class_init(ObjectClass *klass, void *data)
xnc->notify = pnv_xive2_notify;

xpc->match_nvt = pnv_xive2_match_nvt;
xpc->get_config = pnv_xive2_presenter_get_config;
};

static const TypeInfo pnv_xive2_info = {
Expand Down
16 changes: 16 additions & 0 deletions hw/intc/spapr_xive.c
Expand Up @@ -475,6 +475,21 @@ static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
return count;
}

static uint32_t spapr_xive_presenter_get_config(XivePresenter *xptr)
{
uint32_t cfg = 0;

/*
* Let's claim GEN1 TIMA format. If running with KVM on P10, the
* correct answer is deep in the hardware and not accessible to
* us. But it shouldn't matter as it only affects the presenter
* as seen by a guest OS.
*/
cfg |= XIVE_PRESENTER_GEN1_TIMA_OS;

return cfg;
}

static uint8_t spapr_xive_get_block_id(XiveRouter *xrtr)
{
return SPAPR_XIVE_BLOCK_ID;
Expand Down Expand Up @@ -832,6 +847,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
sicc->post_load = spapr_xive_post_load;

xpc->match_nvt = spapr_xive_match_nvt;
xpc->get_config = spapr_xive_presenter_get_config;
xpc->in_kernel = spapr_xive_in_kernel_xptr;
}

Expand Down
57 changes: 49 additions & 8 deletions hw/intc/xive.c
Expand Up @@ -20,6 +20,7 @@
#include "monitor/monitor.h"
#include "hw/irq.h"
#include "hw/ppc/xive.h"
#include "hw/ppc/xive2.h"
#include "hw/ppc/xive_regs.h"
#include "trace.h"

Expand Down Expand Up @@ -461,6 +462,13 @@ static void xive_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
}
}

static uint32_t xive_presenter_get_config(XivePresenter *xptr)
{
XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);

return xpc->get_config(xptr);
}

/*
* Define a mapping of "special" operations depending on the TIMA page
* offset and the size of the operation.
Expand Down Expand Up @@ -497,14 +505,47 @@ static const XiveTmOp xive_tm_operations[] = {
{ XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 8, NULL, xive_tm_pull_pool_ctx },
};

static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool write)
static const XiveTmOp xive2_tm_operations[] = {
/*
* MMIOs below 2K : raw values and special operations without side
* effects
*/
{ XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR, 1, xive_tm_set_os_cppr, NULL },
{ XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2, 4, xive2_tm_push_os_ctx, NULL },
{ XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, NULL },
{ XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL },
{ XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll },

/* MMIOs above 2K : special operations with side effects */
{ XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG, 2, NULL, xive_tm_ack_os_reg },
{ XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, NULL },
{ XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX, 4, NULL, xive2_tm_pull_os_ctx },
{ XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX, 8, NULL, xive2_tm_pull_os_ctx },
{ XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG, 2, NULL, xive_tm_ack_hv_reg },
{ XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 4, NULL, xive_tm_pull_pool_ctx },
{ XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 8, NULL, xive_tm_pull_pool_ctx },
};

static const XiveTmOp *xive_tm_find_op(XivePresenter *xptr, hwaddr offset,
unsigned size, bool write)
{
uint8_t page_offset = (offset >> TM_SHIFT) & 0x3;
uint32_t op_offset = offset & TM_ADDRESS_MASK;
int i;
const XiveTmOp *tm_ops;
int i, tm_ops_count;
uint32_t cfg;

cfg = xive_presenter_get_config(xptr);
if (cfg & XIVE_PRESENTER_GEN1_TIMA_OS) {
tm_ops = xive_tm_operations;
tm_ops_count = ARRAY_SIZE(xive_tm_operations);
} else {
tm_ops = xive2_tm_operations;
tm_ops_count = ARRAY_SIZE(xive2_tm_operations);
}

for (i = 0; i < ARRAY_SIZE(xive_tm_operations); i++) {
const XiveTmOp *xto = &xive_tm_operations[i];
for (i = 0; i < tm_ops_count; i++) {
const XiveTmOp *xto = &tm_ops[i];

/* Accesses done from a more privileged TIMA page is allowed */
if (xto->page_offset >= page_offset &&
Expand Down Expand Up @@ -535,7 +576,7 @@ void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
* First, check for special operations in the 2K region
*/
if (offset & TM_SPECIAL_OP) {
xto = xive_tm_find_op(offset, size, true);
xto = xive_tm_find_op(tctx->xptr, offset, size, true);
if (!xto) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA "
"@%"HWADDR_PRIx"\n", offset);
Expand All @@ -548,7 +589,7 @@ void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
/*
* Then, for special operations in the region below 2K.
*/
xto = xive_tm_find_op(offset, size, true);
xto = xive_tm_find_op(tctx->xptr, offset, size, true);
if (xto) {
xto->write_handler(xptr, tctx, offset, value, size);
return;
Expand All @@ -574,7 +615,7 @@ uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
* First, check for special operations in the 2K region
*/
if (offset & TM_SPECIAL_OP) {
xto = xive_tm_find_op(offset, size, false);
xto = xive_tm_find_op(tctx->xptr, offset, size, false);
if (!xto) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid read access to TIMA"
"@%"HWADDR_PRIx"\n", offset);
Expand All @@ -587,7 +628,7 @@ uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
/*
* Then, for special operations in the region below 2K.
*/
xto = xive_tm_find_op(offset, size, false);
xto = xive_tm_find_op(tctx->xptr, offset, size, false);
if (xto) {
ret = xto->read_handler(xptr, tctx, offset, size);
goto out;
Expand Down
14 changes: 7 additions & 7 deletions hw/pci-host/pnv_phb4.c
Expand Up @@ -133,13 +133,13 @@ static void pnv_phb4_rc_config_write(PnvPHB4 *phb, unsigned off,
PCIDevice *pdev;

if (size != 4) {
phb_error(phb, "rc_config_write invalid size %d\n", size);
phb_error(phb, "rc_config_write invalid size %d", size);
return;
}

pdev = pci_find_device(pci->bus, 0, 0);
if (!pdev) {
phb_error(phb, "rc_config_write device not found\n");
phb_error(phb, "rc_config_write device not found");
return;
}

Expand All @@ -155,13 +155,13 @@ static uint64_t pnv_phb4_rc_config_read(PnvPHB4 *phb, unsigned off,
uint64_t val;

if (size != 4) {
phb_error(phb, "rc_config_read invalid size %d\n", size);
phb_error(phb, "rc_config_read invalid size %d", size);
return ~0ull;
}

pdev = pci_find_device(pci->bus, 0, 0);
if (!pdev) {
phb_error(phb, "rc_config_read device not found\n");
phb_error(phb, "rc_config_read device not found");
return ~0ull;
}

Expand Down Expand Up @@ -1039,19 +1039,19 @@ static void pnv_pec_stk_nest_xscom_write(void *opaque, hwaddr addr,
if (phb->nest_regs[PEC_NEST_STK_BAR_EN] &
(PEC_NEST_STK_BAR_EN_MMIO0 |
PEC_NEST_STK_BAR_EN_MMIO1)) {
phb_pec_error(pec, "Changing enabled BAR unsupported\n");
phb_pec_error(pec, "Changing enabled BAR unsupported");
}
phb->nest_regs[reg] = val & 0xffffffffff000000ull;
break;
case PEC_NEST_STK_PHB_REGS_BAR:
if (phb->nest_regs[PEC_NEST_STK_BAR_EN] & PEC_NEST_STK_BAR_EN_PHB) {
phb_pec_error(pec, "Changing enabled BAR unsupported\n");
phb_pec_error(pec, "Changing enabled BAR unsupported");
}
phb->nest_regs[reg] = val & 0xffffffffffc00000ull;
break;
case PEC_NEST_STK_INT_BAR:
if (phb->nest_regs[PEC_NEST_STK_BAR_EN] & PEC_NEST_STK_BAR_EN_INT) {
phb_pec_error(pec, "Changing enabled BAR unsupported\n");
phb_pec_error(pec, "Changing enabled BAR unsupported");
}
phb->nest_regs[reg] = val & 0xfffffff000000000ull;
break;
Expand Down
1 change: 1 addition & 0 deletions hw/ppc/meson.build
Expand Up @@ -15,6 +15,7 @@ ppc_ss.add(when: 'CONFIG_PSERIES', if_true: files(
'spapr_vio.c',
'spapr_events.c',
'spapr_hcall.c',
'spapr_nested.c',
'spapr_iommu.c',
'spapr_rtas.c',
'spapr_pci.c',
Expand Down
3 changes: 2 additions & 1 deletion hw/ppc/pnv.c
Expand Up @@ -799,7 +799,8 @@ static void pnv_init(MachineState *machine)
DeviceState *dev;

if (kvm_enabled()) {
error_report("The powernv machine does not work with KVM acceleration");
error_report("machine %s does not support the KVM accelerator",
mc->name);
exit(EXIT_FAILURE);
}

Expand Down
6 changes: 6 additions & 0 deletions hw/ppc/ppc.c
Expand Up @@ -1436,6 +1436,12 @@ int ppc_cpu_pir(PowerPCCPU *cpu)
return env->spr_cb[SPR_PIR].default_value;
}

int ppc_cpu_tir(PowerPCCPU *cpu)
{
CPUPPCState *env = &cpu->env;
return env->spr_cb[SPR_TIR].default_value;
}

PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
{
CPUState *cs;
Expand Down
17 changes: 6 additions & 11 deletions hw/ppc/ppc440_bamboo.c
Expand Up @@ -19,7 +19,6 @@
#include "hw/pci/pci.h"
#include "hw/boards.h"
#include "sysemu/kvm.h"
#include "kvm_ppc.h"
#include "sysemu/device_tree.h"
#include "hw/loader.h"
#include "elf.h"
Expand Down Expand Up @@ -97,16 +96,6 @@ static int bamboo_load_device_tree(MachineState *machine,
fprintf(stderr, "couldn't set /chosen/bootargs\n");
}

/*
* Copy data from the host device tree into the guest. Since the guest can
* directly access the timebase without host involvement, we must expose
* the correct frequencies.
*/
if (kvm_enabled()) {
tb_freq = kvmppc_get_tbfreq();
clock_freq = kvmppc_get_clockfreq();
}

qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
clock_freq);
qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
Expand Down Expand Up @@ -175,6 +164,12 @@ static void bamboo_init(MachineState *machine)
int success;
int i;

if (kvm_enabled()) {
error_report("machine %s does not support the KVM accelerator",
MACHINE_GET_CLASS(machine)->name);
exit(EXIT_FAILURE);
}

cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
env = &cpu->env;

Expand Down

0 comments on commit f9925ab

Please sign in to comment.