ppc patch queue for 2020-11-18

This fixes a regression that badly breaks some guest setups because
 IPIs end up misconfigured in the XIVE interrupt controller. Hopefully,
 the last fix for sPAPR. I'm sending this PR with the blessing of David
 who is currently on holidays.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEtIKLr5QxQM7yo0kQcdTV5YIvc9YFAl+09tcACgkQcdTV5YIv
 c9aW+xAAn0H219o6zfbJSkWnFcqq3vVLGhAva/QoQHzy2oeusbTgo968J4p9zwZb
 rS+jRo1uA+U6cuRo+1PPh+iMP+t8ZLlN9AQIqdqtIIeUxpKTGUKUpX7AvZcknpvN
 VNvcUsGJGIl/mOjHPXbP29PGi0hWv8+kvESoOOqGfxkv0bY8L1+PItEMK22+n3n2
 aaPiWtxsx6UtRoFpyj82bMM/Y5PsKlP0ZvrVChvF8VZZu0kWe8KWKsR7do2/RLAX
 tb5J4BN9gWPC2KERsrBWsGn0A4pE5n1NXnERH6BlwEBU/AhUM9d80N6280SSge0k
 noE2U1pVAva78NJzAWAiweP1ZGR3yt71MWP2i7ndCxcbFG9IQ7Su48nSmzwKfutT
 +SEuoP0fmTSRXmWiKkrOT+9ZdC4+Vpn0IvCGFHzoPTyNlhaOZRIoqhqxTlvrSYwx
 /DDwechCwPhidpZ+RYaQudX4yUtZIh+Y33LH879aDxkWW8HcaA98XSXXQ+iOiofu
 SY25HisfZjj1xHNuipjoGyMCdPZh4rdspaAGWzJVkOUjjFnzY9PeOxh7bYHz32eN
 xFr3f/1woPYHacqQE5lP2aWmyUvWHkvJsEW3yVix1j+luzn1UmXOwRm1P7tGC1o5
 gtMgQXR3ZodyLxO20slZjt/G77aFz3bpetWcHxoxaksPua3RZoc=
 =zUP3
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/gkurz/tags/ppc-for-5.2-20201118' into staging

ppc patch queue for 2020-11-18

This fixes a regression that badly breaks some guest setups because
IPIs end up misconfigured in the XIVE interrupt controller. Hopefully,
the last fix for sPAPR. I'm sending this PR with the blessing of David
who is currently on holidays.

# gpg: Signature made Wed 18 Nov 2020 10:26:31 GMT
# gpg:                using RSA key B4828BAF943140CEF2A3491071D4D5E5822F73D6
# gpg: Good signature from "Greg Kurz <groug@kaod.org>" [full]
# gpg:                 aka "Gregory Kurz <gregory.kurz@free.fr>" [full]
# gpg:                 aka "[jpeg image of size 3330]" [full]
# Primary key fingerprint: B482 8BAF 9431 40CE F2A3  4910 71D4 D5E5 822F 73D6

* remotes/gkurz/tags/ppc-for-5.2-20201118:
  Revert series "spapr/xive: Allocate vCPU IPIs from the vCPU contexts"

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-11-18 15:28:38 +00:00
commit 3d275bd17c

View File

@ -36,9 +36,10 @@ typedef struct KVMEnabledCPU {
static QLIST_HEAD(, KVMEnabledCPU)
kvm_enabled_cpus = QLIST_HEAD_INITIALIZER(&kvm_enabled_cpus);
static bool kvm_cpu_is_enabled(unsigned long vcpu_id)
static bool kvm_cpu_is_enabled(CPUState *cs)
{
KVMEnabledCPU *enabled_cpu;
unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
QLIST_FOREACH(enabled_cpu, &kvm_enabled_cpus, node) {
if (enabled_cpu->vcpu_id == vcpu_id) {
@ -146,45 +147,6 @@ int kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp)
return s.ret;
}
/*
* Allocate the vCPU IPIs from the vCPU context. This will allocate
* the XIVE IPI interrupt on the chip on which the vCPU is running.
* This gives a better distribution of IPIs when the guest has a lot
* of vCPUs. When the vCPUs are pinned, this will make the IPI local
* to the chip of the vCPU. It will reduce rerouting between interrupt
* controllers and gives better performance.
*/
typedef struct {
SpaprXive *xive;
Error *err;
int rc;
} XiveInitIPI;
static void kvmppc_xive_reset_ipi_on_cpu(CPUState *cs, run_on_cpu_data arg)
{
unsigned long ipi = kvm_arch_vcpu_id(cs);
XiveInitIPI *s = arg.host_ptr;
uint64_t state = 0;
s->rc = kvm_device_access(s->xive->fd, KVM_DEV_XIVE_GRP_SOURCE, ipi,
&state, true, &s->err);
}
static int kvmppc_xive_reset_ipi(SpaprXive *xive, CPUState *cs, Error **errp)
{
XiveInitIPI s = {
.xive = xive,
.err = NULL,
.rc = 0,
};
run_on_cpu(cs, kvmppc_xive_reset_ipi_on_cpu, RUN_ON_CPU_HOST_PTR(&s));
if (s.err) {
error_propagate(errp, s.err);
}
return s.rc;
}
int kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
{
ERRP_GUARD();
@ -195,7 +157,7 @@ int kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
assert(xive->fd != -1);
/* Check if CPU was hot unplugged and replugged. */
if (kvm_cpu_is_enabled(kvm_arch_vcpu_id(tctx->cs))) {
if (kvm_cpu_is_enabled(tctx->cs)) {
return 0;
}
@ -214,12 +176,6 @@ int kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
return ret;
}
/* Create/reset the vCPU IPI */
ret = kvmppc_xive_reset_ipi(xive, tctx->cs, errp);
if (ret < 0) {
return ret;
}
kvm_cpu_enable(tctx->cs);
return 0;
}
@ -279,12 +235,6 @@ int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
assert(xive->fd != -1);
/*
* The vCPU IPIs are now allocated in kvmppc_xive_cpu_connect()
* and not with all sources in kvmppc_xive_source_reset()
*/
assert(srcno >= SPAPR_XIRQ_BASE);
if (xive_source_irq_is_lsi(xsrc, srcno)) {
state |= KVM_XIVE_LEVEL_SENSITIVE;
if (xsrc->status[srcno] & XIVE_STATUS_ASSERTED) {
@ -296,28 +246,12 @@ int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
true, errp);
}
/*
* To be valid, a source must have been claimed by the machine (valid
* entry in the EAS table) and if it is a vCPU IPI, the vCPU should
* have been enabled, which means the IPI has been allocated in
* kvmppc_xive_cpu_connect().
*/
static bool xive_source_is_valid(SpaprXive *xive, int i)
{
return xive_eas_is_valid(&xive->eat[i]) &&
(i >= SPAPR_XIRQ_BASE || kvm_cpu_is_enabled(i));
}
static int kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp)
{
SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
int i;
/*
* Skip the vCPU IPIs. These are created/reset when the vCPUs are
* connected in kvmppc_xive_cpu_connect()
*/
for (i = SPAPR_XIRQ_BASE; i < xsrc->nr_irqs; i++) {
for (i = 0; i < xsrc->nr_irqs; i++) {
int ret;
if (!xive_eas_is_valid(&xive->eat[i])) {
@ -399,7 +333,7 @@ static void kvmppc_xive_source_get_state(XiveSource *xsrc)
for (i = 0; i < xsrc->nr_irqs; i++) {
uint8_t pq;
if (!xive_source_is_valid(xive, i)) {
if (!xive_eas_is_valid(&xive->eat[i])) {
continue;
}
@ -582,7 +516,7 @@ static void kvmppc_xive_change_state_handler(void *opaque, int running,
uint8_t pq;
uint8_t old_pq;
if (!xive_source_is_valid(xive, i)) {
if (!xive_eas_is_valid(&xive->eat[i])) {
continue;
}
@ -610,7 +544,7 @@ static void kvmppc_xive_change_state_handler(void *opaque, int running,
for (i = 0; i < xsrc->nr_irqs; i++) {
uint8_t pq;
if (!xive_source_is_valid(xive, i)) {
if (!xive_eas_is_valid(&xive->eat[i])) {
continue;
}
@ -713,22 +647,22 @@ int kvmppc_xive_post_load(SpaprXive *xive, int version_id)
}
}
/*
* We can only restore the source config if the source has been
* previously set in KVM. Since we don't do that at reset time
* when restoring a VM, let's do it now.
*/
ret = kvmppc_xive_source_reset(&xive->source, &local_err);
if (ret < 0) {
goto fail;
}
/* Restore the EAT */
for (i = 0; i < xive->nr_irqs; i++) {
if (!xive_source_is_valid(xive, i)) {
if (!xive_eas_is_valid(&xive->eat[i])) {
continue;
}
/*
* We can only restore the source config if the source has been
* previously set in KVM. Since we don't do that for all interrupts
* at reset time anymore, let's do it now.
*/
ret = kvmppc_xive_source_reset_one(&xive->source, i, &local_err);
if (ret < 0) {
goto fail;
}
ret = kvmppc_xive_set_source_config(xive, i, &xive->eat[i], &local_err);
if (ret < 0) {
goto fail;