summaryrefslogtreecommitdiff
path: root/include/asm-x86
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-x86')
-rw-r--r--include/asm-x86/bitops.h37
-rw-r--r--include/asm-x86/bootparam.h8
-rw-r--r--include/asm-x86/geode.h16
-rw-r--r--include/asm-x86/i387.h12
-rw-r--r--include/asm-x86/kvm_host.h14
-rw-r--r--include/asm-x86/kvm_para.h33
-rw-r--r--include/asm-x86/kvm_x86_emulate.h1
-rw-r--r--include/asm-x86/msr.h2
-rw-r--r--include/asm-x86/page.h15
-rw-r--r--include/asm-x86/page_32.h3
-rw-r--r--include/asm-x86/pat.h8
-rw-r--r--include/asm-x86/pgtable-3level.h6
-rw-r--r--include/asm-x86/pgtable.h19
-rw-r--r--include/asm-x86/pgtable_32.h11
-rw-r--r--include/asm-x86/pgtable_64.h14
-rw-r--r--include/asm-x86/pvclock-abi.h42
-rw-r--r--include/asm-x86/pvclock.h13
-rw-r--r--include/asm-x86/spinlock.h18
-rw-r--r--include/asm-x86/tlbflush.h13
-rw-r--r--include/asm-x86/topology.h18
-rw-r--r--include/asm-x86/types.h38
-rw-r--r--include/asm-x86/xen/page.h6
22 files changed, 193 insertions, 154 deletions
diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h
index b81a4d4d3337..ee4b3ead6a43 100644
--- a/include/asm-x86/bitops.h
+++ b/include/asm-x86/bitops.h
@@ -23,13 +23,10 @@
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
/* Technically wrong, but this avoids compilation errors on some gcc
versions. */
-#define ADDR "=m" (*(volatile long *)addr)
-#define BIT_ADDR "=m" (((volatile int *)addr)[nr >> 5])
+#define ADDR "=m" (*(volatile long *) addr)
#else
#define ADDR "+m" (*(volatile long *) addr)
-#define BIT_ADDR "+m" (((volatile int *)addr)[nr >> 5])
#endif
-#define BASE_ADDR "m" (*(volatile int *)addr)
/**
* set_bit - Atomically set a bit in memory
@@ -77,7 +74,7 @@ static inline void __set_bit(int nr, volatile void *addr)
*/
static inline void clear_bit(int nr, volatile void *addr)
{
- asm volatile(LOCK_PREFIX "btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+ asm volatile(LOCK_PREFIX "btr %1,%0" : ADDR : "Ir" (nr));
}
/*
@@ -96,7 +93,7 @@ static inline void clear_bit_unlock(unsigned nr, volatile void *addr)
static inline void __clear_bit(int nr, volatile void *addr)
{
- asm volatile("btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+ asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
}
/*
@@ -131,7 +128,7 @@ static inline void __clear_bit_unlock(unsigned nr, volatile void *addr)
*/
static inline void __change_bit(int nr, volatile void *addr)
{
- asm volatile("btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+ asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
}
/**
@@ -145,7 +142,7 @@ static inline void __change_bit(int nr, volatile void *addr)
*/
static inline void change_bit(int nr, volatile void *addr)
{
- asm volatile(LOCK_PREFIX "btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+ asm volatile(LOCK_PREFIX "btc %1,%0" : ADDR : "Ir" (nr));
}
/**
@@ -191,9 +188,10 @@ static inline int __test_and_set_bit(int nr, volatile void *addr)
{
int oldbit;
- asm volatile("bts %2,%3\n\t"
- "sbb %0,%0"
- : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR);
+ asm("bts %2,%1\n\t"
+ "sbb %0,%0"
+ : "=r" (oldbit), ADDR
+ : "Ir" (nr));
return oldbit;
}
@@ -229,9 +227,10 @@ static inline int __test_and_clear_bit(int nr, volatile void *addr)
{
int oldbit;
- asm volatile("btr %2,%3\n\t"
+ asm volatile("btr %2,%1\n\t"
"sbb %0,%0"
- : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR);
+ : "=r" (oldbit), ADDR
+ : "Ir" (nr));
return oldbit;
}
@@ -240,9 +239,10 @@ static inline int __test_and_change_bit(int nr, volatile void *addr)
{
int oldbit;
- asm volatile("btc %2,%3\n\t"
+ asm volatile("btc %2,%1\n\t"
"sbb %0,%0"
- : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR);
+ : "=r" (oldbit), ADDR
+ : "Ir" (nr) : "memory");
return oldbit;
}
@@ -276,11 +276,10 @@ static inline int variable_test_bit(int nr, volatile const void *addr)
{
int oldbit;
- asm volatile("bt %2,%3\n\t"
+ asm volatile("bt %2,%1\n\t"
"sbb %0,%0"
: "=r" (oldbit)
- : "m" (((volatile const int *)addr)[nr >> 5]),
- "Ir" (nr), BASE_ADDR);
+ : "m" (*(unsigned long *)addr), "Ir" (nr));
return oldbit;
}
@@ -397,8 +396,6 @@ static inline int fls(int x)
}
#endif /* __KERNEL__ */
-#undef BASE_ADDR
-#undef BIT_ADDR
#undef ADDR
static inline void set_bit_string(unsigned long *bitmap,
diff --git a/include/asm-x86/bootparam.h b/include/asm-x86/bootparam.h
index e8659909e5f6..f62f4733606b 100644
--- a/include/asm-x86/bootparam.h
+++ b/include/asm-x86/bootparam.h
@@ -14,10 +14,10 @@
/* extensible setup data list node */
struct setup_data {
- u64 next;
- u32 type;
- u32 len;
- u8 data[0];
+ __u64 next;
+ __u32 type;
+ __u32 len;
+ __u8 data[0];
};
struct setup_header {
diff --git a/include/asm-x86/geode.h b/include/asm-x86/geode.h
index 7154dc4de951..bb06027fc83e 100644
--- a/include/asm-x86/geode.h
+++ b/include/asm-x86/geode.h
@@ -112,8 +112,8 @@ extern int geode_get_dev_base(unsigned int dev);
#define VSA_VR_UNLOCK 0xFC53 /* unlock virtual register */
#define VSA_VR_SIGNATURE 0x0003
#define VSA_VR_MEM_SIZE 0x0200
-#define VSA_SIG 0x4132 /* signature is ascii 'VSA2' */
-
+#define AMD_VSA_SIG 0x4132 /* signature is ascii 'VSA2' */
+#define GSW_VSA_SIG 0x534d /* General Software signature */
/* GPIO */
#define GPIO_OUTPUT_VAL 0x00
@@ -185,16 +185,14 @@ static inline int is_geode(void)
return (is_geode_gx() || is_geode_lx());
}
-/*
- * The VSA has virtual registers that we can query for a signature.
- */
+#ifdef CONFIG_MGEODE_LX
+extern int geode_has_vsa2(void);
+#else
static inline int geode_has_vsa2(void)
{
- outw(VSA_VR_UNLOCK, VSA_VRC_INDEX);
- outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX);
-
- return (inw(VSA_VRC_DATA) == VSA_SIG);
+ return 0;
}
+#endif
/* MFGPTs */
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
index da2adb45f6e3..37672f79dcc8 100644
--- a/include/asm-x86/i387.h
+++ b/include/asm-x86/i387.h
@@ -175,7 +175,15 @@ static inline int save_i387(struct _fpstate __user *buf)
*/
static inline int restore_i387(struct _fpstate __user *buf)
{
- set_used_math();
+ struct task_struct *tsk = current;
+ int err;
+
+ if (!used_math()) {
+ err = init_fpu(tsk);
+ if (err)
+ return err;
+ }
+
if (!(task_thread_info(current)->status & TS_USEDFPU)) {
clts();
task_thread_info(current)->status |= TS_USEDFPU;
@@ -185,6 +193,8 @@ static inline int restore_i387(struct _fpstate __user *buf)
#else /* CONFIG_X86_32 */
+extern void finit(void);
+
static inline void tolerant_fwait(void)
{
asm volatile("fnclex ; fwait");
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 9d963cd6533c..844f2a89afbc 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -18,6 +18,7 @@
#include <linux/kvm_para.h>
#include <linux/kvm_types.h>
+#include <asm/pvclock-abi.h>
#include <asm/desc.h>
#define KVM_MAX_VCPUS 16
@@ -282,7 +283,8 @@ struct kvm_vcpu_arch {
struct x86_emulate_ctxt emulate_ctxt;
gpa_t time;
- struct kvm_vcpu_time_info hv_clock;
+ struct pvclock_vcpu_time_info hv_clock;
+ unsigned int hv_clock_tsc_khz;
unsigned int time_offset;
struct page *time_page;
};
@@ -314,6 +316,9 @@ struct kvm_arch{
struct page *apic_access_page;
gpa_t wall_clock;
+
+ struct page *ept_identity_pagetable;
+ bool ept_identity_pagetable_done;
};
struct kvm_vm_stat {
@@ -422,6 +427,7 @@ struct kvm_x86_ops {
struct kvm_run *run);
int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
+ int (*get_tdp_level)(void);
};
extern struct kvm_x86_ops *kvm_x86_ops;
@@ -433,6 +439,9 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
int kvm_mmu_create(struct kvm_vcpu *vcpu);
int kvm_mmu_setup(struct kvm_vcpu *vcpu);
void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte);
+void kvm_mmu_set_base_ptes(u64 base_pte);
+void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
+ u64 dirty_mask, u64 nx_mask, u64 x_mask);
int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
@@ -620,7 +629,7 @@ static inline void fx_restore(struct i387_fxsave_struct *image)
asm("fxrstor (%0)":: "r" (image));
}
-static inline void fpu_init(void)
+static inline void fx_finit(void)
{
asm("finit");
}
@@ -644,6 +653,7 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code)
#define ASM_VMX_VMWRITE_RSP_RDX ".byte 0x0f, 0x79, 0xd4"
#define ASM_VMX_VMXOFF ".byte 0x0f, 0x01, 0xc4"
#define ASM_VMX_VMXON_RAX ".byte 0xf3, 0x0f, 0xc7, 0x30"
+#define ASM_VMX_INVEPT ".byte 0x66, 0x0f, 0x38, 0x80, 0x08"
#define ASM_VMX_INVVPID ".byte 0x66, 0x0f, 0x38, 0x81, 0x08"
#define MSR_IA32_TIME_STAMP_COUNTER 0x010
diff --git a/include/asm-x86/kvm_para.h b/include/asm-x86/kvm_para.h
index 509845942070..76f392146daa 100644
--- a/include/asm-x86/kvm_para.h
+++ b/include/asm-x86/kvm_para.h
@@ -48,24 +48,6 @@ struct kvm_mmu_op_release_pt {
#ifdef __KERNEL__
#include <asm/processor.h>
-/* xen binary-compatible interface. See xen headers for details */
-struct kvm_vcpu_time_info {
- uint32_t version;
- uint32_t pad0;
- uint64_t tsc_timestamp;
- uint64_t system_time;
- uint32_t tsc_to_system_mul;
- int8_t tsc_shift;
- int8_t pad[3];
-} __attribute__((__packed__)); /* 32 bytes */
-
-struct kvm_wall_clock {
- uint32_t wc_version;
- uint32_t wc_sec;
- uint32_t wc_nsec;
-} __attribute__((__packed__));
-
-
extern void kvmclock_init(void);
@@ -89,7 +71,8 @@ static inline long kvm_hypercall0(unsigned int nr)
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr));
+ : "a"(nr)
+ : "memory");
return ret;
}
@@ -98,7 +81,8 @@ static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr), "b"(p1));
+ : "a"(nr), "b"(p1)
+ : "memory");
return ret;
}
@@ -108,7 +92,8 @@ static inline long kvm_hypercall2(unsigned int nr, unsigned long p1,
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr), "b"(p1), "c"(p2));
+ : "a"(nr), "b"(p1), "c"(p2)
+ : "memory");
return ret;
}
@@ -118,7 +103,8 @@ static inline long kvm_hypercall3(unsigned int nr, unsigned long p1,
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr), "b"(p1), "c"(p2), "d"(p3));
+ : "a"(nr), "b"(p1), "c"(p2), "d"(p3)
+ : "memory");
return ret;
}
@@ -129,7 +115,8 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4));
+ : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)
+ : "memory");
return ret;
}
diff --git a/include/asm-x86/kvm_x86_emulate.h b/include/asm-x86/kvm_x86_emulate.h
index d6337f941c98..b877bbd2d3a7 100644
--- a/include/asm-x86/kvm_x86_emulate.h
+++ b/include/asm-x86/kvm_x86_emulate.h
@@ -135,6 +135,7 @@ struct decode_cache {
u8 modrm_rm;
u8 use_modrm_ea;
unsigned long modrm_ea;
+ void *modrm_ptr;
unsigned long modrm_val;
struct fetch_cache fetch;
};
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h
index 3707650a169b..2b5f2c91db25 100644
--- a/include/asm-x86/msr.h
+++ b/include/asm-x86/msr.h
@@ -18,7 +18,7 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
unsigned long low, high;
asm volatile(".byte 0x0f,0x01,0xf9"
: "=a" (low), "=d" (high), "=c" (*aux));
- return low | ((u64)high >> 32);
+ return low | ((u64)high << 32);
}
/*
diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h
index b381f4a5a0bd..dc936dddf161 100644
--- a/include/asm-x86/page.h
+++ b/include/asm-x86/page.h
@@ -10,8 +10,16 @@
#ifdef __KERNEL__
-#define PHYSICAL_PAGE_MASK (PAGE_MASK & __PHYSICAL_MASK)
-#define PTE_MASK (_AT(long, PHYSICAL_PAGE_MASK))
+#define __PHYSICAL_MASK ((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1)
+#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
+
+/* Cast PAGE_MASK to a signed type so that it is sign-extended if
+ virtual addresses are 32-bits but physical addresses are larger
+ (ie, 32-bit PAE). */
+#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
+
+/* PTE_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
+#define PTE_MASK ((pteval_t)PHYSICAL_PAGE_MASK)
#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
@@ -24,9 +32,6 @@
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-#define __PHYSICAL_MASK _AT(phys_addr_t, (_AC(1,ULL) << __PHYSICAL_MASK_SHIFT) - 1)
-#define __VIRTUAL_MASK ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1)
-
#ifndef __ASSEMBLY__
#include <linux/types.h>
#endif
diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h
index 424e82f8ae27..ccf0ba3c3aba 100644
--- a/include/asm-x86/page_32.h
+++ b/include/asm-x86/page_32.h
@@ -14,7 +14,8 @@
#define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
#ifdef CONFIG_X86_PAE
-#define __PHYSICAL_MASK_SHIFT 36
+/* 44=32+12, the limit we can fit into an unsigned long pfn */
+#define __PHYSICAL_MASK_SHIFT 44
#define __VIRTUAL_MASK_SHIFT 32
#define PAGETABLE_LEVELS 3
diff --git a/include/asm-x86/pat.h b/include/asm-x86/pat.h
index 8b822b5a1786..88f60cc6a227 100644
--- a/include/asm-x86/pat.h
+++ b/include/asm-x86/pat.h
@@ -4,7 +4,13 @@
#include <linux/types.h>
+#ifdef CONFIG_X86_PAT
extern int pat_wc_enabled;
+extern void validate_pat_support(struct cpuinfo_x86 *c);
+#else
+static const int pat_wc_enabled = 0;
+static inline void validate_pat_support(struct cpuinfo_x86 *c) { }
+#endif
extern void pat_init(void);
@@ -12,5 +18,7 @@ extern int reserve_memtype(u64 start, u64 end,
unsigned long req_type, unsigned long *ret_type);
extern int free_memtype(u64 start, u64 end);
+extern void pat_disable(char *reason);
+
#endif
diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h
index 8b4a9d44b7f4..c93dbb6c2624 100644
--- a/include/asm-x86/pgtable-3level.h
+++ b/include/asm-x86/pgtable-3level.h
@@ -120,9 +120,9 @@ static inline void pud_clear(pud_t *pudp)
write_cr3(pgd);
}
-#define pud_page(pud) ((struct page *) __va(pud_val(pud) & PAGE_MASK))
+#define pud_page(pud) ((struct page *) __va(pud_val(pud) & PTE_MASK))
-#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & PAGE_MASK))
+#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & PTE_MASK))
/* Find an entry in the second-level page table.. */
@@ -160,7 +160,7 @@ static inline int pte_none(pte_t pte)
static inline unsigned long pte_pfn(pte_t pte)
{
- return (pte_val(pte) & ~_PAGE_NX) >> PAGE_SHIFT;
+ return (pte_val(pte) & PTE_MASK) >> PAGE_SHIFT;
}
/*
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index 801b31f71452..97c271b2910b 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -57,7 +57,9 @@
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \
_PAGE_DIRTY)
-#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+/* Set of bits not changed in pte_modify */
+#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_PCD | _PAGE_PWT | \
+ _PAGE_ACCESSED | _PAGE_DIRTY)
#define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT)
#define _PAGE_CACHE_WB (0)
@@ -288,13 +290,22 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
* Chop off the NX bit (if present), and add the NX portion of
* the newprot (if present):
*/
- val &= _PAGE_CHG_MASK & ~_PAGE_NX;
- val |= pgprot_val(newprot) & __supported_pte_mask;
+ val &= _PAGE_CHG_MASK;
+ val |= pgprot_val(newprot) & (~_PAGE_CHG_MASK) & __supported_pte_mask;
return __pte(val);
}
-#define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX))
+/* mprotect needs to preserve PAT bits when updating vm_page_prot */
+#define pgprot_modify pgprot_modify
+static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
+{
+ pgprotval_t preservebits = pgprot_val(oldprot) & _PAGE_CHG_MASK;
+ pgprotval_t addbits = pgprot_val(newprot);
+ return __pgprot(preservebits | addbits);
+}
+
+#define pte_pgprot(x) __pgprot(pte_val(x) & ~PTE_MASK)
#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h
index 577ab79c4c27..32ca03109a4c 100644
--- a/include/asm-x86/pgtable_32.h
+++ b/include/asm-x86/pgtable_32.h
@@ -88,14 +88,7 @@ extern unsigned long pg0[];
/* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
#define pmd_none(x) (!(unsigned long)pmd_val((x)))
#define pmd_present(x) (pmd_val((x)) & _PAGE_PRESENT)
-
-extern int pmd_bad(pmd_t pmd);
-
-#define pmd_bad_v1(x) \
- (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER)))
-#define pmd_bad_v2(x) \
- (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER | \
- _PAGE_PSE | _PAGE_NX)))
+#define pmd_bad(x) ((pmd_val(x) & (~PTE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
@@ -166,7 +159,7 @@ static inline int pud_large(pud_t pud) { return 0; }
#define pmd_page(pmd) (pfn_to_page(pmd_val((pmd)) >> PAGE_SHIFT))
#define pmd_page_vaddr(pmd) \
- ((unsigned long)__va(pmd_val((pmd)) & PAGE_MASK))
+ ((unsigned long)__va(pmd_val((pmd)) & PTE_MASK))
#if defined(CONFIG_HIGHPTE)
#define pte_offset_map(dir, address) \
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
index a3bbf8766c1d..1cc50d22d735 100644
--- a/include/asm-x86/pgtable_64.h
+++ b/include/asm-x86/pgtable_64.h
@@ -151,21 +151,19 @@ static inline void native_pgd_clear(pgd_t *pgd)
#ifndef __ASSEMBLY__
-static inline unsigned long pgd_bad(pgd_t pgd)
+static inline int pgd_bad(pgd_t pgd)
{
- return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
+ return (pgd_val(pgd) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
}
-static inline unsigned long pud_bad(pud_t pud)
+static inline int pud_bad(pud_t pud)
{
- return pud_val(pud) &
- ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX);
+ return (pud_val(pud) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
}
-static inline unsigned long pmd_bad(pmd_t pmd)
+static inline int pmd_bad(pmd_t pmd)
{
- return pmd_val(pmd) &
- ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX);
+ return (pmd_val(pmd) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
}
#define pte_none(x) (!pte_val((x)))
diff --git a/include/asm-x86/pvclock-abi.h b/include/asm-x86/pvclock-abi.h
new file mode 100644
index 000000000000..6857f840b243
--- /dev/null
+++ b/include/asm-x86/pvclock-abi.h
@@ -0,0 +1,42 @@
+#ifndef _ASM_X86_PVCLOCK_ABI_H_
+#define _ASM_X86_PVCLOCK_ABI_H_
+#ifndef __ASSEMBLY__
+
+/*
+ * These structs MUST NOT be changed.
+ * They are the ABI between hypervisor and guest OS.
+ * Both Xen and KVM are using this.
+ *
+ * pvclock_vcpu_time_info holds the system time and the tsc timestamp
+ * of the last update. So the guest can use the tsc delta to get a
+ * more precise system time. There is one per virtual cpu.
+ *
+ * pvclock_wall_clock references the point in time when the system
+ * time was zero (usually boot time), thus the guest calculates the
+ * current wall clock by adding the system time.
+ *
+ * Protocol for the "version" fields is: hypervisor raises it (making
+ * it uneven) before it starts updating the fields and raises it again
+ * (making it even) when it is done. Thus the guest can make sure the
+ * time values it got are consistent by checking the version before
+ * and after reading them.
+ */
+
+struct pvclock_vcpu_time_info {
+ u32 version;
+ u32 pad0;
+ u64 tsc_timestamp;
+ u64 system_time;
+ u32 tsc_to_system_mul;
+ s8 tsc_shift;
+ u8 pad[3];
+} __attribute__((__packed__)); /* 32 bytes */
+
+struct pvclock_wall_clock {
+ u32 version;
+ u32 sec;
+ u32 nsec;
+} __attribute__((__packed__));
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_X86_PVCLOCK_ABI_H_ */
diff --git a/include/asm-x86/pvclock.h b/include/asm-x86/pvclock.h
new file mode 100644
index 000000000000..85b1bba8e0a3
--- /dev/null
+++ b/include/asm-x86/pvclock.h
@@ -0,0 +1,13 @@
+#ifndef _ASM_X86_PVCLOCK_H_
+#define _ASM_X86_PVCLOCK_H_
+
+#include <linux/clocksource.h>
+#include <asm/pvclock-abi.h>
+
+/* some helper functions for xen and kvm pv clock sources */
+cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
+void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
+ struct pvclock_vcpu_time_info *vcpu,
+ struct timespec *ts);
+
+#endif /* _ASM_X86_PVCLOCK_H_ */
diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h
index bc6376f1bc5a..21e89bf92f1c 100644
--- a/include/asm-x86/spinlock.h
+++ b/include/asm-x86/spinlock.h
@@ -20,18 +20,8 @@
*/
#ifdef CONFIG_X86_32
-typedef char _slock_t;
-# define LOCK_INS_DEC "decb"
-# define LOCK_INS_XCH "xchgb"
-# define LOCK_INS_MOV "movb"
-# define LOCK_INS_CMP "cmpb"
# define LOCK_PTR_REG "a"
#else
-typedef int _slock_t;
-# define LOCK_INS_DEC "decl"
-# define LOCK_INS_XCH "xchgl"
-# define LOCK_INS_MOV "movl"
-# define LOCK_INS_CMP "cmpl"
# define LOCK_PTR_REG "D"
#endif
@@ -66,14 +56,14 @@ typedef int _slock_t;
#if (NR_CPUS < 256)
static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
{
- int tmp = *(volatile signed int *)(&(lock)->slock);
+ int tmp = ACCESS_ONCE(lock->slock);
return (((tmp >> 8) & 0xff) != (tmp & 0xff));
}
static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
{
- int tmp = *(volatile signed int *)(&(lock)->slock);
+ int tmp = ACCESS_ONCE(lock->slock);
return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1;
}
@@ -130,14 +120,14 @@ static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
#else
static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
{
- int tmp = *(volatile signed int *)(&(lock)->slock);
+ int tmp = ACCESS_ONCE(lock->slock);
return (((tmp >> 16) & 0xffff) != (tmp & 0xffff));
}
static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
{
- int tmp = *(volatile signed int *)(&(lock)->slock);
+ int tmp = ACCESS_ONCE(lock->slock);
return (((tmp >> 16) & 0xffff) - (tmp & 0xffff)) > 1;
}
diff --git a/include/asm-x86/tlbflush.h b/include/asm-x86/tlbflush.h
index 0c0674d94255..35c76ceb9f40 100644
--- a/include/asm-x86/tlbflush.h
+++ b/include/asm-x86/tlbflush.h
@@ -22,12 +22,23 @@ static inline void __native_flush_tlb(void)
static inline void __native_flush_tlb_global(void)
{
- unsigned long cr4 = read_cr4();
+ unsigned long flags;
+ unsigned long cr4;
+ /*
+ * Read-modify-write to CR4 - protect it from preemption and
+ * from interrupts. (Use the raw variant because this code can
+ * be called from deep inside debugging code.)
+ */
+ raw_local_irq_save(flags);
+
+ cr4 = read_cr4();
/* clear PGE */
write_cr4(cr4 & ~X86_CR4_PGE);
/* write old PGE again and flush TLBs */
write_cr4(cr4);
+
+ raw_local_irq_restore(flags);
}
static inline void __native_flush_tlb_single(unsigned long addr)
diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h
index 4f35a0fb4f22..dcf3f8131d6b 100644
--- a/include/asm-x86/topology.h
+++ b/include/asm-x86/topology.h
@@ -25,6 +25,16 @@
#ifndef _ASM_X86_TOPOLOGY_H
#define _ASM_X86_TOPOLOGY_H
+#ifdef CONFIG_X86_32
+# ifdef CONFIG_X86_HT
+# define ENABLE_TOPO_DEFINES
+# endif
+#else
+# ifdef CONFIG_SMP
+# define ENABLE_TOPO_DEFINES
+# endif
+#endif
+
#ifdef CONFIG_NUMA
#include <linux/cpumask.h>
#include <asm/mpspec.h>
@@ -130,10 +140,6 @@ extern unsigned long node_end_pfn[];
extern unsigned long node_remap_size[];
#define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid])
-# ifdef CONFIG_X86_HT
-# define ENABLE_TOPO_DEFINES
-# endif
-
# define SD_CACHE_NICE_TRIES 1
# define SD_IDLE_IDX 1
# define SD_NEWIDLE_IDX 2
@@ -141,10 +147,6 @@ extern unsigned long node_remap_size[];
#else
-# ifdef CONFIG_SMP
-# define ENABLE_TOPO_DEFINES
-# endif
-
# define SD_CACHE_NICE_TRIES 2
# define SD_IDLE_IDX 2
# define SD_NEWIDLE_IDX 2
diff --git a/include/asm-x86/types.h b/include/asm-x86/types.h
index 63733f315688..1ac80cd9acf8 100644
--- a/include/asm-x86/types.h
+++ b/include/asm-x86/types.h
@@ -1,34 +1,12 @@
#ifndef _ASM_X86_TYPES_H
#define _ASM_X86_TYPES_H
+#include <asm-generic/int-ll64.h>
+
#ifndef __ASSEMBLY__
typedef unsigned short umode_t;
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#ifdef __i386__
-# ifdef __GNUC__
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-# endif
-#else
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-#endif
-
#endif /* __ASSEMBLY__ */
/*
@@ -44,18 +22,6 @@ typedef unsigned long long __u64;
#ifndef __ASSEMBLY__
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
typedef u64 dma64_addr_t;
#if defined(CONFIG_X86_64) || defined(CONFIG_HIGHMEM64G)
/* DMA addresses come in 32-bit and 64-bit flavours. */
diff --git a/include/asm-x86/xen/page.h b/include/asm-x86/xen/page.h
index 01799305f02a..e11f24038b1d 100644
--- a/include/asm-x86/xen/page.h
+++ b/include/asm-x86/xen/page.h
@@ -127,7 +127,7 @@ static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
static inline unsigned long pte_mfn(pte_t pte)
{
- return (pte.pte & ~_PAGE_NX) >> PAGE_SHIFT;
+ return (pte.pte & PTE_MASK) >> PAGE_SHIFT;
}
static inline pte_t mfn_pte(unsigned long page_nr, pgprot_t pgprot)
@@ -150,13 +150,9 @@ static inline pte_t __pte_ma(pteval_t x)
return (pte_t) { .pte = x };
}
-#ifdef CONFIG_X86_PAE
#define pmd_val_ma(v) ((v).pmd)
#define pud_val_ma(v) ((v).pgd.pgd)
#define __pmd_ma(x) ((pmd_t) { (x) } )
-#else /* !X86_PAE */
-#define pmd_val_ma(v) ((v).pud.pgd.pgd)
-#endif /* CONFIG_X86_PAE */
#define pgd_val_ma(x) ((x).pgd)