diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-21 19:38:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-21 19:38:33 -0400 |
commit | d936d2d452ca1848cc4b397bdfb96d4278b9f934 (patch) | |
tree | 205a6d386d363d94208a3340f911009d74d2aa29 | |
parent | 0903391acbc1b509a60a6cb682344c748a69821a (diff) | |
parent | fc78d343fa74514f6fd117b5ef4cd27e4ac30236 (diff) |
Merge tag 'stable/for-linus-3.11-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull Xen bug-fixes from Konrad Rzeszutek Wilk:
- On ARM did not have balanced calls to get/put_cpu.
- Fix to make tboot + Xen + Linux correctly.
- Fix events VCPU binding issues.
- Fix a vCPU online race where IPIs are sent to not-yet-online vCPU.
* tag 'stable/for-linus-3.11-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
xen/smp: initialize IPI vectors before marking CPU online
xen/events: mask events when changing their VCPU binding
xen/events: initialize local per-cpu mask for all possible events
x86/xen: do not identity map UNUSABLE regions in the machine E820
xen/arm: missing put_cpu in xen_percpu_init
-rw-r--r-- | arch/arm/xen/enlighten.c | 1 | ||||
-rw-r--r-- | arch/x86/xen/setup.c | 22 | ||||
-rw-r--r-- | arch/x86/xen/smp.c | 11 | ||||
-rw-r--r-- | drivers/xen/events.c | 13 |
4 files changed, 44 insertions, 3 deletions
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index c9770ba5c7df..8a6295c86209 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c | |||
@@ -170,6 +170,7 @@ static void __init xen_percpu_init(void *unused) | |||
170 | per_cpu(xen_vcpu, cpu) = vcpup; | 170 | per_cpu(xen_vcpu, cpu) = vcpup; |
171 | 171 | ||
172 | enable_percpu_irq(xen_events_irq, 0); | 172 | enable_percpu_irq(xen_events_irq, 0); |
173 | put_cpu(); | ||
173 | } | 174 | } |
174 | 175 | ||
175 | static void xen_restart(enum reboot_mode reboot_mode, const char *cmd) | 176 | static void xen_restart(enum reboot_mode reboot_mode, const char *cmd) |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 056d11faef21..8f3eea6b80c5 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -313,6 +313,17 @@ static void xen_align_and_add_e820_region(u64 start, u64 size, int type) | |||
313 | e820_add_region(start, end - start, type); | 313 | e820_add_region(start, end - start, type); |
314 | } | 314 | } |
315 | 315 | ||
316 | void xen_ignore_unusable(struct e820entry *list, size_t map_size) | ||
317 | { | ||
318 | struct e820entry *entry; | ||
319 | unsigned int i; | ||
320 | |||
321 | for (i = 0, entry = list; i < map_size; i++, entry++) { | ||
322 | if (entry->type == E820_UNUSABLE) | ||
323 | entry->type = E820_RAM; | ||
324 | } | ||
325 | } | ||
326 | |||
316 | /** | 327 | /** |
317 | * machine_specific_memory_setup - Hook for machine specific memory setup. | 328 | * machine_specific_memory_setup - Hook for machine specific memory setup. |
318 | **/ | 329 | **/ |
@@ -353,6 +364,17 @@ char * __init xen_memory_setup(void) | |||
353 | } | 364 | } |
354 | BUG_ON(rc); | 365 | BUG_ON(rc); |
355 | 366 | ||
367 | /* | ||
368 | * Xen won't allow a 1:1 mapping to be created to UNUSABLE | ||
369 | * regions, so if we're using the machine memory map leave the | ||
370 | * region as RAM as it is in the pseudo-physical map. | ||
371 | * | ||
372 | * UNUSABLE regions in domUs are not handled and will need | ||
373 | * a patch in the future. | ||
374 | */ | ||
375 | if (xen_initial_domain()) | ||
376 | xen_ignore_unusable(map, memmap.nr_entries); | ||
377 | |||
356 | /* Make sure the Xen-supplied memory map is well-ordered. */ | 378 | /* Make sure the Xen-supplied memory map is well-ordered. */ |
357 | sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries); | 379 | sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries); |
358 | 380 | ||
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index ca92754eb846..b81c88e51daa 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -694,8 +694,15 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) | |||
694 | static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) | 694 | static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) |
695 | { | 695 | { |
696 | int rc; | 696 | int rc; |
697 | rc = native_cpu_up(cpu, tidle); | 697 | /* |
698 | WARN_ON (xen_smp_intr_init(cpu)); | 698 | * xen_smp_intr_init() needs to run before native_cpu_up() |
699 | * so that IPI vectors are set up on the booting CPU before | ||
700 | * it is marked online in native_cpu_up(). | ||
701 | */ | ||
702 | rc = xen_smp_intr_init(cpu); | ||
703 | WARN_ON(rc); | ||
704 | if (!rc) | ||
705 | rc = native_cpu_up(cpu, tidle); | ||
699 | return rc; | 706 | return rc; |
700 | } | 707 | } |
701 | 708 | ||
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index a58ac435a9a4..5e8be462aed5 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -348,7 +348,7 @@ static void init_evtchn_cpu_bindings(void) | |||
348 | 348 | ||
349 | for_each_possible_cpu(i) | 349 | for_each_possible_cpu(i) |
350 | memset(per_cpu(cpu_evtchn_mask, i), | 350 | memset(per_cpu(cpu_evtchn_mask, i), |
351 | (i == 0) ? ~0 : 0, sizeof(*per_cpu(cpu_evtchn_mask, i))); | 351 | (i == 0) ? ~0 : 0, NR_EVENT_CHANNELS/8); |
352 | } | 352 | } |
353 | 353 | ||
354 | static inline void clear_evtchn(int port) | 354 | static inline void clear_evtchn(int port) |
@@ -1493,8 +1493,10 @@ void rebind_evtchn_irq(int evtchn, int irq) | |||
1493 | /* Rebind an evtchn so that it gets delivered to a specific cpu */ | 1493 | /* Rebind an evtchn so that it gets delivered to a specific cpu */ |
1494 | static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) | 1494 | static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) |
1495 | { | 1495 | { |
1496 | struct shared_info *s = HYPERVISOR_shared_info; | ||
1496 | struct evtchn_bind_vcpu bind_vcpu; | 1497 | struct evtchn_bind_vcpu bind_vcpu; |
1497 | int evtchn = evtchn_from_irq(irq); | 1498 | int evtchn = evtchn_from_irq(irq); |
1499 | int masked; | ||
1498 | 1500 | ||
1499 | if (!VALID_EVTCHN(evtchn)) | 1501 | if (!VALID_EVTCHN(evtchn)) |
1500 | return -1; | 1502 | return -1; |
@@ -1511,6 +1513,12 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) | |||
1511 | bind_vcpu.vcpu = tcpu; | 1513 | bind_vcpu.vcpu = tcpu; |
1512 | 1514 | ||
1513 | /* | 1515 | /* |
1516 | * Mask the event while changing the VCPU binding to prevent | ||
1517 | * it being delivered on an unexpected VCPU. | ||
1518 | */ | ||
1519 | masked = sync_test_and_set_bit(evtchn, BM(s->evtchn_mask)); | ||
1520 | |||
1521 | /* | ||
1514 | * If this fails, it usually just indicates that we're dealing with a | 1522 | * If this fails, it usually just indicates that we're dealing with a |
1515 | * virq or IPI channel, which don't actually need to be rebound. Ignore | 1523 | * virq or IPI channel, which don't actually need to be rebound. Ignore |
1516 | * it, but don't do the xenlinux-level rebind in that case. | 1524 | * it, but don't do the xenlinux-level rebind in that case. |
@@ -1518,6 +1526,9 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) | |||
1518 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) | 1526 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) |
1519 | bind_evtchn_to_cpu(evtchn, tcpu); | 1527 | bind_evtchn_to_cpu(evtchn, tcpu); |
1520 | 1528 | ||
1529 | if (!masked) | ||
1530 | unmask_evtchn(evtchn); | ||
1531 | |||
1521 | return 0; | 1532 | return 0; |
1522 | } | 1533 | } |
1523 | 1534 | ||