/* * Linux driver for TerraTec DMX 6Fire USB * * Rawmidi driver * * Author: Torsten Schenk * Created: Jan 01, 2011 * Copyright: (C) Torsten Schenk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include "midi.h" #include "chip.h" #include "comm.h" enum { MIDI_BUFSIZE = 64 }; static void usb6fire_midi_out_handler(struct urb *urb) { struct midi_runtime *rt = urb->context; int ret; unsigned long flags; spin_lock_irqsave(&rt->out_lock, flags); if (rt->out) { ret = snd_rawmidi_transmit(rt->out, rt->out_buffer + 4, MIDI_BUFSIZE - 4); if (ret > 0) { /* more data available, send next packet */ rt->out_buffer[1] = ret + 2; rt->out_buffer[3] = rt->out_serial++; urb->transfer_buffer_length = ret + 4; ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) dev_err(&urb->dev->dev, "midi out urb submit failed: %d\n", ret); } else /* no more data to transmit */ rt->out = NULL; } spin_unlock_irqrestore(&rt->out_lock, flags); } static void usb6fire_midi_in_received( struct midi_runtime *rt, u8 *data, int length) { unsigned long flags; spin_lock_irqsave(&rt->in_lock, flags); if (rt->in) snd_rawmidi_receive(rt->in, data, length); spin_unlock_irqrestore(&rt->in_lock, flags); } static int usb6fire_midi_out_open(struct snd_rawmidi_substream *alsa_sub) { return 0; } static int usb6fire_midi_out_close(struct snd_rawmidi_substream *alsa_sub) { return 0; } static void usb6fire_midi_out_trigger( struct snd_rawmidi_substream *alsa_sub, int up) { struct midi_runtime *rt = alsa_sub->rmidi->private_data; struct urb *urb = &rt->out_urb; __s8 ret; unsigned long flags; spin_lock_irqsave(&rt->out_lock, flags); if (up) { /* start transfer */ if (rt->out) { /* we are already transmitting so just return */ spin_unlock_irqrestore(&rt->out_lock, flags); return; } ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4, MIDI_BUFSIZE - 4); if (ret > 0) { rt->out_buffer[1] = ret + 2; rt->out_buffer[3] = rt->out_serial++; urb->transfer_buffer_length = ret + 4; ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) dev_err(&urb->dev->dev, "midi out urb submit failed: %d\n", ret); else rt->out = alsa_sub; } } else if (rt->out == alsa_sub) rt->out = NULL; spin_unlock_irqrestore(&rt->out_lock, flags); } static void usb6fire_midi_out_drain(struct snd_rawmidi_substream *alsa_sub) { struct midi_runtime *rt = alsa_sub->rmidi->private_data; int retry = 0; while (rt->out && retry++ < 100) msleep(10); } static int usb6fire_midi_in_open(struct snd_rawmidi_substream *alsa_sub) { return 0; } static int usb6fire_midi_in_close(struct snd_rawmidi_substream *alsa_sub) { return 0; } static void usb6fire_midi_in_trigger( struct snd_rawmidi_substream *alsa_sub, int up) { struct midi_runtime *rt = alsa_sub->rmidi->private_data; unsigned long flags; spin_lock_irqsave(&rt->in_lock, flags); if (up) rt->in = alsa_sub; else rt->in = NULL; spin_unlock_irqrestore(&rt->in_lock, flags); } static struct snd_rawmidi_ops out_ops = { .open = usb6fire_midi_out_open, .close = usb6fire_midi_out_close, .trigger = usb6fire_midi_out_trigger, .drain = usb6fire_midi_out_drain }; static struct snd_rawmidi_ops in_ops = { .open = usb6fire_midi_in_open, .close = usb6fire_midi_in_close, .trigger = usb6fire_midi_in_trigger }; int usb6fire_midi_init(struct sfire_chip *chip) { int ret; struct midi_runtime *rt = kzalloc(sizeof(struct midi_runtime), GFP_KERNEL); struct comm_runtime *comm_rt = chip->comm; if (!rt) return -ENOMEM; rt->out_buffer = kzalloc(MIDI_BUFSIZE, GFP_KERNEL); if (!rt->out_buffer) { kfree(rt); return -ENOMEM; } rt->chip = chip; rt->in_received = usb6fire_midi_in_received; rt->out_buffer[0] = 0x80; /* 'send midi' command */ rt->out_buffer[1] = 0x00; /* size of data */ rt->out_buffer[2] = 0x00; /* always 0 */ spin_lock_init(&rt->in_lock); spin_lock_init(&rt->out_lock); comm_rt->init_urb(comm_rt, &rt->out_urb, rt->out_buffer, rt, usb6fire_midi_out_handler); ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance); if (ret < 0) { kfree(rt->out_buffer); kfree(rt); dev_err(&chip->dev->dev, "unable to create midi.\n"); return ret; } rt->instance->private_data = rt; strcpy(rt->instance->name, "DMX6FireUSB MIDI"); rt->instance->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_OUTPUT, &out_ops); snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_INPUT, &in_ops); chip->midi = rt; return 0; } void usb6fire_midi_abort(struct sfire_chip *chip) { struct midi_runtime *rt = chip->midi; if (rt) usb_poison_urb(&rt->out_urb); } void usb6fire_midi_destroy(struct sfire_chip *chip) { struct midi_runtime *rt = chip->midi; kfree(rt->out_buffer); kfree(rt); chip->midi = NULL; } :11 +0800 commit02608e02fbec04fccf2eb0cc8d8082f65c0a4286 (patch) tree37ff0410d130cfe77185f591b07cd6403f207f0c /tools/perf/scripts/python/Perf-Trace-Util parent7ce7d89f48834cefece7804d38fc5d85382edf77 (diff)
crypto: testmgr - Use heap buffer for acomp test input
Christopher Covington reported a crash on aarch64 on recent Fedora kernels: kernel BUG at ./include/linux/scatterlist.h:140! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP Modules linked in: CPU: 2 PID: 752 Comm: cryptomgr_test Not tainted 4.9.0-11815-ge93b1cc #162 Hardware name: linux,dummy-virt (DT) task: ffff80007c650080 task.stack: ffff800008910000 PC is at sg_init_one+0xa0/0xb8 LR is at sg_init_one+0x24/0xb8 ... [<ffff000008398db8>] sg_init_one+0xa0/0xb8 [<ffff000008350a44>] test_acomp+0x10c/0x438 [<ffff000008350e20>] alg_test_comp+0xb0/0x118 [<ffff00000834f28c>] alg_test+0x17c/0x2f0 [<ffff00000834c6a4>] cryptomgr_test+0x44/0x50 [<ffff0000080dac70>] kthread+0xf8/0x128 [<ffff000008082ec0>] ret_from_fork+0x10/0x50 The test vectors used for input are part of the kernel image. These inputs are passed as a buffer to sg_init_one which eventually blows up with BUG_ON(!virt_addr_valid(buf)). On arm64, virt_addr_valid returns false for the kernel image since virt_to_page will not return the correct page. Fix this by copying the input vectors to heap buffer before setting up the scatterlist. Reported-by: Christopher Covington <cov@codeaurora.org> Fixes: d7db7a882deb ("crypto: acomp - update testmgr with support for acomp") Signed-off-by: Laura Abbott <labbott@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'tools/perf/scripts/python/Perf-Trace-Util')