Skip to content

Commit 1871e84

Browse files
committed
Merge branch 'for-linus-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
Pull UML fixes from Richard Weinberger: "This patch set contains mostly fixes and cleanups. The UML tty driver uses now tty_port and is no longer broken like hell :-)" * 'for-linus-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: um: Add arch/x86/um to MAINTAINERS um: pass siginfo to guest process um: fix ubd_file_size for read-only files um: pull interrupt_end() into userspace() um: split syscall_trace(), pass pt_regs to it um: switch UPT_SET_RETURN_VALUE and regs_return_value to pt_regs um: set BLK_CGROUP=y in defconfig um: remove count_lock um: fully use tty_port um: Remove dead code um: remove line_ioctl() TTY: um/line, use tty from tty_port TTY: um/line, add tty_port
2 parents a6dc772 + b070989 commit 1871e84

File tree

23 files changed

+206
-302
lines changed

23 files changed

+206
-302
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7382,6 +7382,7 @@ W: http://user-mode-linux.sourceforge.net
73827382
S: Maintained
73837383
F: Documentation/virtual/uml/
73847384
F: arch/um/
7385+
F: arch/x86/um/
73857386
F: fs/hostfs/
73867387
F: fs/hppfs/
73877388

arch/um/defconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ CONFIG_CGROUP_SCHED=y
163163
CONFIG_FAIR_GROUP_SCHED=y
164164
# CONFIG_CFS_BANDWIDTH is not set
165165
# CONFIG_RT_GROUP_SCHED is not set
166-
CONFIG_BLK_CGROUP=m
166+
CONFIG_BLK_CGROUP=y
167167
# CONFIG_DEBUG_BLK_CGROUP is not set
168168
# CONFIG_CHECKPOINT_RESTORE is not set
169169
CONFIG_NAMESPACES=y

arch/um/drivers/chan_kern.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,11 @@ void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
150150
static void line_timer_cb(struct work_struct *work)
151151
{
152152
struct line *line = container_of(work, struct line, task.work);
153+
struct tty_struct *tty = tty_port_tty_get(&line->port);
153154

154155
if (!line->throttled)
155-
chan_interrupt(line, line->tty, line->driver->read_irq);
156+
chan_interrupt(line, tty, line->driver->read_irq);
157+
tty_kref_put(tty);
156158
}
157159

158160
int enable_chan(struct line *line)

arch/um/drivers/line.c

Lines changed: 63 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ static irqreturn_t line_interrupt(int irq, void *data)
1919
{
2020
struct chan *chan = data;
2121
struct line *line = chan->line;
22+
struct tty_struct *tty = tty_port_tty_get(&line->port);
2223

2324
if (line)
24-
chan_interrupt(line, line->tty, irq);
25+
chan_interrupt(line, tty, irq);
26+
tty_kref_put(tty);
2527
return IRQ_HANDLED;
2628
}
2729

@@ -219,92 +221,6 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old)
219221
/* nothing */
220222
}
221223

222-
static const struct {
223-
int cmd;
224-
char *level;
225-
char *name;
226-
} tty_ioctls[] = {
227-
/* don't print these, they flood the log ... */
228-
{ TCGETS, NULL, "TCGETS" },
229-
{ TCSETS, NULL, "TCSETS" },
230-
{ TCSETSW, NULL, "TCSETSW" },
231-
{ TCFLSH, NULL, "TCFLSH" },
232-
{ TCSBRK, NULL, "TCSBRK" },
233-
234-
/* general tty stuff */
235-
{ TCSETSF, KERN_DEBUG, "TCSETSF" },
236-
{ TCGETA, KERN_DEBUG, "TCGETA" },
237-
{ TIOCMGET, KERN_DEBUG, "TIOCMGET" },
238-
{ TCSBRKP, KERN_DEBUG, "TCSBRKP" },
239-
{ TIOCMSET, KERN_DEBUG, "TIOCMSET" },
240-
241-
/* linux-specific ones */
242-
{ TIOCLINUX, KERN_INFO, "TIOCLINUX" },
243-
{ KDGKBMODE, KERN_INFO, "KDGKBMODE" },
244-
{ KDGKBTYPE, KERN_INFO, "KDGKBTYPE" },
245-
{ KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" },
246-
};
247-
248-
int line_ioctl(struct tty_struct *tty, unsigned int cmd,
249-
unsigned long arg)
250-
{
251-
int ret;
252-
int i;
253-
254-
ret = 0;
255-
switch(cmd) {
256-
#ifdef TIOCGETP
257-
case TIOCGETP:
258-
case TIOCSETP:
259-
case TIOCSETN:
260-
#endif
261-
#ifdef TIOCGETC
262-
case TIOCGETC:
263-
case TIOCSETC:
264-
#endif
265-
#ifdef TIOCGLTC
266-
case TIOCGLTC:
267-
case TIOCSLTC:
268-
#endif
269-
/* Note: these are out of date as we now have TCGETS2 etc but this
270-
whole lot should probably go away */
271-
case TCGETS:
272-
case TCSETSF:
273-
case TCSETSW:
274-
case TCSETS:
275-
case TCGETA:
276-
case TCSETAF:
277-
case TCSETAW:
278-
case TCSETA:
279-
case TCXONC:
280-
case TCFLSH:
281-
case TIOCOUTQ:
282-
case TIOCINQ:
283-
case TIOCGLCKTRMIOS:
284-
case TIOCSLCKTRMIOS:
285-
case TIOCPKT:
286-
case TIOCGSOFTCAR:
287-
case TIOCSSOFTCAR:
288-
return -ENOIOCTLCMD;
289-
#if 0
290-
case TCwhatever:
291-
/* do something */
292-
break;
293-
#endif
294-
default:
295-
for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++)
296-
if (cmd == tty_ioctls[i].cmd)
297-
break;
298-
if (i == ARRAY_SIZE(tty_ioctls)) {
299-
printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n",
300-
__func__, tty->name, cmd);
301-
}
302-
ret = -ENOIOCTLCMD;
303-
break;
304-
}
305-
return ret;
306-
}
307-
308224
void line_throttle(struct tty_struct *tty)
309225
{
310226
struct line *line = tty->driver_data;
@@ -333,7 +249,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
333249
{
334250
struct chan *chan = data;
335251
struct line *line = chan->line;
336-
struct tty_struct *tty = line->tty;
252+
struct tty_struct *tty;
337253
int err;
338254

339255
/*
@@ -352,10 +268,13 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
352268
}
353269
spin_unlock(&line->lock);
354270

271+
tty = tty_port_tty_get(&line->port);
355272
if (tty == NULL)
356273
return IRQ_NONE;
357274

358275
tty_wakeup(tty);
276+
tty_kref_put(tty);
277+
359278
return IRQ_HANDLED;
360279
}
361280

@@ -377,88 +296,75 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
377296
return err;
378297
}
379298

380-
/*
381-
* Normally, a driver like this can rely mostly on the tty layer
382-
* locking, particularly when it comes to the driver structure.
383-
* However, in this case, mconsole requests can come in "from the
384-
* side", and race with opens and closes.
385-
*
386-
* mconsole config requests will want to be sure the device isn't in
387-
* use, and get_config, open, and close will want a stable
388-
* configuration. The checking and modification of the configuration
389-
* is done under a spinlock. Checking whether the device is in use is
390-
* line->tty->count > 1, also under the spinlock.
391-
*
392-
* line->count serves to decide whether the device should be enabled or
393-
* disabled on the host. If it's equal to 0, then we are doing the
394-
* first open or last close. Otherwise, open and close just return.
395-
*/
396-
397-
int line_open(struct line *lines, struct tty_struct *tty)
299+
static int line_activate(struct tty_port *port, struct tty_struct *tty)
398300
{
399-
struct line *line = &lines[tty->index];
400-
int err = -ENODEV;
401-
402-
mutex_lock(&line->count_lock);
403-
if (!line->valid)
404-
goto out_unlock;
405-
406-
err = 0;
407-
if (line->count++)
408-
goto out_unlock;
409-
410-
BUG_ON(tty->driver_data);
411-
tty->driver_data = line;
412-
line->tty = tty;
301+
int ret;
302+
struct line *line = tty->driver_data;
413303

414-
err = enable_chan(line);
415-
if (err) /* line_close() will be called by our caller */
416-
goto out_unlock;
304+
ret = enable_chan(line);
305+
if (ret)
306+
return ret;
417307

418308
if (!line->sigio) {
419309
chan_enable_winch(line->chan_out, tty);
420310
line->sigio = 1;
421311
}
422312

423313
chan_window_size(line, &tty->winsize.ws_row,
424-
&tty->winsize.ws_col);
425-
out_unlock:
426-
mutex_unlock(&line->count_lock);
427-
return err;
314+
&tty->winsize.ws_col);
315+
316+
return 0;
428317
}
429318

430-
static void unregister_winch(struct tty_struct *tty);
319+
static const struct tty_port_operations line_port_ops = {
320+
.activate = line_activate,
321+
};
431322

432-
void line_close(struct tty_struct *tty, struct file * filp)
323+
int line_open(struct tty_struct *tty, struct file *filp)
433324
{
434325
struct line *line = tty->driver_data;
435326

436-
/*
437-
* If line_open fails (and tty->driver_data is never set),
438-
* tty_open will call line_close. So just return in this case.
439-
*/
440-
if (line == NULL)
441-
return;
327+
return tty_port_open(&line->port, tty, filp);
328+
}
442329

443-
/* We ignore the error anyway! */
444-
flush_buffer(line);
330+
int line_install(struct tty_driver *driver, struct tty_struct *tty,
331+
struct line *line)
332+
{
333+
int ret;
445334

446-
mutex_lock(&line->count_lock);
447-
BUG_ON(!line->valid);
335+
ret = tty_standard_install(driver, tty);
336+
if (ret)
337+
return ret;
448338

449-
if (--line->count)
450-
goto out_unlock;
339+
tty->driver_data = line;
451340

452-
line->tty = NULL;
453-
tty->driver_data = NULL;
341+
return 0;
342+
}
343+
344+
static void unregister_winch(struct tty_struct *tty);
345+
346+
void line_cleanup(struct tty_struct *tty)
347+
{
348+
struct line *line = tty->driver_data;
454349

455350
if (line->sigio) {
456351
unregister_winch(tty);
457352
line->sigio = 0;
458353
}
354+
}
355+
356+
void line_close(struct tty_struct *tty, struct file * filp)
357+
{
358+
struct line *line = tty->driver_data;
459359

460-
out_unlock:
461-
mutex_unlock(&line->count_lock);
360+
tty_port_close(&line->port, tty, filp);
361+
}
362+
363+
void line_hangup(struct tty_struct *tty)
364+
{
365+
struct line *line = tty->driver_data;
366+
367+
tty_port_hangup(&line->port);
462368
}
463369

464370
void close_lines(struct line *lines, int nlines)
@@ -476,9 +382,7 @@ int setup_one_line(struct line *lines, int n, char *init,
476382
struct tty_driver *driver = line->driver->driver;
477383
int err = -EINVAL;
478384

479-
mutex_lock(&line->count_lock);
480-
481-
if (line->count) {
385+
if (line->port.count) {
482386
*error_out = "Device is already open";
483387
goto out;
484388
}
@@ -519,7 +423,6 @@ int setup_one_line(struct line *lines, int n, char *init,
519423
}
520424
}
521425
out:
522-
mutex_unlock(&line->count_lock);
523426
return err;
524427
}
525428

@@ -607,13 +510,17 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
607510

608511
line = &lines[dev];
609512

610-
mutex_lock(&line->count_lock);
611513
if (!line->valid)
612514
CONFIG_CHUNK(str, size, n, "none", 1);
613-
else if (line->tty == NULL)
614-
CONFIG_CHUNK(str, size, n, line->init_str, 1);
615-
else n = chan_config_string(line, str, size, error_out);
616-
mutex_unlock(&line->count_lock);
515+
else {
516+
struct tty_struct *tty = tty_port_tty_get(&line->port);
517+
if (tty == NULL) {
518+
CONFIG_CHUNK(str, size, n, line->init_str, 1);
519+
} else {
520+
n = chan_config_string(line, str, size, error_out);
521+
tty_kref_put(tty);
522+
}
523+
}
617524

618525
return n;
619526
}
@@ -663,8 +570,9 @@ int register_lines(struct line_driver *line_driver,
663570
driver->init_termios = tty_std_termios;
664571

665572
for (i = 0; i < nlines; i++) {
573+
tty_port_init(&lines[i].port);
574+
lines[i].port.ops = &line_port_ops;
666575
spin_lock_init(&lines[i].lock);
667-
mutex_init(&lines[i].count_lock);
668576
lines[i].driver = line_driver;
669577
INIT_LIST_HEAD(&lines[i].chan_list);
670578
}

arch/um/drivers/line.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ struct line_driver {
3232
};
3333

3434
struct line {
35-
struct tty_struct *tty;
36-
struct mutex count_lock;
37-
unsigned long count;
35+
struct tty_port port;
3836
int valid;
3937

4038
char *init_str;
@@ -59,7 +57,11 @@ struct line {
5957
};
6058

6159
extern void line_close(struct tty_struct *tty, struct file * filp);
62-
extern int line_open(struct line *lines, struct tty_struct *tty);
60+
extern int line_open(struct tty_struct *tty, struct file *filp);
61+
extern int line_install(struct tty_driver *driver, struct tty_struct *tty,
62+
struct line *line);
63+
extern void line_cleanup(struct tty_struct *tty);
64+
extern void line_hangup(struct tty_struct *tty);
6365
extern int line_setup(char **conf, unsigned nlines, char **def,
6466
char *init, char *name);
6567
extern int line_write(struct tty_struct *tty, const unsigned char *buf,
@@ -70,8 +72,6 @@ extern int line_chars_in_buffer(struct tty_struct *tty);
7072
extern void line_flush_buffer(struct tty_struct *tty);
7173
extern void line_flush_chars(struct tty_struct *tty);
7274
extern int line_write_room(struct tty_struct *tty);
73-
extern int line_ioctl(struct tty_struct *tty, unsigned int cmd,
74-
unsigned long arg);
7575
extern void line_throttle(struct tty_struct *tty);
7676
extern void line_unthrottle(struct tty_struct *tty);
7777

0 commit comments

Comments
 (0)