ppc patch queue for 2019-11-26

Here's the first 4.2 hard freeze pull request from me.  This has:
 
   * A fix for some testcases that cause errors on older host kernels
     (e.g. RHEL7), with our new default configuration of VSMT mode
   * Changes to make VFIO devices interact properly with change of irq
     chip caused by PAPR feature negotiation.  This is more involved
     than I would like, but it's a problem in real use cases and I
     can't see an easier way to handle it.
   * Fix an error with ms6522 counters for the g3beige machine
   * Fix a coverity warning
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEdfRlhq5hpmzETofcbDjKyiDZs5IFAl3cvZAACgkQbDjKyiDZ
 s5LzYA/+KUmXnvvaVfRMLqYZuBVLxUN7+b472mYxrZY8neQ4yO9JYcFRb1FWlZKo
 zqUjBXljARPJZoT4pGhobqgR6hs/nbn6WaN0oI0ZrxHKMUsPe56c90PbvprtiGMe
 qGCoSuWQHccwouSZFmMcOUqO8rT+wlwMV+if/WbwNvhm4oCvA9Lcx2bBNllLN8XB
 bIdiZACsk+XHJDm5SDNr/Wyhz/N8tODStuKPYtyoHd5LarXVUymqljaNJhEIcqQZ
 awFP200fX6fKR+jRUV7AnG5faF2p1P6K2khwMYQF0QzpEQg4d9hKBs7SsSkzY3YD
 8nVeXGi6201kw9V5tqzqiG0mNcCME8Pb3K4fsmOfLSWbnOax8yv9tisz8+FYuful
 KxUBjp9cE/Tla+Zg1SeQ8VZrHJhcX98aT57CWQCtuYX+82krHQCKMSRpbEJ6ECRJ
 dChfXrAqmtG0mPd7sypeQPuJRBMOwuJsuJr6a0glDY61XmXCJbH5R6Jf+iDQ2Nf8
 owx07xNQ5fVO0RYDqr+eZSTfllW1P2FNI8sz0XFp6/dAz3KbLuNbzREFZcdEV1Gp
 CdJd9UA1P45c/BOOQy7FAeewKhuhgBE1S7m5brX9t1CorUW2zaM/hLwd3ZII0UyE
 if8hYpfeTY+lhNpu0hCpyzecZOMBabLAmQqIUUKO/wkydcIKYUg=
 =GHGC
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.2-20191126' into staging

ppc patch queue for 2019-11-26

Here's the first 4.2 hard freeze pull request from me.  This has:

  * A fix for some testcases that cause errors on older host kernels
    (e.g. RHEL7), with our new default configuration of VSMT mode
  * Changes to make VFIO devices interact properly with change of irq
    chip caused by PAPR feature negotiation.  This is more involved
    than I would like, but it's a problem in real use cases and I
    can't see an easier way to handle it.
  * Fix an error with ms6522 counters for the g3beige machine
  * Fix a coverity warning

# gpg: Signature made Tue 26 Nov 2019 05:52:16 GMT
# gpg:                using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full]
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full]
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full]
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown]
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-4.2-20191126:
  ppc/spapr_events: fix potential NULL pointer dereference in rtas_event_log_dequeue
  mos6522: update counters when timer interrupts are off
  spapr: Work around spurious warnings from vfio INTx initialization
  spapr: Handle irq backend changes with VFIO PCI devices
  vfio/pci: Respond to KVM irqchip change notifier
  vfio/pci: Split vfio_intx_update()
  kvm: Introduce KVM irqchip change notifier
  pseries: fix migration-test and pxe-test

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-11-26 16:48:48 +00:00
commit a0aaca7e9c
10 changed files with 105 additions and 31 deletions

View File

@ -149,6 +149,9 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = {
KVM_CAP_LAST_INFO
};
static NotifierList kvm_irqchip_change_notifiers =
NOTIFIER_LIST_INITIALIZER(kvm_irqchip_change_notifiers);
#define kvm_slots_lock(kml) qemu_mutex_lock(&(kml)->slots_lock)
#define kvm_slots_unlock(kml) qemu_mutex_unlock(&(kml)->slots_lock)
@ -1396,6 +1399,21 @@ void kvm_irqchip_release_virq(KVMState *s, int virq)
trace_kvm_irqchip_release_virq(virq);
}
void kvm_irqchip_add_change_notifier(Notifier *n)
{
notifier_list_add(&kvm_irqchip_change_notifiers, n);
}
void kvm_irqchip_remove_change_notifier(Notifier *n)
{
notifier_remove(n);
}
void kvm_irqchip_change_notify(void)
{
notifier_list_notify(&kvm_irqchip_change_notifiers, NULL);
}
static unsigned int kvm_hash_msi(uint32_t data)
{
/* This is optimized for IA32 MSI layout. However, no other arch shall

View File

@ -138,6 +138,18 @@ void kvm_irqchip_commit_routes(KVMState *s)
{
}
void kvm_irqchip_add_change_notifier(Notifier *n)
{
}
void kvm_irqchip_remove_change_notifier(Notifier *n)
{
}
void kvm_irqchip_change_notify(void)
{
}
int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter)
{
return -ENOSYS;

View File

@ -113,6 +113,10 @@ static int64_t get_next_irq_time(MOS6522State *s, MOS6522Timer *ti,
int64_t d, next_time;
unsigned int counter;
if (ti->frequency == 0) {
return INT64_MAX;
}
/* current counter value */
d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - ti->load_time,
ti->frequency, NANOSECONDS_PER_SECOND);
@ -149,10 +153,10 @@ static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti,
if (!ti->timer) {
return;
}
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
if ((s->ier & T1_INT) == 0 || (s->acr & T1MODE) != T1MODE_CONT) {
timer_del(ti->timer);
} else {
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
timer_mod(ti->timer, ti->next_irq_time);
}
}
@ -163,10 +167,10 @@ static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti,
if (!ti->timer) {
return;
}
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
if ((s->ier & T2_INT) == 0) {
timer_del(ti->timer);
} else {
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
timer_mod(ti->timer, ti->next_irq_time);
}
}

View File

@ -358,6 +358,7 @@ static SpaprEventLogEntry *rtas_event_log_dequeue(SpaprMachineState *spapr,
rtas_event_log_to_source(spapr,
spapr_event_log_entry_type(entry));
g_assert(source);
if (source->mask & event_mask) {
break;
}

View File

@ -373,6 +373,14 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
smc->nr_xirqs + SPAPR_XIRQ_BASE);
/*
* Mostly we don't actually need this until reset, except that not
* having this set up can cause VFIO devices to issue a
* false-positive warning during realize(), because they don't yet
* have an in-kernel irq chip.
*/
spapr_irq_update_active_intc(spapr);
}
int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
@ -508,6 +516,12 @@ static void set_active_intc(SpaprMachineState *spapr,
}
spapr->active_intc = new_intc;
/*
* We've changed the kernel irqchip, let VFIO devices know they
* need to readjust.
*/
kvm_irqchip_change_notify();
}
void spapr_irq_update_active_intc(SpaprMachineState *spapr)
@ -522,7 +536,8 @@ void spapr_irq_update_active_intc(SpaprMachineState *spapr)
* this.
*/
new_intc = SPAPR_INTC(spapr->xive);
} else if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
} else if (spapr->ov5_cas
&& spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
new_intc = SPAPR_INTC(spapr->xive);
} else {
new_intc = SPAPR_INTC(spapr->ics);

View File

@ -216,30 +216,18 @@ static void vfio_intx_disable_kvm(VFIOPCIDevice *vdev)
#endif
}
static void vfio_intx_update(PCIDevice *pdev)
static void vfio_intx_update(VFIOPCIDevice *vdev, PCIINTxRoute *route)
{
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
PCIINTxRoute route;
Error *err = NULL;
if (vdev->interrupt != VFIO_INT_INTx) {
return;
}
route = pci_device_route_intx_to_irq(&vdev->pdev, vdev->intx.pin);
if (!pci_intx_route_changed(&vdev->intx.route, &route)) {
return; /* Nothing changed */
}
trace_vfio_intx_update(vdev->vbasedev.name,
vdev->intx.route.irq, route.irq);
vdev->intx.route.irq, route->irq);
vfio_intx_disable_kvm(vdev);
vdev->intx.route = route;
vdev->intx.route = *route;
if (route.mode != PCI_INTX_ENABLED) {
if (route->mode != PCI_INTX_ENABLED) {
return;
}
@ -252,6 +240,30 @@ static void vfio_intx_update(PCIDevice *pdev)
vfio_intx_eoi(&vdev->vbasedev);
}
static void vfio_intx_routing_notifier(PCIDevice *pdev)
{
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
PCIINTxRoute route;
if (vdev->interrupt != VFIO_INT_INTx) {
return;
}
route = pci_device_route_intx_to_irq(&vdev->pdev, vdev->intx.pin);
if (pci_intx_route_changed(&vdev->intx.route, &route)) {
vfio_intx_update(vdev, &route);
}
}
static void vfio_irqchip_change(Notifier *notify, void *data)
{
VFIOPCIDevice *vdev = container_of(notify, VFIOPCIDevice,
irqchip_change_notifier);
vfio_intx_update(vdev, &vdev->intx.route);
}
static int vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp)
{
uint8_t pin = vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1);
@ -2967,31 +2979,34 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
if (vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1)) {
vdev->intx.mmap_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
vfio_intx_mmap_enable, vdev);
pci_device_set_intx_routing_notifier(&vdev->pdev, vfio_intx_update);
pci_device_set_intx_routing_notifier(&vdev->pdev,
vfio_intx_routing_notifier);
vdev->irqchip_change_notifier.notify = vfio_irqchip_change;
kvm_irqchip_add_change_notifier(&vdev->irqchip_change_notifier);
ret = vfio_intx_enable(vdev, errp);
if (ret) {
goto out_teardown;
goto out_deregister;
}
}
if (vdev->display != ON_OFF_AUTO_OFF) {
ret = vfio_display_probe(vdev, errp);
if (ret) {
goto out_teardown;
goto out_deregister;
}
}
if (vdev->enable_ramfb && vdev->dpy == NULL) {
error_setg(errp, "ramfb=on requires display=on");
goto out_teardown;
goto out_deregister;
}
if (vdev->display_xres || vdev->display_yres) {
if (vdev->dpy == NULL) {
error_setg(errp, "xres and yres properties require display=on");
goto out_teardown;
goto out_deregister;
}
if (vdev->dpy->edid_regs == NULL) {
error_setg(errp, "xres and yres properties need edid support");
goto out_teardown;
goto out_deregister;
}
}
@ -3015,8 +3030,10 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
return;
out_teardown:
out_deregister:
pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier);
out_teardown:
vfio_teardown_msi(vdev);
vfio_bars_exit(vdev);
error:
@ -3059,6 +3076,7 @@ static void vfio_exitfn(PCIDevice *pdev)
vfio_unregister_req_notifier(vdev);
vfio_unregister_err_notifier(vdev);
pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier);
vfio_disable_interrupts(vdev);
if (vdev->intx.mmap_timer) {
timer_free(vdev->intx.mmap_timer);

View File

@ -169,6 +169,7 @@ typedef struct VFIOPCIDevice {
bool enable_ramfb;
VFIODisplay *dpy;
Error *migration_blocker;
Notifier irqchip_change_notifier;
} VFIOPCIDevice;
uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len);

View File

@ -201,6 +201,7 @@ typedef struct KVMCapabilityInfo {
struct KVMState;
typedef struct KVMState KVMState;
extern KVMState *kvm_state;
typedef struct Notifier Notifier;
/* external API */
@ -401,6 +402,10 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
void kvm_irqchip_add_change_notifier(Notifier *n);
void kvm_irqchip_remove_change_notifier(Notifier *n);
void kvm_irqchip_change_notify(void);
void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
struct kvm_guest_debug;

View File

@ -614,7 +614,7 @@ static int test_migrate_start(QTestState **from, QTestState **to,
end_address = S390_TEST_MEM_END;
} else if (strcmp(arch, "ppc64") == 0) {
extra_opts = use_shmem ? get_shmem_opts("256M", shmem_path) : NULL;
cmd_src = g_strdup_printf("-machine accel=%s -m 256M -nodefaults"
cmd_src = g_strdup_printf("-machine accel=%s,vsmt=8 -m 256M -nodefaults"
" -name source,debug-threads=on"
" -serial file:%s/src_serial"
" -prom-env 'use-nvramrc?=true' -prom-env "
@ -623,7 +623,7 @@ static int test_migrate_start(QTestState **from, QTestState **to,
"until' %s %s", accel, tmpfs, end_address,
start_address, extra_opts ? extra_opts : "",
opts_src);
cmd_dst = g_strdup_printf("-machine accel=%s -m 256M"
cmd_dst = g_strdup_printf("-machine accel=%s,vsmt=8 -m 256M"
" -name target,debug-threads=on"
" -serial file:%s/dest_serial"
" -incoming %s %s %s",

View File

@ -46,15 +46,15 @@ static testdef_t x86_tests_slow[] = {
static testdef_t ppc64_tests[] = {
{ "pseries", "spapr-vlan",
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken" },
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,vsmt=8" },
{ "pseries", "virtio-net-pci",
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken" },
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,vsmt=8" },
{ NULL },
};
static testdef_t ppc64_tests_slow[] = {
{ "pseries", "e1000",
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken" },
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,vsmt=8" },
{ NULL },
};