Skip to content

Commit 2495697

Browse files
committed
Merge tag 'for-linus-6.3-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen fixes from Juergen Gross: - fix build warning - avoid concurrent accesses to the Xen PV console ring page * tag 'for-linus-6.3-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: x86/PVH: avoid 32-bit build warning when obtaining VGA console info hvc/xen: prevent concurrent accesses to the shared ring
2 parents 4bae0ad + aadbd07 commit 2495697

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

arch/x86/xen/enlighten_pvh.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void __init xen_pvh_init(struct boot_params *boot_params)
4848
struct xen_platform_op op = {
4949
.cmd = XENPF_get_dom0_console,
5050
};
51-
long ret = HYPERVISOR_platform_op(&op);
51+
int ret = HYPERVISOR_platform_op(&op);
5252

5353
if (ret > 0)
5454
xen_init_vga(&op.u.dom0_console,

drivers/tty/hvc/hvc_xen.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct xencons_info {
4343
int irq;
4444
int vtermno;
4545
grant_ref_t gntref;
46+
spinlock_t ring_lock;
4647
};
4748

4849
static LIST_HEAD(xenconsoles);
@@ -89,12 +90,15 @@ static int __write_console(struct xencons_info *xencons,
8990
XENCONS_RING_IDX cons, prod;
9091
struct xencons_interface *intf = xencons->intf;
9192
int sent = 0;
93+
unsigned long flags;
9294

95+
spin_lock_irqsave(&xencons->ring_lock, flags);
9396
cons = intf->out_cons;
9497
prod = intf->out_prod;
9598
mb(); /* update queue values before going on */
9699

97100
if ((prod - cons) > sizeof(intf->out)) {
101+
spin_unlock_irqrestore(&xencons->ring_lock, flags);
98102
pr_err_once("xencons: Illegal ring page indices");
99103
return -EINVAL;
100104
}
@@ -104,6 +108,7 @@ static int __write_console(struct xencons_info *xencons,
104108

105109
wmb(); /* write ring before updating pointer */
106110
intf->out_prod = prod;
111+
spin_unlock_irqrestore(&xencons->ring_lock, flags);
107112

108113
if (sent)
109114
notify_daemon(xencons);
@@ -146,16 +151,19 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
146151
int recv = 0;
147152
struct xencons_info *xencons = vtermno_to_xencons(vtermno);
148153
unsigned int eoiflag = 0;
154+
unsigned long flags;
149155

150156
if (xencons == NULL)
151157
return -EINVAL;
152158
intf = xencons->intf;
153159

160+
spin_lock_irqsave(&xencons->ring_lock, flags);
154161
cons = intf->in_cons;
155162
prod = intf->in_prod;
156163
mb(); /* get pointers before reading ring */
157164

158165
if ((prod - cons) > sizeof(intf->in)) {
166+
spin_unlock_irqrestore(&xencons->ring_lock, flags);
159167
pr_err_once("xencons: Illegal ring page indices");
160168
return -EINVAL;
161169
}
@@ -179,10 +187,13 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
179187
xencons->out_cons = intf->out_cons;
180188
xencons->out_cons_same = 0;
181189
}
190+
if (!recv && xencons->out_cons_same++ > 1) {
191+
eoiflag = XEN_EOI_FLAG_SPURIOUS;
192+
}
193+
spin_unlock_irqrestore(&xencons->ring_lock, flags);
194+
182195
if (recv) {
183196
notify_daemon(xencons);
184-
} else if (xencons->out_cons_same++ > 1) {
185-
eoiflag = XEN_EOI_FLAG_SPURIOUS;
186197
}
187198

188199
xen_irq_lateeoi(xencons->irq, eoiflag);
@@ -239,6 +250,7 @@ static int xen_hvm_console_init(void)
239250
info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
240251
if (!info)
241252
return -ENOMEM;
253+
spin_lock_init(&info->ring_lock);
242254
} else if (info->intf != NULL) {
243255
/* already configured */
244256
return 0;
@@ -275,6 +287,7 @@ static int xen_hvm_console_init(void)
275287

276288
static int xencons_info_pv_init(struct xencons_info *info, int vtermno)
277289
{
290+
spin_lock_init(&info->ring_lock);
278291
info->evtchn = xen_start_info->console.domU.evtchn;
279292
/* GFN == MFN for PV guest */
280293
info->intf = gfn_to_virt(xen_start_info->console.domU.mfn);
@@ -325,6 +338,7 @@ static int xen_initial_domain_console_init(void)
325338
info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
326339
if (!info)
327340
return -ENOMEM;
341+
spin_lock_init(&info->ring_lock);
328342
}
329343

330344
info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false);
@@ -482,6 +496,7 @@ static int xencons_probe(struct xenbus_device *dev,
482496
info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
483497
if (!info)
484498
return -ENOMEM;
499+
spin_lock_init(&info->ring_lock);
485500
dev_set_drvdata(&dev->dev, info);
486501
info->xbdev = dev;
487502
info->vtermno = xenbus_devid_to_vtermno(devid);

0 commit comments

Comments
 (0)