Commit ba31f97d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-5.14-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen fixes from Juergen Gross:
 "A small cleanup patch and a fix of a rare race in the Xen evtchn
  driver"

* tag 'for-linus-5.14-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen/events: Fix race in set_evtchn_to_irq
  xen/events: remove redundant initialization of variable irq
parents a7a4f1c0 88ca2521
...@@ -198,12 +198,12 @@ static void disable_dynirq(struct irq_data *data); ...@@ -198,12 +198,12 @@ static void disable_dynirq(struct irq_data *data);
static DEFINE_PER_CPU(unsigned int, irq_epoch); static DEFINE_PER_CPU(unsigned int, irq_epoch);
static void clear_evtchn_to_irq_row(unsigned row) static void clear_evtchn_to_irq_row(int *evtchn_row)
{ {
unsigned col; unsigned col;
for (col = 0; col < EVTCHN_PER_ROW; col++) for (col = 0; col < EVTCHN_PER_ROW; col++)
WRITE_ONCE(evtchn_to_irq[row][col], -1); WRITE_ONCE(evtchn_row[col], -1);
} }
static void clear_evtchn_to_irq_all(void) static void clear_evtchn_to_irq_all(void)
...@@ -213,7 +213,7 @@ static void clear_evtchn_to_irq_all(void) ...@@ -213,7 +213,7 @@ static void clear_evtchn_to_irq_all(void)
for (row = 0; row < EVTCHN_ROW(xen_evtchn_max_channels()); row++) { for (row = 0; row < EVTCHN_ROW(xen_evtchn_max_channels()); row++) {
if (evtchn_to_irq[row] == NULL) if (evtchn_to_irq[row] == NULL)
continue; continue;
clear_evtchn_to_irq_row(row); clear_evtchn_to_irq_row(evtchn_to_irq[row]);
} }
} }
...@@ -221,6 +221,7 @@ static int set_evtchn_to_irq(evtchn_port_t evtchn, unsigned int irq) ...@@ -221,6 +221,7 @@ static int set_evtchn_to_irq(evtchn_port_t evtchn, unsigned int irq)
{ {
unsigned row; unsigned row;
unsigned col; unsigned col;
int *evtchn_row;
if (evtchn >= xen_evtchn_max_channels()) if (evtchn >= xen_evtchn_max_channels())
return -EINVAL; return -EINVAL;
...@@ -233,11 +234,18 @@ static int set_evtchn_to_irq(evtchn_port_t evtchn, unsigned int irq) ...@@ -233,11 +234,18 @@ static int set_evtchn_to_irq(evtchn_port_t evtchn, unsigned int irq)
if (irq == -1) if (irq == -1)
return 0; return 0;
evtchn_to_irq[row] = (int *)get_zeroed_page(GFP_KERNEL); evtchn_row = (int *) __get_free_pages(GFP_KERNEL, 0);
if (evtchn_to_irq[row] == NULL) if (evtchn_row == NULL)
return -ENOMEM; return -ENOMEM;
clear_evtchn_to_irq_row(row); clear_evtchn_to_irq_row(evtchn_row);
/*
* We've prepared an empty row for the mapping. If a different
* thread was faster inserting it, we can drop ours.
*/
if (cmpxchg(&evtchn_to_irq[row], NULL, evtchn_row) != NULL)
free_page((unsigned long) evtchn_row);
} }
WRITE_ONCE(evtchn_to_irq[row][col], irq); WRITE_ONCE(evtchn_to_irq[row][col], irq);
...@@ -1009,7 +1017,7 @@ static void __unbind_from_irq(unsigned int irq) ...@@ -1009,7 +1017,7 @@ static void __unbind_from_irq(unsigned int irq)
int xen_bind_pirq_gsi_to_irq(unsigned gsi, int xen_bind_pirq_gsi_to_irq(unsigned gsi,
unsigned pirq, int shareable, char *name) unsigned pirq, int shareable, char *name)
{ {
int irq = -1; int irq;
struct physdev_irq irq_op; struct physdev_irq irq_op;
int ret; int ret;
......
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