* [PATCH 1/3] xen/events/fifo: reset control block and local HEADs on resume
[not found] <1406820146-1616-1-git-send-email-david.vrabel@citrix.com>
@ 2014-07-31 15:22 ` David Vrabel
2014-07-31 15:22 ` [PATCH 2/3] xen/events/fifo: ensure all bitops are properly aligned even on x86 David Vrabel
2014-07-31 15:22 ` [PATCH 3/3] xen/events/fifo: remove a unecessary use of BM() David Vrabel
2 siblings, 0 replies; 3+ messages in thread
From: David Vrabel @ 2014-07-31 15:22 UTC (permalink / raw)
To: xen-devel; +Cc: Boris Ostrovsky, David Vrabel, stable
When using the FIFO-based event channel ABI, if the control block or
the local HEADs are not reset after resuming the guest may see stale
HEAD values and will fail to traverse the FIFO correctly.
This may prevent one or more VCPUs from receiving any events following
a resume.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Cc: stable@vger.kernel.org
---
drivers/xen/events/events_fifo.c | 41 ++++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index 84b4bfb..7dc0a7c 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -100,6 +100,24 @@ static unsigned evtchn_fifo_nr_channels(void)
return event_array_pages * EVENT_WORDS_PER_PAGE;
}
+static int init_control_block(int cpu, void *control_block)
+{
+ struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu);
+ struct evtchn_init_control init_control;
+ unsigned int i;
+
+ /* Reset the control block and the local HEADs. */
+ clear_page(control_block);
+ for (i = 0; i < EVTCHN_FIFO_MAX_QUEUES; i++)
+ q->head[i] = 0;
+
+ init_control.control_gfn = virt_to_mfn(control_block);
+ init_control.offset = 0;
+ init_control.vcpu = cpu;
+
+ return HYPERVISOR_event_channel_op(EVTCHNOP_init_control, &init_control);
+}
+
static void free_unused_array_pages(void)
{
unsigned i;
@@ -324,7 +342,6 @@ static void evtchn_fifo_resume(void)
for_each_possible_cpu(cpu) {
void *control_block = per_cpu(cpu_control_block, cpu);
- struct evtchn_init_control init_control;
int ret;
if (!control_block)
@@ -341,12 +358,7 @@ static void evtchn_fifo_resume(void)
continue;
}
- init_control.control_gfn = virt_to_mfn(control_block);
- init_control.offset = 0;
- init_control.vcpu = cpu;
-
- ret = HYPERVISOR_event_channel_op(EVTCHNOP_init_control,
- &init_control);
+ ret = init_control_block(cpu, control_block);
if (ret < 0)
BUG();
}
@@ -376,28 +388,23 @@ static const struct evtchn_ops evtchn_ops_fifo = {
static int evtchn_fifo_init_control_block(unsigned cpu)
{
- struct page *control_block = NULL;
- struct evtchn_init_control init_control;
+ void *control_block = NULL;
int ret = -ENOMEM;
- control_block = alloc_page(GFP_KERNEL|__GFP_ZERO);
+ control_block = (void *)__get_free_page(GFP_KERNEL);
if (control_block == NULL)
goto error;
- init_control.control_gfn = virt_to_mfn(page_address(control_block));
- init_control.offset = 0;
- init_control.vcpu = cpu;
-
- ret = HYPERVISOR_event_channel_op(EVTCHNOP_init_control, &init_control);
+ ret = init_control_block(cpu, control_block);
if (ret < 0)
goto error;
- per_cpu(cpu_control_block, cpu) = page_address(control_block);
+ per_cpu(cpu_control_block, cpu) = control_block;
return 0;
error:
- __free_page(control_block);
+ free_page((unsigned long)control_block);
return ret;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 2/3] xen/events/fifo: ensure all bitops are properly aligned even on x86
[not found] <1406820146-1616-1-git-send-email-david.vrabel@citrix.com>
2014-07-31 15:22 ` [PATCH 1/3] xen/events/fifo: reset control block and local HEADs on resume David Vrabel
@ 2014-07-31 15:22 ` David Vrabel
2014-07-31 15:22 ` [PATCH 3/3] xen/events/fifo: remove a unecessary use of BM() David Vrabel
2 siblings, 0 replies; 3+ messages in thread
From: David Vrabel @ 2014-07-31 15:22 UTC (permalink / raw)
To: xen-devel; +Cc: Boris Ostrovsky, David Vrabel, stable
When using the FIFO-based ABI on x86_64, if the last port is at the
end of an event array page then sync_test_bit() on this port's event
word will read beyond the end of the page and in certain circumstances
this may fault.
The fault requires the following page in the kernel's direct mapping
to be not present, which would mean:
a) the array page is the last page of RAM; or
b) the following page is ballooned out /and/ it has been used for a
foreign mapping by a kernel driver (such as netback or blkback)
/and/ the grant has been unmapped.
Use the infrastructure added for arm64 to ensure that all bitops
operating on event words are unsigned long aligned.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Cc: stable@vger.kernel.org
---
drivers/xen/events/events_fifo.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index 7dc0a7c..b8de5d3 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -67,10 +67,9 @@ static event_word_t *event_array[MAX_EVENT_ARRAY_PAGES] __read_mostly;
static unsigned event_array_pages __read_mostly;
/*
- * sync_set_bit() and friends must be unsigned long aligned on non-x86
- * platforms.
+ * sync_set_bit() and friends must be unsigned long aligned.
*/
-#if !defined(CONFIG_X86) && BITS_PER_LONG > 32
+#if BITS_PER_LONG > 32
#define BM(w) (unsigned long *)((unsigned long)w & ~0x7UL)
#define EVTCHN_FIFO_BIT(b, w) \
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 3/3] xen/events/fifo: remove a unecessary use of BM()
[not found] <1406820146-1616-1-git-send-email-david.vrabel@citrix.com>
2014-07-31 15:22 ` [PATCH 1/3] xen/events/fifo: reset control block and local HEADs on resume David Vrabel
2014-07-31 15:22 ` [PATCH 2/3] xen/events/fifo: ensure all bitops are properly aligned even on x86 David Vrabel
@ 2014-07-31 15:22 ` David Vrabel
2 siblings, 0 replies; 3+ messages in thread
From: David Vrabel @ 2014-07-31 15:22 UTC (permalink / raw)
To: xen-devel; +Cc: Boris Ostrovsky, David Vrabel, Frediano Ziglio
From: Frediano Ziglio <frediano.ziglio@citrix.com>
Since 05a812ac474d0d6aef6d54b66bb08b81abde79c6 (xen/events/fifo:
correctly align bitops), ready is an unsigned long instead of uint32_t
and the BM() macro is no longer required.
Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
drivers/xen/events/events_fifo.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index b8de5d3..5c63795 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -329,7 +329,7 @@ static void evtchn_fifo_handle_events(unsigned cpu)
ready = xchg(&control_block->ready, 0);
while (ready) {
- q = find_first_bit(BM(&ready), EVTCHN_FIFO_MAX_QUEUES);
+ q = find_first_bit(&ready, EVTCHN_FIFO_MAX_QUEUES);
consume_one_event(cpu, control_block, q, &ready);
ready |= xchg(&control_block->ready, 0);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread