Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 356262
b: refs/heads/master
c: 0da3e7f
h: refs/heads/master
v: v3
  • Loading branch information
H. Peter Anvin committed Feb 15, 2013
1 parent 8056a44 commit 2b4ff42
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 49 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 68d00bbebb5a48b7a9056a8c03476a71ecbc30a6
refs/heads/master: 0da3e7f526fde7a6522a3038b7ce609fc50f6707
55 changes: 21 additions & 34 deletions trunk/arch/x86/include/asm/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,12 @@ extern int __get_user_4(void);
extern int __get_user_8(void);
extern int __get_user_bad(void);

#define __get_user_x(size, ret, x, ptr) \
asm volatile("call __get_user_" #size \
: "=a" (ret), "=d" (x) \
: "0" (ptr)) \

/* Careful: we have to cast the result to the type of the pointer
* for sign reasons */
/*
* This is a type: either unsigned long, if the argument fits into
* that type, or otherwise unsigned long long.
*/
#define __inttype(x) \
__typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))

/**
* get_user: - Get a simple variable from user space.
Expand All @@ -150,38 +149,26 @@ extern int __get_user_bad(void);
* Returns zero on success, or -EFAULT on error.
* On error, the variable @x is set to zero.
*/
#ifdef CONFIG_X86_32
#define __get_user_8(__ret_gu, __val_gu, ptr) \
__get_user_x(X, __ret_gu, __val_gu, ptr)
#else
#define __get_user_8(__ret_gu, __val_gu, ptr) \
__get_user_x(8, __ret_gu, __val_gu, ptr)
#endif

/*
* Careful: we have to cast the result to the type of the pointer
* for sign reasons.
*
* The use of %edx as the register specifier is a bit of a
* simplification, as gcc only cares about it as the starting point
* and not size: for a 64-bit value it will use %ecx:%edx on 32 bits
* (%ecx being the next register in gcc's x86 register sequence), and
* %rdx on 64 bits.
*/
#define get_user(x, ptr) \
({ \
int __ret_gu; \
unsigned long __val_gu; \
register __inttype(*(ptr)) __val_gu asm("%edx"); \
__chk_user_ptr(ptr); \
might_fault(); \
switch (sizeof(*(ptr))) { \
case 1: \
__get_user_x(1, __ret_gu, __val_gu, ptr); \
break; \
case 2: \
__get_user_x(2, __ret_gu, __val_gu, ptr); \
break; \
case 4: \
__get_user_x(4, __ret_gu, __val_gu, ptr); \
break; \
case 8: \
__get_user_8(__ret_gu, __val_gu, ptr); \
break; \
default: \
__get_user_x(X, __ret_gu, __val_gu, ptr); \
break; \
} \
(x) = (__typeof__(*(ptr)))__val_gu; \
asm volatile("call __get_user_%P3" \
: "=a" (__ret_gu), "=r" (__val_gu) \
: "0" (ptr), "i" (sizeof(*(ptr)))); \
(x) = (__typeof__(*(ptr))) __val_gu; \
__ret_gu; \
})

Expand Down
1 change: 1 addition & 0 deletions trunk/arch/x86/kernel/i386_ksyms_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ EXPORT_SYMBOL(csum_partial_copy_generic);
EXPORT_SYMBOL(__get_user_1);
EXPORT_SYMBOL(__get_user_2);
EXPORT_SYMBOL(__get_user_4);
EXPORT_SYMBOL(__get_user_8);

EXPORT_SYMBOL(__put_user_1);
EXPORT_SYMBOL(__put_user_2);
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/x86/kernel/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ static void kvm_register_steal_time(void)
memset(st, 0, sizeof(*st));

wrmsrl(MSR_KVM_STEAL_TIME, (slow_virt_to_phys(st) | KVM_MSR_ENABLED));
printk(KERN_INFO "kvm-stealtime: cpu %d, msr %lx\n",
cpu, slow_virt_to_phys(st));
pr_info("kvm-stealtime: cpu %d, msr %llx\n",
cpu, (unsigned long long) slow_virt_to_phys(st));
}

static DEFINE_PER_CPU(unsigned long, kvm_apic_eoi) = KVM_PV_EOI_DISABLED;
Expand Down
13 changes: 9 additions & 4 deletions trunk/arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,8 +644,6 @@ static __init void reserve_ibft_region(void)
memblock_reserve(addr, size);
}

static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;

static bool __init snb_gfx_workaround_needed(void)
{
#ifdef CONFIG_PCI
Expand Down Expand Up @@ -734,8 +732,7 @@ static void __init trim_bios_range(void)
* since some BIOSes are known to corrupt low memory. See the
* Kconfig help text for X86_RESERVE_LOW.
*/
e820_update_range(0, ALIGN(reserve_low, PAGE_SIZE),
E820_RAM, E820_RESERVED);
e820_update_range(0, PAGE_SIZE, E820_RAM, E820_RESERVED);

/*
* special case: Some BIOSen report the PC BIOS
Expand Down Expand Up @@ -768,6 +765,8 @@ static void __init e820_add_kernel_range(void)
e820_add_region(start, size, E820_RAM);
}

static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;

static int __init parse_reservelow(char *p)
{
unsigned long long size;
Expand All @@ -790,6 +789,11 @@ static int __init parse_reservelow(char *p)

early_param("reservelow", parse_reservelow);

static void __init trim_low_memory_range(void)
{
memblock_reserve(0, ALIGN(reserve_low, PAGE_SIZE));
}

/*
* Determine if we were loaded by an EFI loader. If so, then we have also been
* passed the efi memmap, systab, etc., so we should use these data structures
Expand Down Expand Up @@ -1060,6 +1064,7 @@ void __init setup_arch(char **cmdline_p)
reserve_real_mode();

trim_platform_memory_ranges();
trim_low_memory_range();

init_mem_mapping();

Expand Down
43 changes: 35 additions & 8 deletions trunk/arch/x86/lib/getuser.S
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
* __get_user_X
*
* Inputs: %[r|e]ax contains the address.
* The register is modified, but all changes are undone
* before returning because the C code doesn't know about it.
*
* Outputs: %[r|e]ax is error code (0 or -EFAULT)
* %[r|e]dx contains zero-extended value
* %ecx contains the high half for 32-bit __get_user_8
*
*
* These functions should not modify any other registers,
Expand All @@ -42,7 +41,7 @@ ENTRY(__get_user_1)
cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
jae bad_get_user
ASM_STAC
1: movzb (%_ASM_AX),%edx
1: movzbl (%_ASM_AX),%edx
xor %eax,%eax
ASM_CLAC
ret
Expand Down Expand Up @@ -72,29 +71,42 @@ ENTRY(__get_user_4)
cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
jae bad_get_user
ASM_STAC
3: mov -3(%_ASM_AX),%edx
3: movl -3(%_ASM_AX),%edx
xor %eax,%eax
ASM_CLAC
ret
CFI_ENDPROC
ENDPROC(__get_user_4)

#ifdef CONFIG_X86_64
ENTRY(__get_user_8)
CFI_STARTPROC
#ifdef CONFIG_X86_64
add $7,%_ASM_AX
jc bad_get_user
GET_THREAD_INFO(%_ASM_DX)
cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
jae bad_get_user
jae bad_get_user
ASM_STAC
4: movq -7(%_ASM_AX),%_ASM_DX
4: movq -7(%_ASM_AX),%rdx
xor %eax,%eax
ASM_CLAC
ret
#else
add $7,%_ASM_AX
jc bad_get_user_8
GET_THREAD_INFO(%_ASM_DX)
cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
jae bad_get_user_8
ASM_STAC
4: movl -7(%_ASM_AX),%edx
5: movl -3(%_ASM_AX),%ecx
xor %eax,%eax
ASM_CLAC
ret
#endif
CFI_ENDPROC
ENDPROC(__get_user_8)
#endif


bad_get_user:
CFI_STARTPROC
Expand All @@ -105,9 +117,24 @@ bad_get_user:
CFI_ENDPROC
END(bad_get_user)

#ifdef CONFIG_X86_32
bad_get_user_8:
CFI_STARTPROC
xor %edx,%edx
xor %ecx,%ecx
mov $(-EFAULT),%_ASM_AX
ASM_CLAC
ret
CFI_ENDPROC
END(bad_get_user_8)
#endif

_ASM_EXTABLE(1b,bad_get_user)
_ASM_EXTABLE(2b,bad_get_user)
_ASM_EXTABLE(3b,bad_get_user)
#ifdef CONFIG_X86_64
_ASM_EXTABLE(4b,bad_get_user)
#else
_ASM_EXTABLE(4b,bad_get_user_8)
_ASM_EXTABLE(5b,bad_get_user_8)
#endif

0 comments on commit 2b4ff42

Please sign in to comment.