Skip to content

Commit 345b17a

Browse files
committed
Merge tag 'for-linus-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
Pull UML updates from Richard Weinberger: - IRQ handling cleanups - Support for suspend - Various fixes for UML specific drivers: ubd, vector, xterm * tag 'for-linus-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: (32 commits) um: Fix build w/o CONFIG_PM_SLEEP um: time-travel: Correct time event IRQ delivery um: irq/sigio: Support suspend/resume handling of workaround IRQs um: time-travel: Actually apply "free-until" optimisation um: chan_xterm: Fix fd leak um: tty: Fix handling of close in tty lines um: Monitor error events in IRQ controller um: allocate a guard page to helper threads um: support some of ARCH_HAS_SET_MEMORY um: time-travel: avoid multiple identical propagations um: Fetch registers only for signals which need them um: Support suspend to RAM um: Allow PM with suspend-to-idle um: time: Fix read_persistent_clock64() in time-travel um: Simplify os_idle_sleep() and sleep longer um: Simplify IRQ handling code um: Remove IRQ_NONE type um: irq: Reduce irq_reg allocation um: irq: Clean up and rename struct irq_fd um: Clean up alarm IRQ chip name ...
2 parents 787fec8 + 1fb1abc commit 345b17a

36 files changed

Lines changed: 905 additions & 596 deletions

arch/um/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ config UML
1515
select HAVE_DEBUG_KMEMLEAK
1616
select HAVE_DEBUG_BUGVERBOSE
1717
select NO_DMA
18+
select ARCH_HAS_SET_MEMORY
1819
select GENERIC_IRQ_SHOW
1920
select GENERIC_CPU_DEVICES
2021
select HAVE_GCC_PLUGINS
@@ -191,3 +192,8 @@ config UML_TIME_TRAVEL_SUPPORT
191192
endmenu
192193

193194
source "arch/um/drivers/Kconfig"
195+
196+
config ARCH_SUSPEND_POSSIBLE
197+
def_bool y
198+
199+
source "kernel/power/Kconfig"

arch/um/drivers/chan_user.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ int generic_read(int fd, char *c_out, void *unused)
2626
n = read(fd, c_out, sizeof(*c_out));
2727
if (n > 0)
2828
return n;
29-
else if (errno == EAGAIN)
30-
return 0;
3129
else if (n == 0)
3230
return -EIO;
31+
else if (errno == EAGAIN)
32+
return 0;
3333
return -errno;
3434
}
3535

arch/um/drivers/line.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -262,19 +262,25 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
262262
int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
263263
{
264264
const struct line_driver *driver = line->driver;
265-
int err = 0;
265+
int err;
266266

267-
if (input)
267+
if (input) {
268268
err = um_request_irq(driver->read_irq, fd, IRQ_READ,
269269
line_interrupt, IRQF_SHARED,
270270
driver->read_irq_name, data);
271-
if (err)
272-
return err;
273-
if (output)
271+
if (err < 0)
272+
return err;
273+
}
274+
275+
if (output) {
274276
err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
275277
line_write_interrupt, IRQF_SHARED,
276278
driver->write_irq_name, data);
277-
return err;
279+
if (err < 0)
280+
return err;
281+
}
282+
283+
return 0;
278284
}
279285

280286
static int line_activate(struct tty_port *port, struct tty_struct *tty)
@@ -608,7 +614,6 @@ static void free_winch(struct winch *winch)
608614
winch->fd = -1;
609615
if (fd != -1)
610616
os_close_file(fd);
611-
list_del(&winch->list);
612617
__free_winch(&winch->work);
613618
}
614619

@@ -709,6 +714,8 @@ static void unregister_winch(struct tty_struct *tty)
709714
winch = list_entry(ele, struct winch, list);
710715
wtty = tty_port_tty_get(winch->port);
711716
if (wtty == tty) {
717+
list_del(&winch->list);
718+
spin_unlock(&winch_handler_lock);
712719
free_winch(winch);
713720
break;
714721
}
@@ -719,14 +726,17 @@ static void unregister_winch(struct tty_struct *tty)
719726

720727
static void winch_cleanup(void)
721728
{
722-
struct list_head *ele, *next;
723729
struct winch *winch;
724730

725731
spin_lock(&winch_handler_lock);
732+
while ((winch = list_first_entry_or_null(&winch_handlers,
733+
struct winch, list))) {
734+
list_del(&winch->list);
735+
spin_unlock(&winch_handler_lock);
726736

727-
list_for_each_safe(ele, next, &winch_handlers) {
728-
winch = list_entry(ele, struct winch, list);
729737
free_winch(winch);
738+
739+
spin_lock(&winch_handler_lock);
730740
}
731741

732742
spin_unlock(&winch_handler_lock);

arch/um/drivers/mconsole_kern.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ static int __init mconsole_init(void)
738738

739739
err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
740740
IRQF_SHARED, "mconsole", (void *)sock);
741-
if (err) {
741+
if (err < 0) {
742742
printk(KERN_ERR "Failed to get IRQ for management console\n");
743743
goto out;
744744
}

arch/um/drivers/net_kern.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ static int uml_net_open(struct net_device *dev)
160160

161161
err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
162162
IRQF_SHARED, dev->name, dev);
163-
if (err != 0) {
163+
if (err < 0) {
164164
printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
165165
err = -ENETUNREACH;
166166
goto out_close;

arch/um/drivers/port_kern.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ static int port_accept(struct port_list *port)
100100
.port = port });
101101

102102
if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
103-
IRQF_SHARED, "telnetd", conn)) {
103+
IRQF_SHARED, "telnetd", conn) < 0) {
104104
printk(KERN_ERR "port_accept : failed to get IRQ for "
105105
"telnetd\n");
106106
goto out_free;
@@ -182,7 +182,7 @@ void *port_data(int port_num)
182182
}
183183

184184
if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
185-
IRQF_SHARED, "port", port)) {
185+
IRQF_SHARED, "port", port) < 0) {
186186
printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
187187
goto out_close;
188188
}

arch/um/drivers/random.c

Lines changed: 27 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -11,105 +11,53 @@
1111
#include <linux/fs.h>
1212
#include <linux/interrupt.h>
1313
#include <linux/miscdevice.h>
14+
#include <linux/hw_random.h>
1415
#include <linux/delay.h>
1516
#include <linux/uaccess.h>
1617
#include <init.h>
1718
#include <irq_kern.h>
1819
#include <os.h>
1920

2021
/*
21-
* core module and version information
22+
* core module information
2223
*/
23-
#define RNG_VERSION "1.0.0"
2424
#define RNG_MODULE_NAME "hw_random"
2525

2626
/* Changed at init time, in the non-modular case, and at module load
2727
* time, in the module case. Presumably, the module subsystem
2828
* protects against a module being loaded twice at the same time.
2929
*/
3030
static int random_fd = -1;
31-
static DECLARE_WAIT_QUEUE_HEAD(host_read_wait);
31+
static struct hwrng hwrng = { 0, };
32+
static DECLARE_COMPLETION(have_data);
3233

33-
static int rng_dev_open (struct inode *inode, struct file *filp)
34+
static int rng_dev_read(struct hwrng *rng, void *buf, size_t max, bool block)
3435
{
35-
/* enforce read-only access to this chrdev */
36-
if ((filp->f_mode & FMODE_READ) == 0)
37-
return -EINVAL;
38-
if ((filp->f_mode & FMODE_WRITE) != 0)
39-
return -EINVAL;
36+
int ret;
4037

41-
return 0;
42-
}
43-
44-
static atomic_t host_sleep_count = ATOMIC_INIT(0);
45-
46-
static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
47-
loff_t *offp)
48-
{
49-
u32 data;
50-
int n, ret = 0, have_data;
51-
52-
while (size) {
53-
n = os_read_file(random_fd, &data, sizeof(data));
54-
if (n > 0) {
55-
have_data = n;
56-
while (have_data && size) {
57-
if (put_user((u8) data, buf++)) {
58-
ret = ret ? : -EFAULT;
59-
break;
60-
}
61-
size--;
62-
ret++;
63-
have_data--;
64-
data >>= 8;
65-
}
66-
}
67-
else if (n == -EAGAIN) {
68-
DECLARE_WAITQUEUE(wait, current);
69-
70-
if (filp->f_flags & O_NONBLOCK)
71-
return ret ? : -EAGAIN;
72-
73-
atomic_inc(&host_sleep_count);
38+
for (;;) {
39+
ret = os_read_file(random_fd, buf, max);
40+
if (block && ret == -EAGAIN) {
7441
add_sigio_fd(random_fd);
7542

76-
add_wait_queue(&host_read_wait, &wait);
77-
set_current_state(TASK_INTERRUPTIBLE);
43+
ret = wait_for_completion_killable(&have_data);
7844

79-
schedule();
80-
remove_wait_queue(&host_read_wait, &wait);
45+
ignore_sigio_fd(random_fd);
46+
deactivate_fd(random_fd, RANDOM_IRQ);
8147

82-
if (atomic_dec_and_test(&host_sleep_count)) {
83-
ignore_sigio_fd(random_fd);
84-
deactivate_fd(random_fd, RANDOM_IRQ);
85-
}
48+
if (ret < 0)
49+
break;
50+
} else {
51+
break;
8652
}
87-
else
88-
return n;
89-
90-
if (signal_pending (current))
91-
return ret ? : -ERESTARTSYS;
9253
}
93-
return ret;
94-
}
95-
96-
static const struct file_operations rng_chrdev_ops = {
97-
.owner = THIS_MODULE,
98-
.open = rng_dev_open,
99-
.read = rng_dev_read,
100-
.llseek = noop_llseek,
101-
};
10254

103-
/* rng_init shouldn't be called more than once at boot time */
104-
static struct miscdevice rng_miscdev = {
105-
HWRNG_MINOR,
106-
RNG_MODULE_NAME,
107-
&rng_chrdev_ops,
108-
};
55+
return ret != -EAGAIN ? ret : 0;
56+
}
10957

11058
static irqreturn_t random_interrupt(int irq, void *data)
11159
{
112-
wake_up(&host_read_wait);
60+
complete(&have_data);
11361

11462
return IRQ_HANDLED;
11563
}
@@ -126,18 +74,19 @@ static int __init rng_init (void)
12674
goto out;
12775

12876
random_fd = err;
129-
13077
err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
13178
0, "random", NULL);
132-
if (err)
79+
if (err < 0)
13380
goto err_out_cleanup_hw;
13481

135-
sigio_broken(random_fd, 1);
82+
sigio_broken(random_fd);
83+
hwrng.name = RNG_MODULE_NAME;
84+
hwrng.read = rng_dev_read;
85+
hwrng.quality = 1024;
13686

137-
err = misc_register (&rng_miscdev);
87+
err = hwrng_register(&hwrng);
13888
if (err) {
139-
printk (KERN_ERR RNG_MODULE_NAME ": misc device register "
140-
"failed\n");
89+
pr_err(RNG_MODULE_NAME " registering failed (%d)\n", err);
14190
goto err_out_cleanup_hw;
14291
}
14392
out:
@@ -161,8 +110,8 @@ static void cleanup(void)
161110

162111
static void __exit rng_cleanup(void)
163112
{
113+
hwrng_unregister(&hwrng);
164114
os_close_file(random_fd);
165-
misc_deregister (&rng_miscdev);
166115
}
167116

168117
module_init (rng_init);

0 commit comments

Comments
 (0)