]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-x86/paravirt.h
x86/paravirt: add spin_lock_flags lock op
[linux-2.6-omap-h63xx.git] / include / asm-x86 / paravirt.h
index eef8095a09dcca01b0cb7ad4aa4c76ef52fe10f9..8e9b1266898c1e7aaff682b1ea2ceca49c9de9c0 100644 (file)
@@ -124,6 +124,9 @@ struct pv_cpu_ops {
                                int entrynum, const void *desc, int size);
        void (*write_idt_entry)(gate_desc *,
                                int entrynum, const gate_desc *gate);
+       void (*alloc_ldt)(struct desc_struct *ldt, unsigned entries);
+       void (*free_ldt)(struct desc_struct *ldt, unsigned entries);
+
        void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t);
 
        void (*set_iopl_mask)(unsigned mask);
@@ -205,7 +208,6 @@ struct pv_apic_ops {
         * these shouldn't be in this interface.
         */
        void (*apic_write)(unsigned long reg, u32 v);
-       void (*apic_write_atomic)(unsigned long reg, u32 v);
        u32 (*apic_read)(unsigned long reg);
        void (*setup_boot_clock)(void);
        void (*setup_secondary_clock)(void);
@@ -326,6 +328,16 @@ struct pv_mmu_ops {
                           unsigned long phys, pgprot_t flags);
 };
 
+struct raw_spinlock;
+struct pv_lock_ops {
+       int (*spin_is_locked)(struct raw_spinlock *lock);
+       int (*spin_is_contended)(struct raw_spinlock *lock);
+       void (*spin_lock)(struct raw_spinlock *lock);
+       void (*spin_lock_flags)(struct raw_spinlock *lock, unsigned long flags);
+       int (*spin_trylock)(struct raw_spinlock *lock);
+       void (*spin_unlock)(struct raw_spinlock *lock);
+};
+
 /* This contains all the paravirt structures: we get a convenient
  * number for each function using the offset which we use to indicate
  * what to patch. */
@@ -336,6 +348,7 @@ struct paravirt_patch_template {
        struct pv_irq_ops pv_irq_ops;
        struct pv_apic_ops pv_apic_ops;
        struct pv_mmu_ops pv_mmu_ops;
+       struct pv_lock_ops pv_lock_ops;
 };
 
 extern struct pv_info pv_info;
@@ -345,6 +358,7 @@ extern struct pv_cpu_ops pv_cpu_ops;
 extern struct pv_irq_ops pv_irq_ops;
 extern struct pv_apic_ops pv_apic_ops;
 extern struct pv_mmu_ops pv_mmu_ops;
+extern struct pv_lock_ops pv_lock_ops;
 
 #define PARAVIRT_PATCH(x)                                      \
        (offsetof(struct paravirt_patch_template, x) / sizeof(void *))
@@ -814,6 +828,16 @@ do {                                                       \
        (aux) = __aux;                                  \
 } while (0)
 
+static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries)
+{
+       PVOP_VCALL2(pv_cpu_ops.alloc_ldt, ldt, entries);
+}
+
+static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries)
+{
+       PVOP_VCALL2(pv_cpu_ops.free_ldt, ldt, entries);
+}
+
 static inline void load_TR_desc(void)
 {
        PVOP_VCALL0(pv_cpu_ops.load_tr_desc);
@@ -896,11 +920,6 @@ static inline void apic_write(unsigned long reg, u32 v)
        PVOP_VCALL2(pv_apic_ops.apic_write, reg, v);
 }
 
-static inline void apic_write_atomic(unsigned long reg, u32 v)
-{
-       PVOP_VCALL2(pv_apic_ops.apic_write_atomic, reg, v);
-}
-
 static inline u32 apic_read(unsigned long reg)
 {
        return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg);
@@ -1083,6 +1102,9 @@ static inline pteval_t pte_flags(pte_t pte)
                ret = PVOP_CALL1(pteval_t, pv_mmu_ops.pte_flags,
                                 pte.pte);
 
+#ifdef CONFIG_PARAVIRT_DEBUG
+       BUG_ON(ret & PTE_PFN_MASK);
+#endif
        return ret;
 }
 
@@ -1374,6 +1396,43 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
 void _paravirt_nop(void);
 #define paravirt_nop   ((void *)_paravirt_nop)
 
+void paravirt_use_bytelocks(void);
+
+#ifdef CONFIG_SMP
+
+static inline int __raw_spin_is_locked(struct raw_spinlock *lock)
+{
+       return PVOP_CALL1(int, pv_lock_ops.spin_is_locked, lock);
+}
+
+static inline int __raw_spin_is_contended(struct raw_spinlock *lock)
+{
+       return PVOP_CALL1(int, pv_lock_ops.spin_is_contended, lock);
+}
+
+static __always_inline void __raw_spin_lock(struct raw_spinlock *lock)
+{
+       PVOP_VCALL1(pv_lock_ops.spin_lock, lock);
+}
+
+static __always_inline void __raw_spin_lock_flags(struct raw_spinlock *lock,
+                                                 unsigned long flags)
+{
+       PVOP_VCALL2(pv_lock_ops.spin_lock_flags, lock, flags);
+}
+
+static __always_inline int __raw_spin_trylock(struct raw_spinlock *lock)
+{
+       return PVOP_CALL1(int, pv_lock_ops.spin_trylock, lock);
+}
+
+static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock)
+{
+       PVOP_VCALL1(pv_lock_ops.spin_unlock, lock);
+}
+
+#endif
+
 /* These all sit in the .parainstructions section to tell us what to patch. */
 struct paravirt_patch_site {
        u8 *instr;              /* original instructions */
@@ -1458,6 +1517,7 @@ static inline unsigned long __raw_local_irq_save(void)
        return f;
 }
 
+
 /* Make sure as little as possible of this mess escapes. */
 #undef PARAVIRT_CALL
 #undef __PVOP_CALL