aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/Makefile4
-rw-r--r--arch/x86/kernel/ldt.c9
-rw-r--r--arch/x86/kernel/paravirt-spinlocks.c31
-rw-r--r--arch/x86/kernel/paravirt.c27
-rw-r--r--arch/x86/xen/Makefile11
-rw-r--r--arch/x86/xen/enlighten.c173
-rw-r--r--arch/x86/xen/irq.c143
-rw-r--r--arch/x86/xen/smp.c167
-rw-r--r--arch/x86/xen/spinlock.c183
-rw-r--r--arch/x86/xen/xen-asm_32.S2
-rw-r--r--arch/x86/xen/xen-asm_64.S2
-rw-r--r--arch/x86/xen/xen-ops.h4
-rw-r--r--drivers/xen/balloon.c174
-rw-r--r--drivers/xen/events.c11
-rw-r--r--include/asm-x86/desc.h15
-rw-r--r--include/asm-x86/paravirt.h13
-rw-r--r--include/linux/kernel.h2
-rw-r--r--lib/cmdline.c2
18 files changed, 491 insertions, 482 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 3db651fc8ec5..d679cb2c79b4 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -10,7 +10,7 @@ ifdef CONFIG_FTRACE
10# Do not profile debug and lowlevel utilities 10# Do not profile debug and lowlevel utilities
11CFLAGS_REMOVE_tsc.o = -pg 11CFLAGS_REMOVE_tsc.o = -pg
12CFLAGS_REMOVE_rtc.o = -pg 12CFLAGS_REMOVE_rtc.o = -pg
13CFLAGS_REMOVE_paravirt.o = -pg 13CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
14endif 14endif
15 15
16# 16#
@@ -89,7 +89,7 @@ obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o
89obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o 89obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o
90obj-$(CONFIG_KVM_GUEST) += kvm.o 90obj-$(CONFIG_KVM_GUEST) += kvm.o
91obj-$(CONFIG_KVM_CLOCK) += kvmclock.o 91obj-$(CONFIG_KVM_CLOCK) += kvmclock.o
92obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o 92obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o paravirt-spinlocks.o
93obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o 93obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o
94 94
95obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o 95obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index b68e21f06f4f..6e388412a854 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -51,6 +51,8 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
51 memset(newldt + oldsize * LDT_ENTRY_SIZE, 0, 51 memset(newldt + oldsize * LDT_ENTRY_SIZE, 0,
52 (mincount - oldsize) * LDT_ENTRY_SIZE); 52 (mincount - oldsize) * LDT_ENTRY_SIZE);
53 53
54 paravirt_alloc_ldt(newldt, mincount);
55
54#ifdef CONFIG_X86_64 56#ifdef CONFIG_X86_64
55 /* CHECKME: Do we really need this ? */ 57 /* CHECKME: Do we really need this ? */
56 wmb(); 58 wmb();
@@ -73,6 +75,7 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
73#endif 75#endif
74 } 76 }
75 if (oldsize) { 77 if (oldsize) {
78 paravirt_free_ldt(oldldt, oldsize);
76 if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE) 79 if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE)
77 vfree(oldldt); 80 vfree(oldldt);
78 else 81 else
@@ -84,10 +87,13 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
84static inline int copy_ldt(mm_context_t *new, mm_context_t *old) 87static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
85{ 88{
86 int err = alloc_ldt(new, old->size, 0); 89 int err = alloc_ldt(new, old->size, 0);
90 int i;
87 91
88 if (err < 0) 92 if (err < 0)
89 return err; 93 return err;
90 memcpy(new->ldt, old->ldt, old->size * LDT_ENTRY_SIZE); 94
95 for(i = 0; i < old->size; i++)
96 write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
91 return 0; 97 return 0;
92} 98}
93 99
@@ -124,6 +130,7 @@ void destroy_context(struct mm_struct *mm)
124 if (mm == current->active_mm) 130 if (mm == current->active_mm)
125 clear_LDT(); 131 clear_LDT();
126#endif 132#endif
133 paravirt_free_ldt(mm->context.ldt, mm->context.size);
127 if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE) 134 if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE)
128 vfree(mm->context.ldt); 135 vfree(mm->context.ldt);
129 else 136 else
diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c
new file mode 100644
index 000000000000..38d7f7f1dbc9
--- /dev/null
+++ b/arch/x86/kernel/paravirt-spinlocks.c
@@ -0,0 +1,31 @@
1/*
2 * Split spinlock implementation out into its own file, so it can be
3 * compiled in a FTRACE-compatible way.
4 */
5#include <linux/spinlock.h>
6#include <linux/module.h>
7
8#include <asm/paravirt.h>
9
10struct pv_lock_ops pv_lock_ops = {
11#ifdef CONFIG_SMP
12 .spin_is_locked = __ticket_spin_is_locked,
13 .spin_is_contended = __ticket_spin_is_contended,
14
15 .spin_lock = __ticket_spin_lock,
16 .spin_trylock = __ticket_spin_trylock,
17 .spin_unlock = __ticket_spin_unlock,
18#endif
19};
20EXPORT_SYMBOL_GPL(pv_lock_ops);
21
22void __init paravirt_use_bytelocks(void)
23{
24#ifdef CONFIG_SMP
25 pv_lock_ops.spin_is_locked = __byte_spin_is_locked;
26 pv_lock_ops.spin_is_contended = __byte_spin_is_contended;
27 pv_lock_ops.spin_lock = __byte_spin_lock;
28 pv_lock_ops.spin_trylock = __byte_spin_trylock;
29 pv_lock_ops.spin_unlock = __byte_spin_unlock;
30#endif
31}
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 94da4d52d798..7faea1817d05 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -268,17 +268,6 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
268 return __get_cpu_var(paravirt_lazy_mode); 268 return __get_cpu_var(paravirt_lazy_mode);
269} 269}
270 270
271void __init paravirt_use_bytelocks(void)
272{
273#ifdef CONFIG_SMP
274 pv_lock_ops.spin_is_locked = __byte_spin_is_locked;
275 pv_lock_ops.spin_is_contended = __byte_spin_is_contended;
276 pv_lock_ops.spin_lock = __byte_spin_lock;
277 pv_lock_ops.spin_trylock = __byte_spin_trylock;
278 pv_lock_ops.spin_unlock = __byte_spin_unlock;
279#endif
280}
281
282struct pv_info pv_info = { 271struct pv_info pv_info = {
283 .name = "bare hardware", 272 .name = "bare hardware",
284 .paravirt_enabled = 0, 273 .paravirt_enabled = 0,
@@ -348,6 +337,10 @@ struct pv_cpu_ops pv_cpu_ops = {
348 .write_ldt_entry = native_write_ldt_entry, 337 .write_ldt_entry = native_write_ldt_entry,
349 .write_gdt_entry = native_write_gdt_entry, 338 .write_gdt_entry = native_write_gdt_entry,
350 .write_idt_entry = native_write_idt_entry, 339 .write_idt_entry = native_write_idt_entry,
340
341 .alloc_ldt = paravirt_nop,
342 .free_ldt = paravirt_nop,
343
351 .load_sp0 = native_load_sp0, 344 .load_sp0 = native_load_sp0,
352 345
353#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) 346#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
@@ -461,18 +454,6 @@ struct pv_mmu_ops pv_mmu_ops = {
461 .set_fixmap = native_set_fixmap, 454 .set_fixmap = native_set_fixmap,
462}; 455};
463 456
464struct pv_lock_ops pv_lock_ops = {
465#ifdef CONFIG_SMP
466 .spin_is_locked = __ticket_spin_is_locked,
467 .spin_is_contended = __ticket_spin_is_contended,
468
469 .spin_lock = __ticket_spin_lock,
470 .spin_trylock = __ticket_spin_trylock,
471 .spin_unlock = __ticket_spin_unlock,
472#endif
473};
474EXPORT_SYMBOL_GPL(pv_lock_ops);
475
476EXPORT_SYMBOL_GPL(pv_time_ops); 457EXPORT_SYMBOL_GPL(pv_time_ops);
477EXPORT_SYMBOL (pv_cpu_ops); 458EXPORT_SYMBOL (pv_cpu_ops);
478EXPORT_SYMBOL (pv_mmu_ops); 459EXPORT_SYMBOL (pv_mmu_ops);
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
index 59c1e539aed2..9ee745fa5527 100644
--- a/arch/x86/xen/Makefile
+++ b/arch/x86/xen/Makefile
@@ -1,4 +1,11 @@
1obj-y := enlighten.o setup.o multicalls.o mmu.o \ 1ifdef CONFIG_FTRACE
2# Do not profile debug and lowlevel utilities
3CFLAGS_REMOVE_spinlock.o = -pg
4CFLAGS_REMOVE_time.o = -pg
5CFLAGS_REMOVE_irq.o = -pg
6endif
7
8obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
2 time.o xen-asm_$(BITS).o grant-table.o suspend.o 9 time.o xen-asm_$(BITS).o grant-table.o suspend.o
3 10
4obj-$(CONFIG_SMP) += smp.o 11obj-$(CONFIG_SMP) += smp.o spinlock.o
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 9ff6e3cbf08f..cf8b3a93122b 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -30,7 +30,6 @@
30#include <xen/interface/xen.h> 30#include <xen/interface/xen.h>
31#include <xen/interface/physdev.h> 31#include <xen/interface/physdev.h>
32#include <xen/interface/vcpu.h> 32#include <xen/interface/vcpu.h>
33#include <xen/interface/sched.h>
34#include <xen/features.h> 33#include <xen/features.h>
35#include <xen/page.h> 34#include <xen/page.h>
36#include <xen/hvc-console.h> 35#include <xen/hvc-console.h>
@@ -226,103 +225,66 @@ static unsigned long xen_get_debugreg(int reg)
226 return HYPERVISOR_get_debugreg(reg); 225 return HYPERVISOR_get_debugreg(reg);
227} 226}
228 227
229static unsigned long xen_save_fl(void) 228static void xen_leave_lazy(void)
230{ 229{
231 struct vcpu_info *vcpu; 230 paravirt_leave_lazy(paravirt_get_lazy_mode());
232 unsigned long flags; 231 xen_mc_flush();
233
234 vcpu = x86_read_percpu(xen_vcpu);
235
236 /* flag has opposite sense of mask */
237 flags = !vcpu->evtchn_upcall_mask;
238
239 /* convert to IF type flag
240 -0 -> 0x00000000
241 -1 -> 0xffffffff
242 */
243 return (-flags) & X86_EFLAGS_IF;
244} 232}
245 233
246static void xen_restore_fl(unsigned long flags) 234static unsigned long xen_store_tr(void)
247{ 235{
248 struct vcpu_info *vcpu; 236 return 0;
249
250 /* convert from IF type flag */
251 flags = !(flags & X86_EFLAGS_IF);
252
253 /* There's a one instruction preempt window here. We need to
254 make sure we're don't switch CPUs between getting the vcpu
255 pointer and updating the mask. */
256 preempt_disable();
257 vcpu = x86_read_percpu(xen_vcpu);
258 vcpu->evtchn_upcall_mask = flags;
259 preempt_enable_no_resched();
260
261 /* Doesn't matter if we get preempted here, because any
262 pending event will get dealt with anyway. */
263
264 if (flags == 0) {
265 preempt_check_resched();
266 barrier(); /* unmask then check (avoid races) */
267 if (unlikely(vcpu->evtchn_upcall_pending))
268 force_evtchn_callback();
269 }
270} 237}
271 238
272static void xen_irq_disable(void) 239/*
240 * If 'v' is a vmalloc mapping, then find the linear mapping of the
241 * page (if any) and also set its protections to match:
242 */
243static void set_aliased_prot(void *v, pgprot_t prot)
273{ 244{
274 /* There's a one instruction preempt window here. We need to 245 int level;
275 make sure we're don't switch CPUs between getting the vcpu 246 pte_t *ptep;
276 pointer and updating the mask. */ 247 pte_t pte;
277 preempt_disable(); 248 unsigned long pfn;
278 x86_read_percpu(xen_vcpu)->evtchn_upcall_mask = 1; 249 struct page *page;
279 preempt_enable_no_resched();
280}
281 250
282static void xen_irq_enable(void) 251 ptep = lookup_address((unsigned long)v, &level);
283{ 252 BUG_ON(ptep == NULL);
284 struct vcpu_info *vcpu;
285 253
286 /* We don't need to worry about being preempted here, since 254 pfn = pte_pfn(*ptep);
287 either a) interrupts are disabled, so no preemption, or b) 255 page = pfn_to_page(pfn);
288 the caller is confused and is trying to re-enable interrupts
289 on an indeterminate processor. */
290 256
291 vcpu = x86_read_percpu(xen_vcpu); 257 pte = pfn_pte(pfn, prot);
292 vcpu->evtchn_upcall_mask = 0;
293 258
294 /* Doesn't matter if we get preempted here, because any 259 if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0))
295 pending event will get dealt with anyway. */ 260 BUG();
296 261
297 barrier(); /* unmask then check (avoid races) */ 262 if (!PageHighMem(page)) {
298 if (unlikely(vcpu->evtchn_upcall_pending)) 263 void *av = __va(PFN_PHYS(pfn));
299 force_evtchn_callback();
300}
301 264
302static void xen_safe_halt(void) 265 if (av != v)
303{ 266 if (HYPERVISOR_update_va_mapping((unsigned long)av, pte, 0))
304 /* Blocking includes an implicit local_irq_enable(). */ 267 BUG();
305 if (HYPERVISOR_sched_op(SCHEDOP_block, NULL) != 0) 268 } else
306 BUG(); 269 kmap_flush_unused();
307} 270}
308 271
309static void xen_halt(void) 272static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries)
310{ 273{
311 if (irqs_disabled()) 274 const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE;
312 HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL); 275 int i;
313 else
314 xen_safe_halt();
315}
316 276
317static void xen_leave_lazy(void) 277 for(i = 0; i < entries; i += entries_per_page)
318{ 278 set_aliased_prot(ldt + i, PAGE_KERNEL_RO);
319 paravirt_leave_lazy(paravirt_get_lazy_mode());
320 xen_mc_flush();
321} 279}
322 280
323static unsigned long xen_store_tr(void) 281static void xen_free_ldt(struct desc_struct *ldt, unsigned entries)
324{ 282{
325 return 0; 283 const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE;
284 int i;
285
286 for(i = 0; i < entries; i += entries_per_page)
287 set_aliased_prot(ldt + i, PAGE_KERNEL);
326} 288}
327 289
328static void xen_set_ldt(const void *addr, unsigned entries) 290static void xen_set_ldt(const void *addr, unsigned entries)
@@ -426,7 +388,7 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
426 const void *ptr) 388 const void *ptr)
427{ 389{
428 unsigned long lp = (unsigned long)&dt[entrynum]; 390 unsigned long lp = (unsigned long)&dt[entrynum];
429 xmaddr_t mach_lp = virt_to_machine(lp); 391 xmaddr_t mach_lp = arbitrary_virt_to_machine(lp);
430 u64 entry = *(u64 *)ptr; 392 u64 entry = *(u64 *)ptr;
431 393
432 preempt_disable(); 394 preempt_disable();
@@ -559,7 +521,7 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry,
559} 521}
560 522
561static void xen_load_sp0(struct tss_struct *tss, 523static void xen_load_sp0(struct tss_struct *tss,
562 struct thread_struct *thread) 524 struct thread_struct *thread)
563{ 525{
564 struct multicall_space mcs = xen_mc_entry(0); 526 struct multicall_space mcs = xen_mc_entry(0);
565 MULTI_stack_switch(mcs.mc, __KERNEL_DS, thread->sp0); 527 MULTI_stack_switch(mcs.mc, __KERNEL_DS, thread->sp0);
@@ -803,6 +765,19 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
803 ret = -EFAULT; 765 ret = -EFAULT;
804 break; 766 break;
805#endif 767#endif
768
769 case MSR_STAR:
770 case MSR_CSTAR:
771 case MSR_LSTAR:
772 case MSR_SYSCALL_MASK:
773 case MSR_IA32_SYSENTER_CS:
774 case MSR_IA32_SYSENTER_ESP:
775 case MSR_IA32_SYSENTER_EIP:
776 /* Fast syscall setup is all done in hypercalls, so
777 these are all ignored. Stub them out here to stop
778 Xen console noise. */
779 break;
780
806 default: 781 default:
807 ret = native_write_msr_safe(msr, low, high); 782 ret = native_write_msr_safe(msr, low, high);
808 } 783 }
@@ -1220,6 +1195,9 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
1220 .load_gs_index = xen_load_gs_index, 1195 .load_gs_index = xen_load_gs_index,
1221#endif 1196#endif
1222 1197
1198 .alloc_ldt = xen_alloc_ldt,
1199 .free_ldt = xen_free_ldt,
1200
1223 .store_gdt = native_store_gdt, 1201 .store_gdt = native_store_gdt,
1224 .store_idt = native_store_idt, 1202 .store_idt = native_store_idt,
1225 .store_tr = xen_store_tr, 1203 .store_tr = xen_store_tr,
@@ -1241,36 +1219,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
1241 }, 1219 },
1242}; 1220};
1243 1221
1244static void __init __xen_init_IRQ(void)
1245{
1246#ifdef CONFIG_X86_64
1247 int i;
1248
1249 /* Create identity vector->irq map */
1250 for(i = 0; i < NR_VECTORS; i++) {
1251 int cpu;
1252
1253 for_each_possible_cpu(cpu)
1254 per_cpu(vector_irq, cpu)[i] = i;
1255 }
1256#endif /* CONFIG_X86_64 */
1257
1258 xen_init_IRQ();
1259}
1260
1261static const struct pv_irq_ops xen_irq_ops __initdata = {
1262 .init_IRQ = __xen_init_IRQ,
1263 .save_fl = xen_save_fl,
1264 .restore_fl = xen_restore_fl,
1265 .irq_disable = xen_irq_disable,
1266 .irq_enable = xen_irq_enable,
1267 .safe_halt = xen_safe_halt,
1268 .halt = xen_halt,
1269#ifdef CONFIG_X86_64
1270 .adjust_exception_frame = xen_adjust_exception_frame,
1271#endif
1272};
1273
1274static const struct pv_apic_ops xen_apic_ops __initdata = { 1222static const struct pv_apic_ops xen_apic_ops __initdata = {
1275#ifdef CONFIG_X86_LOCAL_APIC 1223#ifdef CONFIG_X86_LOCAL_APIC
1276 .apic_write = xen_apic_write, 1224 .apic_write = xen_apic_write,
@@ -1324,7 +1272,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1324 .ptep_modify_prot_commit = __ptep_modify_prot_commit, 1272 .ptep_modify_prot_commit = __ptep_modify_prot_commit,
1325 1273
1326 .pte_val = xen_pte_val, 1274 .pte_val = xen_pte_val,
1327 .pte_flags = native_pte_val, 1275 .pte_flags = native_pte_flags,
1328 .pgd_val = xen_pgd_val, 1276 .pgd_val = xen_pgd_val,
1329 1277
1330 .make_pte = xen_make_pte, 1278 .make_pte = xen_make_pte,
@@ -1673,10 +1621,11 @@ asmlinkage void __init xen_start_kernel(void)
1673 pv_init_ops = xen_init_ops; 1621 pv_init_ops = xen_init_ops;
1674 pv_time_ops = xen_time_ops; 1622 pv_time_ops = xen_time_ops;
1675 pv_cpu_ops = xen_cpu_ops; 1623 pv_cpu_ops = xen_cpu_ops;
1676 pv_irq_ops = xen_irq_ops;
1677 pv_apic_ops = xen_apic_ops; 1624 pv_apic_ops = xen_apic_ops;
1678 pv_mmu_ops = xen_mmu_ops; 1625 pv_mmu_ops = xen_mmu_ops;
1679 1626
1627 xen_init_irq_ops();
1628
1680 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { 1629 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
1681 pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start; 1630 pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
1682 pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit; 1631 pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
new file mode 100644
index 000000000000..28b85ab8422e
--- /dev/null
+++ b/arch/x86/xen/irq.c
@@ -0,0 +1,143 @@
1#include <linux/hardirq.h>
2
3#include <xen/interface/xen.h>
4#include <xen/interface/sched.h>
5#include <xen/interface/vcpu.h>
6
7#include <asm/xen/hypercall.h>
8#include <asm/xen/hypervisor.h>
9
10#include "xen-ops.h"
11
12/*
13 * Force a proper event-channel callback from Xen after clearing the
14 * callback mask. We do this in a very simple manner, by making a call
15 * down into Xen. The pending flag will be checked by Xen on return.
16 */
17void xen_force_evtchn_callback(void)
18{
19 (void)HYPERVISOR_xen_version(0, NULL);
20}
21
22static void __init __xen_init_IRQ(void)
23{
24#ifdef CONFIG_X86_64
25 int i;
26
27 /* Create identity vector->irq map */
28 for(i = 0; i < NR_VECTORS; i++) {
29 int cpu;
30
31 for_each_possible_cpu(cpu)
32 per_cpu(vector_irq, cpu)[i] = i;
33 }
34#endif /* CONFIG_X86_64 */
35
36 xen_init_IRQ();
37}
38
39static unsigned long xen_save_fl(void)
40{
41 struct vcpu_info *vcpu;
42 unsigned long flags;
43
44 vcpu = x86_read_percpu(xen_vcpu);
45
46 /* flag has opposite sense of mask */
47 flags = !vcpu->evtchn_upcall_mask;
48
49 /* convert to IF type flag
50 -0 -> 0x00000000
51 -1 -> 0xffffffff
52 */
53 return (-flags) & X86_EFLAGS_IF;
54}
55
56static void xen_restore_fl(unsigned long flags)
57{
58 struct vcpu_info *vcpu;
59
60 /* convert from IF type flag */
61 flags = !(flags & X86_EFLAGS_IF);
62
63 /* There's a one instruction preempt window here. We need to
64 make sure we're don't switch CPUs between getting the vcpu
65 pointer and updating the mask. */
66 preempt_disable();
67 vcpu = x86_read_percpu(xen_vcpu);
68 vcpu->evtchn_upcall_mask = flags;
69 preempt_enable_no_resched();
70
71 /* Doesn't matter if we get preempted here, because any
72 pending event will get dealt with anyway. */
73
74 if (flags == 0) {
75 preempt_check_resched();
76 barrier(); /* unmask then check (avoid races) */
77 if (unlikely(vcpu->evtchn_upcall_pending))
78 xen_force_evtchn_callback();
79 }
80}
81
82static void xen_irq_disable(void)
83{
84 /* There's a one instruction preempt window here. We need to
85 make sure we're don't switch CPUs between getting the vcpu
86 pointer and updating the mask. */
87 preempt_disable();
88 x86_read_percpu(xen_vcpu)->evtchn_upcall_mask = 1;
89 preempt_enable_no_resched();
90}
91
92static void xen_irq_enable(void)
93{
94 struct vcpu_info *vcpu;
95
96 /* We don't need to worry about being preempted here, since
97 either a) interrupts are disabled, so no preemption, or b)
98 the caller is confused and is trying to re-enable interrupts
99 on an indeterminate processor. */
100
101 vcpu = x86_read_percpu(xen_vcpu);
102 vcpu->evtchn_upcall_mask = 0;
103
104 /* Doesn't matter if we get preempted here, because any
105 pending event will get dealt with anyway. */
106
107 barrier(); /* unmask then check (avoid races) */
108 if (unlikely(vcpu->evtchn_upcall_pending))
109 xen_force_evtchn_callback();
110}
111
112static void xen_safe_halt(void)
113{
114 /* Blocking includes an implicit local_irq_enable(). */
115 if (HYPERVISOR_sched_op(SCHEDOP_block, NULL) != 0)
116 BUG();
117}
118
119static void xen_halt(void)
120{
121 if (irqs_disabled())
122 HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
123 else
124 xen_safe_halt();
125}
126
127static const struct pv_irq_ops xen_irq_ops __initdata = {
128 .init_IRQ = __xen_init_IRQ,
129 .save_fl = xen_save_fl,
130 .restore_fl = xen_restore_fl,
131 .irq_disable = xen_irq_disable,
132 .irq_enable = xen_irq_enable,
133 .safe_halt = xen_safe_halt,
134 .halt = xen_halt,
135#ifdef CONFIG_X86_64
136 .adjust_exception_frame = xen_adjust_exception_frame,
137#endif
138};
139
140void __init xen_init_irq_ops()
141{
142 pv_irq_ops = xen_irq_ops;
143}
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index d8faf79a0a1d..baca7f2fbd8a 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -15,7 +15,6 @@
15 * This does not handle HOTPLUG_CPU yet. 15 * This does not handle HOTPLUG_CPU yet.
16 */ 16 */
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/kernel_stat.h>
19#include <linux/err.h> 18#include <linux/err.h>
20#include <linux/smp.h> 19#include <linux/smp.h>
21 20
@@ -36,8 +35,6 @@
36#include "xen-ops.h" 35#include "xen-ops.h"
37#include "mmu.h" 36#include "mmu.h"
38 37
39static void __cpuinit xen_init_lock_cpu(int cpu);
40
41cpumask_t xen_cpu_initialized_map; 38cpumask_t xen_cpu_initialized_map;
42 39
43static DEFINE_PER_CPU(int, resched_irq); 40static DEFINE_PER_CPU(int, resched_irq);
@@ -419,170 +416,6 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id)
419 return IRQ_HANDLED; 416 return IRQ_HANDLED;
420} 417}
421 418
422struct xen_spinlock {
423 unsigned char lock; /* 0 -> free; 1 -> locked */
424 unsigned short spinners; /* count of waiting cpus */
425};
426
427static int xen_spin_is_locked(struct raw_spinlock *lock)
428{
429 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
430
431 return xl->lock != 0;
432}
433
434static int xen_spin_is_contended(struct raw_spinlock *lock)
435{
436 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
437
438 /* Not strictly true; this is only the count of contended
439 lock-takers entering the slow path. */
440 return xl->spinners != 0;
441}
442
443static int xen_spin_trylock(struct raw_spinlock *lock)
444{
445 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
446 u8 old = 1;
447
448 asm("xchgb %b0,%1"
449 : "+q" (old), "+m" (xl->lock) : : "memory");
450
451 return old == 0;
452}
453
454static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
455static DEFINE_PER_CPU(struct xen_spinlock *, lock_spinners);
456
457static inline void spinning_lock(struct xen_spinlock *xl)
458{
459 __get_cpu_var(lock_spinners) = xl;
460 wmb(); /* set lock of interest before count */
461 asm(LOCK_PREFIX " incw %0"
462 : "+m" (xl->spinners) : : "memory");
463}
464
465static inline void unspinning_lock(struct xen_spinlock *xl)
466{
467 asm(LOCK_PREFIX " decw %0"
468 : "+m" (xl->spinners) : : "memory");
469 wmb(); /* decrement count before clearing lock */
470 __get_cpu_var(lock_spinners) = NULL;
471}
472
473static noinline int xen_spin_lock_slow(struct raw_spinlock *lock)
474{
475 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
476 int irq = __get_cpu_var(lock_kicker_irq);
477 int ret;
478
479 /* If kicker interrupts not initialized yet, just spin */
480 if (irq == -1)
481 return 0;
482
483 /* announce we're spinning */
484 spinning_lock(xl);
485
486 /* clear pending */
487 xen_clear_irq_pending(irq);
488
489 /* check again make sure it didn't become free while
490 we weren't looking */
491 ret = xen_spin_trylock(lock);
492 if (ret)
493 goto out;
494
495 /* block until irq becomes pending */
496 xen_poll_irq(irq);
497 kstat_this_cpu.irqs[irq]++;
498
499out:
500 unspinning_lock(xl);
501 return ret;
502}
503
504static void xen_spin_lock(struct raw_spinlock *lock)
505{
506 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
507 int timeout;
508 u8 oldval;
509
510 do {
511 timeout = 1 << 10;
512
513 asm("1: xchgb %1,%0\n"
514 " testb %1,%1\n"
515 " jz 3f\n"
516 "2: rep;nop\n"
517 " cmpb $0,%0\n"
518 " je 1b\n"
519 " dec %2\n"
520 " jnz 2b\n"
521 "3:\n"
522 : "+m" (xl->lock), "=q" (oldval), "+r" (timeout)
523 : "1" (1)
524 : "memory");
525
526 } while (unlikely(oldval != 0 && !xen_spin_lock_slow(lock)));
527}
528
529static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl)
530{
531 int cpu;
532
533 for_each_online_cpu(cpu) {
534 /* XXX should mix up next cpu selection */
535 if (per_cpu(lock_spinners, cpu) == xl) {
536 xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR);
537 break;
538 }
539 }
540}
541
542static void xen_spin_unlock(struct raw_spinlock *lock)
543{
544 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
545
546 smp_wmb(); /* make sure no writes get moved after unlock */
547 xl->lock = 0; /* release lock */
548
549 /* make sure unlock happens before kick */
550 barrier();
551
552 if (unlikely(xl->spinners))
553 xen_spin_unlock_slow(xl);
554}
555
556static __cpuinit void xen_init_lock_cpu(int cpu)
557{
558 int irq;
559 const char *name;
560
561 name = kasprintf(GFP_KERNEL, "spinlock%d", cpu);
562 irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
563 cpu,
564 xen_reschedule_interrupt,
565 IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
566 name,
567 NULL);
568
569 if (irq >= 0) {
570 disable_irq(irq); /* make sure it's never delivered */
571 per_cpu(lock_kicker_irq, cpu) = irq;
572 }
573
574 printk("cpu %d spinlock event irq %d\n", cpu, irq);
575}
576
577static void __init xen_init_spinlocks(void)
578{
579 pv_lock_ops.spin_is_locked = xen_spin_is_locked;
580 pv_lock_ops.spin_is_contended = xen_spin_is_contended;
581 pv_lock_ops.spin_lock = xen_spin_lock;
582 pv_lock_ops.spin_trylock = xen_spin_trylock;
583 pv_lock_ops.spin_unlock = xen_spin_unlock;
584}
585
586static const struct smp_ops xen_smp_ops __initdata = { 419static const struct smp_ops xen_smp_ops __initdata = {
587 .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu, 420 .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu,
588 .smp_prepare_cpus = xen_smp_prepare_cpus, 421 .smp_prepare_cpus = xen_smp_prepare_cpus,
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
new file mode 100644
index 000000000000..8dc4d31da67f
--- /dev/null
+++ b/arch/x86/xen/spinlock.c
@@ -0,0 +1,183 @@
1/*
2 * Split spinlock implementation out into its own file, so it can be
3 * compiled in a FTRACE-compatible way.
4 */
5#include <linux/kernel_stat.h>
6#include <linux/spinlock.h>
7
8#include <asm/paravirt.h>
9
10#include <xen/interface/xen.h>
11#include <xen/events.h>
12
13#include "xen-ops.h"
14
15struct xen_spinlock {
16 unsigned char lock; /* 0 -> free; 1 -> locked */
17 unsigned short spinners; /* count of waiting cpus */
18};
19
20static int xen_spin_is_locked(struct raw_spinlock *lock)
21{
22 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
23
24 return xl->lock != 0;
25}
26
27static int xen_spin_is_contended(struct raw_spinlock *lock)
28{
29 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
30
31 /* Not strictly true; this is only the count of contended
32 lock-takers entering the slow path. */
33 return xl->spinners != 0;
34}
35
36static int xen_spin_trylock(struct raw_spinlock *lock)
37{
38 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
39 u8 old = 1;
40
41 asm("xchgb %b0,%1"
42 : "+q" (old), "+m" (xl->lock) : : "memory");
43
44 return old == 0;
45}
46
47static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
48static DEFINE_PER_CPU(struct xen_spinlock *, lock_spinners);
49
50static inline void spinning_lock(struct xen_spinlock *xl)
51{
52 __get_cpu_var(lock_spinners) = xl;
53 wmb(); /* set lock of interest before count */
54 asm(LOCK_PREFIX " incw %0"
55 : "+m" (xl->spinners) : : "memory");
56}
57
58static inline void unspinning_lock(struct xen_spinlock *xl)
59{
60 asm(LOCK_PREFIX " decw %0"
61 : "+m" (xl->spinners) : : "memory");
62 wmb(); /* decrement count before clearing lock */
63 __get_cpu_var(lock_spinners) = NULL;
64}
65
66static noinline int xen_spin_lock_slow(struct raw_spinlock *lock)
67{
68 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
69 int irq = __get_cpu_var(lock_kicker_irq);
70 int ret;
71
72 /* If kicker interrupts not initialized yet, just spin */
73 if (irq == -1)
74 return 0;
75
76 /* announce we're spinning */
77 spinning_lock(xl);
78
79 /* clear pending */
80 xen_clear_irq_pending(irq);
81
82 /* check again make sure it didn't become free while
83 we weren't looking */
84 ret = xen_spin_trylock(lock);
85 if (ret)
86 goto out;
87
88 /* block until irq becomes pending */
89 xen_poll_irq(irq);
90 kstat_this_cpu.irqs[irq]++;
91
92out:
93 unspinning_lock(xl);
94 return ret;
95}
96
97static void xen_spin_lock(struct raw_spinlock *lock)
98{
99 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
100 int timeout;
101 u8 oldval;
102
103 do {
104 timeout = 1 << 10;
105
106 asm("1: xchgb %1,%0\n"
107 " testb %1,%1\n"
108 " jz 3f\n"
109 "2: rep;nop\n"
110 " cmpb $0,%0\n"
111 " je 1b\n"
112 " dec %2\n"
113 " jnz 2b\n"
114 "3:\n"
115 : "+m" (xl->lock), "=q" (oldval), "+r" (timeout)
116 : "1" (1)
117 : "memory");
118
119 } while (unlikely(oldval != 0 && !xen_spin_lock_slow(lock)));
120}
121
122static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl)
123{
124 int cpu;
125
126 for_each_online_cpu(cpu) {
127 /* XXX should mix up next cpu selection */
128 if (per_cpu(lock_spinners, cpu) == xl) {
129 xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR);
130 break;
131 }
132 }
133}
134
135static void xen_spin_unlock(struct raw_spinlock *lock)
136{
137 struct xen_spinlock *xl = (struct xen_spinlock *)lock;
138
139 smp_wmb(); /* make sure no writes get moved after unlock */
140 xl->lock = 0; /* release lock */
141
142 /* make sure unlock happens before kick */
143 barrier();
144
145 if (unlikely(xl->spinners))
146 xen_spin_unlock_slow(xl);
147}
148
149static irqreturn_t dummy_handler(int irq, void *dev_id)
150{
151 BUG();
152 return IRQ_HANDLED;
153}
154
155void __cpuinit xen_init_lock_cpu(int cpu)
156{
157 int irq;
158 const char *name;
159
160 name = kasprintf(GFP_KERNEL, "spinlock%d", cpu);
161 irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
162 cpu,
163 dummy_handler,
164 IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
165 name,
166 NULL);
167
168 if (irq >= 0) {
169 disable_irq(irq); /* make sure it's never delivered */
170 per_cpu(lock_kicker_irq, cpu) = irq;
171 }
172
173 printk("cpu %d spinlock event irq %d\n", cpu, irq);
174}
175
176void __init xen_init_spinlocks(void)
177{
178 pv_lock_ops.spin_is_locked = xen_spin_is_locked;
179 pv_lock_ops.spin_is_contended = xen_spin_is_contended;
180 pv_lock_ops.spin_lock = xen_spin_lock;
181 pv_lock_ops.spin_trylock = xen_spin_trylock;
182 pv_lock_ops.spin_unlock = xen_spin_unlock;
183}
diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S
index 2497a30f41de..42786f59d9c0 100644
--- a/arch/x86/xen/xen-asm_32.S
+++ b/arch/x86/xen/xen-asm_32.S
@@ -298,7 +298,7 @@ check_events:
298 push %eax 298 push %eax
299 push %ecx 299 push %ecx
300 push %edx 300 push %edx
301 call force_evtchn_callback 301 call xen_force_evtchn_callback
302 pop %edx 302 pop %edx
303 pop %ecx 303 pop %ecx
304 pop %eax 304 pop %eax
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
index 7f58304fafb3..3b9bda46487a 100644
--- a/arch/x86/xen/xen-asm_64.S
+++ b/arch/x86/xen/xen-asm_64.S
@@ -122,7 +122,7 @@ check_events:
122 push %r9 122 push %r9
123 push %r10 123 push %r10
124 push %r11 124 push %r11
125 call force_evtchn_callback 125 call xen_force_evtchn_callback
126 pop %r11 126 pop %r11
127 pop %r10 127 pop %r10
128 pop %r9 128 pop %r9
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index dd3c23152a2e..3c70ebc50b1b 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -31,6 +31,7 @@ void xen_vcpu_restore(void);
31 31
32void __init xen_build_dynamic_phys_to_machine(void); 32void __init xen_build_dynamic_phys_to_machine(void);
33 33
34void xen_init_irq_ops(void);
34void xen_setup_timer(int cpu); 35void xen_setup_timer(int cpu);
35void xen_setup_cpu_clockevents(void); 36void xen_setup_cpu_clockevents(void);
36unsigned long xen_tsc_khz(void); 37unsigned long xen_tsc_khz(void);
@@ -50,6 +51,9 @@ void __init xen_setup_vcpu_info_placement(void);
50#ifdef CONFIG_SMP 51#ifdef CONFIG_SMP
51void xen_smp_init(void); 52void xen_smp_init(void);
52 53
54void __init xen_init_spinlocks(void);
55__cpuinit void xen_init_lock_cpu(int cpu);
56
53extern cpumask_t xen_cpu_initialized_map; 57extern cpumask_t xen_cpu_initialized_map;
54#else 58#else
55static inline void xen_smp_init(void) {} 59static inline void xen_smp_init(void) {}
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index d4427cb86979..fff987b10e0f 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -60,7 +60,7 @@
60 60
61#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) 61#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
62 62
63#define BALLOON_CLASS_NAME "memory" 63#define BALLOON_CLASS_NAME "xen_memory"
64 64
65struct balloon_stats { 65struct balloon_stats {
66 /* We aim for 'current allocation' == 'target allocation'. */ 66 /* We aim for 'current allocation' == 'target allocation'. */
@@ -226,9 +226,8 @@ static int increase_reservation(unsigned long nr_pages)
226 } 226 }
227 227
228 set_xen_guest_handle(reservation.extent_start, frame_list); 228 set_xen_guest_handle(reservation.extent_start, frame_list);
229 reservation.nr_extents = nr_pages; 229 reservation.nr_extents = nr_pages;
230 rc = HYPERVISOR_memory_op( 230 rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
231 XENMEM_populate_physmap, &reservation);
232 if (rc < nr_pages) { 231 if (rc < nr_pages) {
233 if (rc > 0) { 232 if (rc > 0) {
234 int ret; 233 int ret;
@@ -236,7 +235,7 @@ static int increase_reservation(unsigned long nr_pages)
236 /* We hit the Xen hard limit: reprobe. */ 235 /* We hit the Xen hard limit: reprobe. */
237 reservation.nr_extents = rc; 236 reservation.nr_extents = rc;
238 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, 237 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
239 &reservation); 238 &reservation);
240 BUG_ON(ret != rc); 239 BUG_ON(ret != rc);
241 } 240 }
242 if (rc >= 0) 241 if (rc >= 0)
@@ -464,136 +463,13 @@ static void balloon_exit(void)
464 463
465module_exit(balloon_exit); 464module_exit(balloon_exit);
466 465
467static void balloon_update_driver_allowance(long delta) 466#define BALLOON_SHOW(name, format, args...) \
468{ 467 static ssize_t show_##name(struct sys_device *dev, \
469 unsigned long flags; 468 struct sysdev_attribute *attr, \
470 469 char *buf) \
471 spin_lock_irqsave(&balloon_lock, flags); 470 { \
472 balloon_stats.driver_pages += delta; 471 return sprintf(buf, format, ##args); \
473 spin_unlock_irqrestore(&balloon_lock, flags); 472 } \
474}
475
476static int dealloc_pte_fn(
477 pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
478{
479 unsigned long mfn = pte_mfn(*pte);
480 int ret;
481 struct xen_memory_reservation reservation = {
482 .nr_extents = 1,
483 .extent_order = 0,
484 .domid = DOMID_SELF
485 };
486 set_xen_guest_handle(reservation.extent_start, &mfn);
487 set_pte_at(&init_mm, addr, pte, __pte_ma(0ull));
488 set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY);
489 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
490 BUG_ON(ret != 1);
491 return 0;
492}
493
494static struct page **alloc_empty_pages_and_pagevec(int nr_pages)
495{
496 unsigned long vaddr, flags;
497 struct page *page, **pagevec;
498 int i, ret;
499
500 pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL);
501 if (pagevec == NULL)
502 return NULL;
503
504 for (i = 0; i < nr_pages; i++) {
505 page = pagevec[i] = alloc_page(GFP_KERNEL);
506 if (page == NULL)
507 goto err;
508
509 vaddr = (unsigned long)page_address(page);
510
511 scrub_page(page);
512
513 spin_lock_irqsave(&balloon_lock, flags);
514
515 if (xen_feature(XENFEAT_auto_translated_physmap)) {
516 unsigned long gmfn = page_to_pfn(page);
517 struct xen_memory_reservation reservation = {
518 .nr_extents = 1,
519 .extent_order = 0,
520 .domid = DOMID_SELF
521 };
522 set_xen_guest_handle(reservation.extent_start, &gmfn);
523 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
524 &reservation);
525 if (ret == 1)
526 ret = 0; /* success */
527 } else {
528 ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE,
529 dealloc_pte_fn, NULL);
530 }
531
532 if (ret != 0) {
533 spin_unlock_irqrestore(&balloon_lock, flags);
534 __free_page(page);
535 goto err;
536 }
537
538 totalram_pages = --balloon_stats.current_pages;
539
540 spin_unlock_irqrestore(&balloon_lock, flags);
541 }
542
543 out:
544 schedule_work(&balloon_worker);
545 flush_tlb_all();
546 return pagevec;
547
548 err:
549 spin_lock_irqsave(&balloon_lock, flags);
550 while (--i >= 0)
551 balloon_append(pagevec[i]);
552 spin_unlock_irqrestore(&balloon_lock, flags);
553 kfree(pagevec);
554 pagevec = NULL;
555 goto out;
556}
557
558static void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
559{
560 unsigned long flags;
561 int i;
562
563 if (pagevec == NULL)
564 return;
565
566 spin_lock_irqsave(&balloon_lock, flags);
567 for (i = 0; i < nr_pages; i++) {
568 BUG_ON(page_count(pagevec[i]) != 1);
569 balloon_append(pagevec[i]);
570 }
571 spin_unlock_irqrestore(&balloon_lock, flags);
572
573 kfree(pagevec);
574
575 schedule_work(&balloon_worker);
576}
577
578static void balloon_release_driver_page(struct page *page)
579{
580 unsigned long flags;
581
582 spin_lock_irqsave(&balloon_lock, flags);
583 balloon_append(page);
584 balloon_stats.driver_pages--;
585 spin_unlock_irqrestore(&balloon_lock, flags);
586
587 schedule_work(&balloon_worker);
588}
589
590
591#define BALLOON_SHOW(name, format, args...) \
592 static ssize_t show_##name(struct sys_device *dev, \
593 char *buf) \
594 { \
595 return sprintf(buf, format, ##args); \
596 } \
597 static SYSDEV_ATTR(name, S_IRUGO, show_##name, NULL) 473 static SYSDEV_ATTR(name, S_IRUGO, show_##name, NULL)
598 474
599BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); 475BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages));
@@ -604,7 +480,8 @@ BALLOON_SHOW(hard_limit_kb,
604 (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0); 480 (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0);
605BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); 481BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages));
606 482
607static ssize_t show_target_kb(struct sys_device *dev, char *buf) 483static ssize_t show_target_kb(struct sys_device *dev, struct sysdev_attribute *attr,
484 char *buf)
608{ 485{
609 return sprintf(buf, "%lu\n", PAGES2KB(balloon_stats.target_pages)); 486 return sprintf(buf, "%lu\n", PAGES2KB(balloon_stats.target_pages));
610} 487}
@@ -614,19 +491,14 @@ static ssize_t store_target_kb(struct sys_device *dev,
614 const char *buf, 491 const char *buf,
615 size_t count) 492 size_t count)
616{ 493{
617 char memstring[64], *endchar; 494 char *endchar;
618 unsigned long long target_bytes; 495 unsigned long long target_bytes;
619 496
620 if (!capable(CAP_SYS_ADMIN)) 497 if (!capable(CAP_SYS_ADMIN))
621 return -EPERM; 498 return -EPERM;
622 499
623 if (count <= 1) 500 target_bytes = memparse(buf, &endchar);
624 return -EBADMSG; /* runt */
625 if (count > sizeof(memstring))
626 return -EFBIG; /* too long */
627 strcpy(memstring, buf);
628 501
629 target_bytes = memparse(memstring, &endchar);
630 balloon_set_new_target(target_bytes >> PAGE_SHIFT); 502 balloon_set_new_target(target_bytes >> PAGE_SHIFT);
631 503
632 return count; 504 return count;
@@ -694,20 +566,4 @@ static int register_balloon(struct sys_device *sysdev)
694 return error; 566 return error;
695} 567}
696 568
697static void unregister_balloon(struct sys_device *sysdev)
698{
699 int i;
700
701 sysfs_remove_group(&sysdev->kobj, &balloon_info_group);
702 for (i = 0; i < ARRAY_SIZE(balloon_attrs); i++)
703 sysdev_remove_file(sysdev, balloon_attrs[i]);
704 sysdev_unregister(sysdev);
705 sysdev_class_unregister(&balloon_sysdev_class);
706}
707
708static void balloon_sysfs_exit(void)
709{
710 unregister_balloon(&balloon_sysdev);
711}
712
713MODULE_LICENSE("GPL"); 569MODULE_LICENSE("GPL");
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 0e0c28574af8..a0837036d898 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -84,17 +84,6 @@ static int irq_bindcount[NR_IRQS];
84/* Xen will never allocate port zero for any purpose. */ 84/* Xen will never allocate port zero for any purpose. */
85#define VALID_EVTCHN(chn) ((chn) != 0) 85#define VALID_EVTCHN(chn) ((chn) != 0)
86 86
87/*
88 * Force a proper event-channel callback from Xen after clearing the
89 * callback mask. We do this in a very simple manner, by making a call
90 * down into Xen. The pending flag will be checked by Xen on return.
91 */
92void force_evtchn_callback(void)
93{
94 (void)HYPERVISOR_xen_version(0, NULL);
95}
96EXPORT_SYMBOL_GPL(force_evtchn_callback);
97
98static struct irq_chip xen_dynamic_chip; 87static struct irq_chip xen_dynamic_chip;
99 88
100/* Constructor for packed IRQ information. */ 89/* Constructor for packed IRQ information. */
diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h
index a44c4dc70590..06f786f4b4fb 100644
--- a/include/asm-x86/desc.h
+++ b/include/asm-x86/desc.h
@@ -24,6 +24,11 @@ static inline void fill_ldt(struct desc_struct *desc,
24 desc->d = info->seg_32bit; 24 desc->d = info->seg_32bit;
25 desc->g = info->limit_in_pages; 25 desc->g = info->limit_in_pages;
26 desc->base2 = (info->base_addr & 0xff000000) >> 24; 26 desc->base2 = (info->base_addr & 0xff000000) >> 24;
27 /*
28 * Don't allow setting of the lm bit. It is useless anyway
29 * because 64bit system calls require __USER_CS:
30 */
31 desc->l = 0;
27} 32}
28 33
29extern struct desc_ptr idt_descr; 34extern struct desc_ptr idt_descr;
@@ -97,7 +102,15 @@ static inline int desc_empty(const void *ptr)
97 native_write_gdt_entry(dt, entry, desc, type) 102 native_write_gdt_entry(dt, entry, desc, type)
98#define write_idt_entry(dt, entry, g) \ 103#define write_idt_entry(dt, entry, g) \
99 native_write_idt_entry(dt, entry, g) 104 native_write_idt_entry(dt, entry, g)
100#endif 105
106static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries)
107{
108}
109
110static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries)
111{
112}
113#endif /* CONFIG_PARAVIRT */
101 114
102static inline void native_write_idt_entry(gate_desc *idt, int entry, 115static inline void native_write_idt_entry(gate_desc *idt, int entry,
103 const gate_desc *gate) 116 const gate_desc *gate)
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index fbbde93f12d6..db9b0647b346 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -124,6 +124,9 @@ struct pv_cpu_ops {
124 int entrynum, const void *desc, int size); 124 int entrynum, const void *desc, int size);
125 void (*write_idt_entry)(gate_desc *, 125 void (*write_idt_entry)(gate_desc *,
126 int entrynum, const gate_desc *gate); 126 int entrynum, const gate_desc *gate);
127 void (*alloc_ldt)(struct desc_struct *ldt, unsigned entries);
128 void (*free_ldt)(struct desc_struct *ldt, unsigned entries);
129
127 void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t); 130 void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t);
128 131
129 void (*set_iopl_mask)(unsigned mask); 132 void (*set_iopl_mask)(unsigned mask);
@@ -824,6 +827,16 @@ do { \
824 (aux) = __aux; \ 827 (aux) = __aux; \
825} while (0) 828} while (0)
826 829
830static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries)
831{
832 PVOP_VCALL2(pv_cpu_ops.alloc_ldt, ldt, entries);
833}
834
835static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries)
836{
837 PVOP_VCALL2(pv_cpu_ops.free_ldt, ldt, entries);
838}
839
827static inline void load_TR_desc(void) 840static inline void load_TR_desc(void)
828{ 841{
829 PVOP_VCALL0(pv_cpu_ops.load_tr_desc); 842 PVOP_VCALL0(pv_cpu_ops.load_tr_desc);
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index fdbbf72ca2eb..7889c2f9b75d 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -176,7 +176,7 @@ extern int vsscanf(const char *, const char *, va_list)
176 176
177extern int get_option(char **str, int *pint); 177extern int get_option(char **str, int *pint);
178extern char *get_options(const char *str, int nints, int *ints); 178extern char *get_options(const char *str, int nints, int *ints);
179extern unsigned long long memparse(char *ptr, char **retptr); 179extern unsigned long long memparse(const char *ptr, char **retptr);
180 180
181extern int core_kernel_text(unsigned long addr); 181extern int core_kernel_text(unsigned long addr);
182extern int __kernel_text_address(unsigned long addr); 182extern int __kernel_text_address(unsigned long addr);
diff --git a/lib/cmdline.c b/lib/cmdline.c
index 5ba8a942a478..f5f3ad8b62ff 100644
--- a/lib/cmdline.c
+++ b/lib/cmdline.c
@@ -126,7 +126,7 @@ char *get_options(const char *str, int nints, int *ints)
126 * megabyte, or one gigabyte, respectively. 126 * megabyte, or one gigabyte, respectively.
127 */ 127 */
128 128
129unsigned long long memparse(char *ptr, char **retptr) 129unsigned long long memparse(const char *ptr, char **retptr)
130{ 130{
131 char *endptr; /* local pointer to end of parsed string */ 131 char *endptr; /* local pointer to end of parsed string */
132 132