aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-01-13 14:07:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-01-13 14:07:42 -0500
commit613d4cefbbb39d3c37f3f22150263900ba11a3e3 (patch)
tree67cc99542c8e87849eca9a825d1bb217330b9411 /arch/x86/xen
parent4f7a42deff8b406d091c989f2587d97889adfd60 (diff)
parentf221b04fe07eb56c39935e31bb8e9ddacc00612f (diff)
Merge tag 'stable/for-linus-3.19-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen bug fixes from David Vrabel: "Several critical linear p2m fixes that prevented some hosts from booting" * tag 'stable/for-linus-3.19-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: x86/xen: properly retrieve NMI reason xen: check for zero sized area when invalidating memory xen: use correct type for physical addresses xen: correct race in alloc_p2m_pmd() xen: correct error for building p2m list on 32 bits x86/xen: avoid freeing static 'name' when kasprintf() fails x86/xen: add extra memory for remapped frames during setup x86/xen: don't count how many PFNs are identity mapped x86/xen: Free bootmem in free_p2m_page() during early boot x86/xen: Remove unnecessary BUG_ON(preemptible()) in xen_setup_timer()
Diffstat (limited to 'arch/x86/xen')
-rw-r--r--arch/x86/xen/enlighten.c22
-rw-r--r--arch/x86/xen/p2m.c20
-rw-r--r--arch/x86/xen/setup.c42
-rw-r--r--arch/x86/xen/time.c18
4 files changed, 56 insertions, 46 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 6bf3a13e3e0f..78a881b7fc41 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -40,6 +40,7 @@
40#include <xen/interface/physdev.h> 40#include <xen/interface/physdev.h>
41#include <xen/interface/vcpu.h> 41#include <xen/interface/vcpu.h>
42#include <xen/interface/memory.h> 42#include <xen/interface/memory.h>
43#include <xen/interface/nmi.h>
43#include <xen/interface/xen-mca.h> 44#include <xen/interface/xen-mca.h>
44#include <xen/features.h> 45#include <xen/features.h>
45#include <xen/page.h> 46#include <xen/page.h>
@@ -66,6 +67,7 @@
66#include <asm/reboot.h> 67#include <asm/reboot.h>
67#include <asm/stackprotector.h> 68#include <asm/stackprotector.h>
68#include <asm/hypervisor.h> 69#include <asm/hypervisor.h>
70#include <asm/mach_traps.h>
69#include <asm/mwait.h> 71#include <asm/mwait.h>
70#include <asm/pci_x86.h> 72#include <asm/pci_x86.h>
71#include <asm/pat.h> 73#include <asm/pat.h>
@@ -1351,6 +1353,21 @@ static const struct machine_ops xen_machine_ops __initconst = {
1351 .emergency_restart = xen_emergency_restart, 1353 .emergency_restart = xen_emergency_restart,
1352}; 1354};
1353 1355
1356static unsigned char xen_get_nmi_reason(void)
1357{
1358 unsigned char reason = 0;
1359
1360 /* Construct a value which looks like it came from port 0x61. */
1361 if (test_bit(_XEN_NMIREASON_io_error,
1362 &HYPERVISOR_shared_info->arch.nmi_reason))
1363 reason |= NMI_REASON_IOCHK;
1364 if (test_bit(_XEN_NMIREASON_pci_serr,
1365 &HYPERVISOR_shared_info->arch.nmi_reason))
1366 reason |= NMI_REASON_SERR;
1367
1368 return reason;
1369}
1370
1354static void __init xen_boot_params_init_edd(void) 1371static void __init xen_boot_params_init_edd(void)
1355{ 1372{
1356#if IS_ENABLED(CONFIG_EDD) 1373#if IS_ENABLED(CONFIG_EDD)
@@ -1535,9 +1552,12 @@ asmlinkage __visible void __init xen_start_kernel(void)
1535 pv_info = xen_info; 1552 pv_info = xen_info;
1536 pv_init_ops = xen_init_ops; 1553 pv_init_ops = xen_init_ops;
1537 pv_apic_ops = xen_apic_ops; 1554 pv_apic_ops = xen_apic_ops;
1538 if (!xen_pvh_domain()) 1555 if (!xen_pvh_domain()) {
1539 pv_cpu_ops = xen_cpu_ops; 1556 pv_cpu_ops = xen_cpu_ops;
1540 1557
1558 x86_platform.get_nmi_reason = xen_get_nmi_reason;
1559 }
1560
1541 if (xen_feature(XENFEAT_auto_translated_physmap)) 1561 if (xen_feature(XENFEAT_auto_translated_physmap))
1542 x86_init.resources.memory_setup = xen_auto_xlated_memory_setup; 1562 x86_init.resources.memory_setup = xen_auto_xlated_memory_setup;
1543 else 1563 else
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index edbc7a63fd73..70fb5075c901 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -167,10 +167,13 @@ static void * __ref alloc_p2m_page(void)
167 return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT); 167 return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT);
168} 168}
169 169
170/* Only to be called in case of a race for a page just allocated! */ 170static void __ref free_p2m_page(void *p)
171static void free_p2m_page(void *p)
172{ 171{
173 BUG_ON(!slab_is_available()); 172 if (unlikely(!slab_is_available())) {
173 free_bootmem((unsigned long)p, PAGE_SIZE);
174 return;
175 }
176
174 free_page((unsigned long)p); 177 free_page((unsigned long)p);
175} 178}
176 179
@@ -375,7 +378,7 @@ static void __init xen_rebuild_p2m_list(unsigned long *p2m)
375 p2m_missing_pte : p2m_identity_pte; 378 p2m_missing_pte : p2m_identity_pte;
376 for (i = 0; i < PMDS_PER_MID_PAGE; i++) { 379 for (i = 0; i < PMDS_PER_MID_PAGE; i++) {
377 pmdp = populate_extra_pmd( 380 pmdp = populate_extra_pmd(
378 (unsigned long)(p2m + pfn + i * PTRS_PER_PTE)); 381 (unsigned long)(p2m + pfn) + i * PMD_SIZE);
379 set_pmd(pmdp, __pmd(__pa(ptep) | _KERNPG_TABLE)); 382 set_pmd(pmdp, __pmd(__pa(ptep) | _KERNPG_TABLE));
380 } 383 }
381 } 384 }
@@ -436,10 +439,9 @@ EXPORT_SYMBOL_GPL(get_phys_to_machine);
436 * a new pmd is to replace p2m_missing_pte or p2m_identity_pte by a individual 439 * a new pmd is to replace p2m_missing_pte or p2m_identity_pte by a individual
437 * pmd. In case of PAE/x86-32 there are multiple pmds to allocate! 440 * pmd. In case of PAE/x86-32 there are multiple pmds to allocate!
438 */ 441 */
439static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg) 442static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
440{ 443{
441 pte_t *ptechk; 444 pte_t *ptechk;
442 pte_t *pteret = ptep;
443 pte_t *pte_newpg[PMDS_PER_MID_PAGE]; 445 pte_t *pte_newpg[PMDS_PER_MID_PAGE];
444 pmd_t *pmdp; 446 pmd_t *pmdp;
445 unsigned int level; 447 unsigned int level;
@@ -473,8 +475,6 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg)
473 if (ptechk == pte_pg) { 475 if (ptechk == pte_pg) {
474 set_pmd(pmdp, 476 set_pmd(pmdp,
475 __pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE)); 477 __pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE));
476 if (vaddr == (addr & ~(PMD_SIZE - 1)))
477 pteret = pte_offset_kernel(pmdp, addr);
478 pte_newpg[i] = NULL; 478 pte_newpg[i] = NULL;
479 } 479 }
480 480
@@ -488,7 +488,7 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg)
488 vaddr += PMD_SIZE; 488 vaddr += PMD_SIZE;
489 } 489 }
490 490
491 return pteret; 491 return lookup_address(addr, &level);
492} 492}
493 493
494/* 494/*
@@ -517,7 +517,7 @@ static bool alloc_p2m(unsigned long pfn)
517 517
518 if (pte_pg == p2m_missing_pte || pte_pg == p2m_identity_pte) { 518 if (pte_pg == p2m_missing_pte || pte_pg == p2m_identity_pte) {
519 /* PMD level is missing, allocate a new one */ 519 /* PMD level is missing, allocate a new one */
520 ptep = alloc_p2m_pmd(addr, ptep, pte_pg); 520 ptep = alloc_p2m_pmd(addr, pte_pg);
521 if (!ptep) 521 if (!ptep)
522 return false; 522 return false;
523 } 523 }
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index dfd77dec8e2b..865e56cea7a0 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -140,7 +140,7 @@ static void __init xen_del_extra_mem(u64 start, u64 size)
140unsigned long __ref xen_chk_extra_mem(unsigned long pfn) 140unsigned long __ref xen_chk_extra_mem(unsigned long pfn)
141{ 141{
142 int i; 142 int i;
143 unsigned long addr = PFN_PHYS(pfn); 143 phys_addr_t addr = PFN_PHYS(pfn);
144 144
145 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { 145 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
146 if (addr >= xen_extra_mem[i].start && 146 if (addr >= xen_extra_mem[i].start &&
@@ -160,6 +160,8 @@ void __init xen_inv_extra_mem(void)
160 int i; 160 int i;
161 161
162 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { 162 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
163 if (!xen_extra_mem[i].size)
164 continue;
163 pfn_s = PFN_DOWN(xen_extra_mem[i].start); 165 pfn_s = PFN_DOWN(xen_extra_mem[i].start);
164 pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size); 166 pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size);
165 for (pfn = pfn_s; pfn < pfn_e; pfn++) 167 for (pfn = pfn_s; pfn < pfn_e; pfn++)
@@ -229,15 +231,14 @@ static int __init xen_free_mfn(unsigned long mfn)
229 * as a fallback if the remapping fails. 231 * as a fallback if the remapping fails.
230 */ 232 */
231static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn, 233static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
232 unsigned long end_pfn, unsigned long nr_pages, unsigned long *identity, 234 unsigned long end_pfn, unsigned long nr_pages, unsigned long *released)
233 unsigned long *released)
234{ 235{
235 unsigned long len = 0;
236 unsigned long pfn, end; 236 unsigned long pfn, end;
237 int ret; 237 int ret;
238 238
239 WARN_ON(start_pfn > end_pfn); 239 WARN_ON(start_pfn > end_pfn);
240 240
241 /* Release pages first. */
241 end = min(end_pfn, nr_pages); 242 end = min(end_pfn, nr_pages);
242 for (pfn = start_pfn; pfn < end; pfn++) { 243 for (pfn = start_pfn; pfn < end; pfn++) {
243 unsigned long mfn = pfn_to_mfn(pfn); 244 unsigned long mfn = pfn_to_mfn(pfn);
@@ -250,16 +251,14 @@ static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
250 WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret); 251 WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret);
251 252
252 if (ret == 1) { 253 if (ret == 1) {
254 (*released)++;
253 if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY)) 255 if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY))
254 break; 256 break;
255 len++;
256 } else 257 } else
257 break; 258 break;
258 } 259 }
259 260
260 /* Need to release pages first */ 261 set_phys_range_identity(start_pfn, end_pfn);
261 *released += len;
262 *identity += set_phys_range_identity(start_pfn, end_pfn);
263} 262}
264 263
265/* 264/*
@@ -287,7 +286,7 @@ static void __init xen_update_mem_tables(unsigned long pfn, unsigned long mfn)
287 } 286 }
288 287
289 /* Update kernel mapping, but not for highmem. */ 288 /* Update kernel mapping, but not for highmem. */
290 if ((pfn << PAGE_SHIFT) >= __pa(high_memory)) 289 if (pfn >= PFN_UP(__pa(high_memory - 1)))
291 return; 290 return;
292 291
293 if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT), 292 if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT),
@@ -318,7 +317,6 @@ static void __init xen_do_set_identity_and_remap_chunk(
318 unsigned long ident_pfn_iter, remap_pfn_iter; 317 unsigned long ident_pfn_iter, remap_pfn_iter;
319 unsigned long ident_end_pfn = start_pfn + size; 318 unsigned long ident_end_pfn = start_pfn + size;
320 unsigned long left = size; 319 unsigned long left = size;
321 unsigned long ident_cnt = 0;
322 unsigned int i, chunk; 320 unsigned int i, chunk;
323 321
324 WARN_ON(size == 0); 322 WARN_ON(size == 0);
@@ -347,8 +345,7 @@ static void __init xen_do_set_identity_and_remap_chunk(
347 xen_remap_mfn = mfn; 345 xen_remap_mfn = mfn;
348 346
349 /* Set identity map */ 347 /* Set identity map */
350 ident_cnt += set_phys_range_identity(ident_pfn_iter, 348 set_phys_range_identity(ident_pfn_iter, ident_pfn_iter + chunk);
351 ident_pfn_iter + chunk);
352 349
353 left -= chunk; 350 left -= chunk;
354 } 351 }
@@ -371,7 +368,7 @@ static void __init xen_do_set_identity_and_remap_chunk(
371static unsigned long __init xen_set_identity_and_remap_chunk( 368static unsigned long __init xen_set_identity_and_remap_chunk(
372 const struct e820entry *list, size_t map_size, unsigned long start_pfn, 369 const struct e820entry *list, size_t map_size, unsigned long start_pfn,
373 unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn, 370 unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn,
374 unsigned long *identity, unsigned long *released) 371 unsigned long *released, unsigned long *remapped)
375{ 372{
376 unsigned long pfn; 373 unsigned long pfn;
377 unsigned long i = 0; 374 unsigned long i = 0;
@@ -386,8 +383,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
386 /* Do not remap pages beyond the current allocation */ 383 /* Do not remap pages beyond the current allocation */
387 if (cur_pfn >= nr_pages) { 384 if (cur_pfn >= nr_pages) {
388 /* Identity map remaining pages */ 385 /* Identity map remaining pages */
389 *identity += set_phys_range_identity(cur_pfn, 386 set_phys_range_identity(cur_pfn, cur_pfn + size);
390 cur_pfn + size);
391 break; 387 break;
392 } 388 }
393 if (cur_pfn + size > nr_pages) 389 if (cur_pfn + size > nr_pages)
@@ -398,7 +394,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
398 if (!remap_range_size) { 394 if (!remap_range_size) {
399 pr_warning("Unable to find available pfn range, not remapping identity pages\n"); 395 pr_warning("Unable to find available pfn range, not remapping identity pages\n");
400 xen_set_identity_and_release_chunk(cur_pfn, 396 xen_set_identity_and_release_chunk(cur_pfn,
401 cur_pfn + left, nr_pages, identity, released); 397 cur_pfn + left, nr_pages, released);
402 break; 398 break;
403 } 399 }
404 /* Adjust size to fit in current e820 RAM region */ 400 /* Adjust size to fit in current e820 RAM region */
@@ -410,7 +406,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
410 /* Update variables to reflect new mappings. */ 406 /* Update variables to reflect new mappings. */
411 i += size; 407 i += size;
412 remap_pfn += size; 408 remap_pfn += size;
413 *identity += size; 409 *remapped += size;
414 } 410 }
415 411
416 /* 412 /*
@@ -427,13 +423,13 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
427 423
428static void __init xen_set_identity_and_remap( 424static void __init xen_set_identity_and_remap(
429 const struct e820entry *list, size_t map_size, unsigned long nr_pages, 425 const struct e820entry *list, size_t map_size, unsigned long nr_pages,
430 unsigned long *released) 426 unsigned long *released, unsigned long *remapped)
431{ 427{
432 phys_addr_t start = 0; 428 phys_addr_t start = 0;
433 unsigned long identity = 0;
434 unsigned long last_pfn = nr_pages; 429 unsigned long last_pfn = nr_pages;
435 const struct e820entry *entry; 430 const struct e820entry *entry;
436 unsigned long num_released = 0; 431 unsigned long num_released = 0;
432 unsigned long num_remapped = 0;
437 int i; 433 int i;
438 434
439 /* 435 /*
@@ -460,14 +456,14 @@ static void __init xen_set_identity_and_remap(
460 last_pfn = xen_set_identity_and_remap_chunk( 456 last_pfn = xen_set_identity_and_remap_chunk(
461 list, map_size, start_pfn, 457 list, map_size, start_pfn,
462 end_pfn, nr_pages, last_pfn, 458 end_pfn, nr_pages, last_pfn,
463 &identity, &num_released); 459 &num_released, &num_remapped);
464 start = end; 460 start = end;
465 } 461 }
466 } 462 }
467 463
468 *released = num_released; 464 *released = num_released;
465 *remapped = num_remapped;
469 466
470 pr_info("Set %ld page(s) to 1-1 mapping\n", identity);
471 pr_info("Released %ld page(s)\n", num_released); 467 pr_info("Released %ld page(s)\n", num_released);
472} 468}
473 469
@@ -586,6 +582,7 @@ char * __init xen_memory_setup(void)
586 struct xen_memory_map memmap; 582 struct xen_memory_map memmap;
587 unsigned long max_pages; 583 unsigned long max_pages;
588 unsigned long extra_pages = 0; 584 unsigned long extra_pages = 0;
585 unsigned long remapped_pages;
589 int i; 586 int i;
590 int op; 587 int op;
591 588
@@ -635,9 +632,10 @@ char * __init xen_memory_setup(void)
635 * underlying RAM. 632 * underlying RAM.
636 */ 633 */
637 xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn, 634 xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn,
638 &xen_released_pages); 635 &xen_released_pages, &remapped_pages);
639 636
640 extra_pages += xen_released_pages; 637 extra_pages += xen_released_pages;
638 extra_pages += remapped_pages;
641 639
642 /* 640 /*
643 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO 641 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index f473d268d387..69087341d9ae 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -391,7 +391,7 @@ static const struct clock_event_device *xen_clockevent =
391 391
392struct xen_clock_event_device { 392struct xen_clock_event_device {
393 struct clock_event_device evt; 393 struct clock_event_device evt;
394 char *name; 394 char name[16];
395}; 395};
396static DEFINE_PER_CPU(struct xen_clock_event_device, xen_clock_events) = { .evt.irq = -1 }; 396static DEFINE_PER_CPU(struct xen_clock_event_device, xen_clock_events) = { .evt.irq = -1 };
397 397
@@ -420,46 +420,38 @@ void xen_teardown_timer(int cpu)
420 if (evt->irq >= 0) { 420 if (evt->irq >= 0) {
421 unbind_from_irqhandler(evt->irq, NULL); 421 unbind_from_irqhandler(evt->irq, NULL);
422 evt->irq = -1; 422 evt->irq = -1;
423 kfree(per_cpu(xen_clock_events, cpu).name);
424 per_cpu(xen_clock_events, cpu).name = NULL;
425 } 423 }
426} 424}
427 425
428void xen_setup_timer(int cpu) 426void xen_setup_timer(int cpu)
429{ 427{
430 char *name; 428 struct xen_clock_event_device *xevt = &per_cpu(xen_clock_events, cpu);
431 struct clock_event_device *evt; 429 struct clock_event_device *evt = &xevt->evt;
432 int irq; 430 int irq;
433 431
434 evt = &per_cpu(xen_clock_events, cpu).evt;
435 WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu); 432 WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu);
436 if (evt->irq >= 0) 433 if (evt->irq >= 0)
437 xen_teardown_timer(cpu); 434 xen_teardown_timer(cpu);
438 435
439 printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); 436 printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu);
440 437
441 name = kasprintf(GFP_KERNEL, "timer%d", cpu); 438 snprintf(xevt->name, sizeof(xevt->name), "timer%d", cpu);
442 if (!name)
443 name = "<timer kasprintf failed>";
444 439
445 irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt, 440 irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
446 IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER| 441 IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER|
447 IRQF_FORCE_RESUME|IRQF_EARLY_RESUME, 442 IRQF_FORCE_RESUME|IRQF_EARLY_RESUME,
448 name, NULL); 443 xevt->name, NULL);
449 (void)xen_set_irq_priority(irq, XEN_IRQ_PRIORITY_MAX); 444 (void)xen_set_irq_priority(irq, XEN_IRQ_PRIORITY_MAX);
450 445
451 memcpy(evt, xen_clockevent, sizeof(*evt)); 446 memcpy(evt, xen_clockevent, sizeof(*evt));
452 447
453 evt->cpumask = cpumask_of(cpu); 448 evt->cpumask = cpumask_of(cpu);
454 evt->irq = irq; 449 evt->irq = irq;
455 per_cpu(xen_clock_events, cpu).name = name;
456} 450}
457 451
458 452
459void xen_setup_cpu_clockevents(void) 453void xen_setup_cpu_clockevents(void)
460{ 454{
461 BUG_ON(preemptible());
462
463 clockevents_register_device(this_cpu_ptr(&xen_clock_events.evt)); 455 clockevents_register_device(this_cpu_ptr(&xen_clock_events.evt));
464} 456}
465 457