Commit 24956974 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 4bae0ad1 aadbd07f
...@@ -48,7 +48,7 @@ void __init xen_pvh_init(struct boot_params *boot_params) ...@@ -48,7 +48,7 @@ void __init xen_pvh_init(struct boot_params *boot_params)
struct xen_platform_op op = { struct xen_platform_op op = {
.cmd = XENPF_get_dom0_console, .cmd = XENPF_get_dom0_console,
}; };
long ret = HYPERVISOR_platform_op(&op); int ret = HYPERVISOR_platform_op(&op);
if (ret > 0) if (ret > 0)
xen_init_vga(&op.u.dom0_console, xen_init_vga(&op.u.dom0_console,
......
...@@ -43,6 +43,7 @@ struct xencons_info { ...@@ -43,6 +43,7 @@ struct xencons_info {
int irq; int irq;
int vtermno; int vtermno;
grant_ref_t gntref; grant_ref_t gntref;
spinlock_t ring_lock;
}; };
static LIST_HEAD(xenconsoles); static LIST_HEAD(xenconsoles);
...@@ -89,12 +90,15 @@ static int __write_console(struct xencons_info *xencons, ...@@ -89,12 +90,15 @@ static int __write_console(struct xencons_info *xencons,
XENCONS_RING_IDX cons, prod; XENCONS_RING_IDX cons, prod;
struct xencons_interface *intf = xencons->intf; struct xencons_interface *intf = xencons->intf;
int sent = 0; int sent = 0;
unsigned long flags;
spin_lock_irqsave(&xencons->ring_lock, flags);
cons = intf->out_cons; cons = intf->out_cons;
prod = intf->out_prod; prod = intf->out_prod;
mb(); /* update queue values before going on */ mb(); /* update queue values before going on */
if ((prod - cons) > sizeof(intf->out)) { if ((prod - cons) > sizeof(intf->out)) {
spin_unlock_irqrestore(&xencons->ring_lock, flags);
pr_err_once("xencons: Illegal ring page indices"); pr_err_once("xencons: Illegal ring page indices");
return -EINVAL; return -EINVAL;
} }
...@@ -104,6 +108,7 @@ static int __write_console(struct xencons_info *xencons, ...@@ -104,6 +108,7 @@ static int __write_console(struct xencons_info *xencons,
wmb(); /* write ring before updating pointer */ wmb(); /* write ring before updating pointer */
intf->out_prod = prod; intf->out_prod = prod;
spin_unlock_irqrestore(&xencons->ring_lock, flags);
if (sent) if (sent)
notify_daemon(xencons); notify_daemon(xencons);
...@@ -146,16 +151,19 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len) ...@@ -146,16 +151,19 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
int recv = 0; int recv = 0;
struct xencons_info *xencons = vtermno_to_xencons(vtermno); struct xencons_info *xencons = vtermno_to_xencons(vtermno);
unsigned int eoiflag = 0; unsigned int eoiflag = 0;
unsigned long flags;
if (xencons == NULL) if (xencons == NULL)
return -EINVAL; return -EINVAL;
intf = xencons->intf; intf = xencons->intf;
spin_lock_irqsave(&xencons->ring_lock, flags);
cons = intf->in_cons; cons = intf->in_cons;
prod = intf->in_prod; prod = intf->in_prod;
mb(); /* get pointers before reading ring */ mb(); /* get pointers before reading ring */
if ((prod - cons) > sizeof(intf->in)) { if ((prod - cons) > sizeof(intf->in)) {
spin_unlock_irqrestore(&xencons->ring_lock, flags);
pr_err_once("xencons: Illegal ring page indices"); pr_err_once("xencons: Illegal ring page indices");
return -EINVAL; return -EINVAL;
} }
...@@ -179,10 +187,13 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len) ...@@ -179,10 +187,13 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
xencons->out_cons = intf->out_cons; xencons->out_cons = intf->out_cons;
xencons->out_cons_same = 0; xencons->out_cons_same = 0;
} }
if (!recv && xencons->out_cons_same++ > 1) {
eoiflag = XEN_EOI_FLAG_SPURIOUS;
}
spin_unlock_irqrestore(&xencons->ring_lock, flags);
if (recv) { if (recv) {
notify_daemon(xencons); notify_daemon(xencons);
} else if (xencons->out_cons_same++ > 1) {
eoiflag = XEN_EOI_FLAG_SPURIOUS;
} }
xen_irq_lateeoi(xencons->irq, eoiflag); xen_irq_lateeoi(xencons->irq, eoiflag);
...@@ -239,6 +250,7 @@ static int xen_hvm_console_init(void) ...@@ -239,6 +250,7 @@ static int xen_hvm_console_init(void)
info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&info->ring_lock);
} else if (info->intf != NULL) { } else if (info->intf != NULL) {
/* already configured */ /* already configured */
return 0; return 0;
...@@ -275,6 +287,7 @@ static int xen_hvm_console_init(void) ...@@ -275,6 +287,7 @@ static int xen_hvm_console_init(void)
static int xencons_info_pv_init(struct xencons_info *info, int vtermno) static int xencons_info_pv_init(struct xencons_info *info, int vtermno)
{ {
spin_lock_init(&info->ring_lock);
info->evtchn = xen_start_info->console.domU.evtchn; info->evtchn = xen_start_info->console.domU.evtchn;
/* GFN == MFN for PV guest */ /* GFN == MFN for PV guest */
info->intf = gfn_to_virt(xen_start_info->console.domU.mfn); info->intf = gfn_to_virt(xen_start_info->console.domU.mfn);
...@@ -325,6 +338,7 @@ static int xen_initial_domain_console_init(void) ...@@ -325,6 +338,7 @@ static int xen_initial_domain_console_init(void)
info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&info->ring_lock);
} }
info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false); info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false);
...@@ -482,6 +496,7 @@ static int xencons_probe(struct xenbus_device *dev, ...@@ -482,6 +496,7 @@ static int xencons_probe(struct xenbus_device *dev,
info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&info->ring_lock);
dev_set_drvdata(&dev->dev, info); dev_set_drvdata(&dev->dev, info);
info->xbdev = dev; info->xbdev = dev;
info->vtermno = xenbus_devid_to_vtermno(devid); info->vtermno = xenbus_devid_to_vtermno(devid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment