-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 93687 b: refs/heads/master c: e123dd3 h: refs/heads/master i: 93685: 2895bf1 93683: cd9befc 93679: c92eff0 v: v3
- Loading branch information
Yinghai Lu
authored and
Ingo Molnar
committed
Apr 26, 2008
1 parent
58e58fb
commit 5f1b8a3
Showing
107 changed files
with
2,513 additions
and
2,253 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: e3505dd50caf54e6f81f897cb347441409974a15 | ||
refs/heads/master: e123dd3f0ec1664576456ea1ea045591a0a95f0c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,3 @@ | ||
|
||
menu "Host processor type and features" | ||
|
||
source "arch/x86/Kconfig.cpu" | ||
|
||
endmenu | ||
|
||
config UML_X86 | ||
bool | ||
default y | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#include <linux/bitops.h> | ||
#include <linux/module.h> | ||
|
||
/** | ||
* find_next_bit - find the next set bit in a memory region | ||
* @addr: The address to base the search on | ||
* @offset: The bitnumber to start searching at | ||
* @size: The maximum size to search | ||
*/ | ||
int find_next_bit(const unsigned long *addr, int size, int offset) | ||
{ | ||
const unsigned long *p = addr + (offset >> 5); | ||
int set = 0, bit = offset & 31, res; | ||
|
||
if (bit) { | ||
/* | ||
* Look for nonzero in the first 32 bits: | ||
*/ | ||
__asm__("bsfl %1,%0\n\t" | ||
"jne 1f\n\t" | ||
"movl $32, %0\n" | ||
"1:" | ||
: "=r" (set) | ||
: "r" (*p >> bit)); | ||
if (set < (32 - bit)) | ||
return set + offset; | ||
set = 32 - bit; | ||
p++; | ||
} | ||
/* | ||
* No set bit yet, search remaining full words for a bit | ||
*/ | ||
res = find_first_bit (p, size - 32 * (p - addr)); | ||
return (offset + set + res); | ||
} | ||
EXPORT_SYMBOL(find_next_bit); | ||
|
||
/** | ||
* find_next_zero_bit - find the first zero bit in a memory region | ||
* @addr: The address to base the search on | ||
* @offset: The bitnumber to start searching at | ||
* @size: The maximum size to search | ||
*/ | ||
int find_next_zero_bit(const unsigned long *addr, int size, int offset) | ||
{ | ||
const unsigned long *p = addr + (offset >> 5); | ||
int set = 0, bit = offset & 31, res; | ||
|
||
if (bit) { | ||
/* | ||
* Look for zero in the first 32 bits. | ||
*/ | ||
__asm__("bsfl %1,%0\n\t" | ||
"jne 1f\n\t" | ||
"movl $32, %0\n" | ||
"1:" | ||
: "=r" (set) | ||
: "r" (~(*p >> bit))); | ||
if (set < (32 - bit)) | ||
return set + offset; | ||
set = 32 - bit; | ||
p++; | ||
} | ||
/* | ||
* No zero yet, search remaining full bytes for a zero | ||
*/ | ||
res = find_first_zero_bit(p, size - 32 * (p - addr)); | ||
return (offset + set + res); | ||
} | ||
EXPORT_SYMBOL(find_next_zero_bit); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
#include <linux/bitops.h> | ||
|
||
#undef find_first_zero_bit | ||
#undef find_next_zero_bit | ||
#undef find_first_bit | ||
#undef find_next_bit | ||
|
||
static inline long | ||
__find_first_zero_bit(const unsigned long * addr, unsigned long size) | ||
{ | ||
long d0, d1, d2; | ||
long res; | ||
|
||
/* | ||
* We must test the size in words, not in bits, because | ||
* otherwise incoming sizes in the range -63..-1 will not run | ||
* any scasq instructions, and then the flags used by the je | ||
* instruction will have whatever random value was in place | ||
* before. Nobody should call us like that, but | ||
* find_next_zero_bit() does when offset and size are at the | ||
* same word and it fails to find a zero itself. | ||
*/ | ||
size += 63; | ||
size >>= 6; | ||
if (!size) | ||
return 0; | ||
asm volatile( | ||
" repe; scasq\n" | ||
" je 1f\n" | ||
" xorq -8(%%rdi),%%rax\n" | ||
" subq $8,%%rdi\n" | ||
" bsfq %%rax,%%rdx\n" | ||
"1: subq %[addr],%%rdi\n" | ||
" shlq $3,%%rdi\n" | ||
" addq %%rdi,%%rdx" | ||
:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) | ||
:"0" (0ULL), "1" (size), "2" (addr), "3" (-1ULL), | ||
[addr] "S" (addr) : "memory"); | ||
/* | ||
* Any register would do for [addr] above, but GCC tends to | ||
* prefer rbx over rsi, even though rsi is readily available | ||
* and doesn't have to be saved. | ||
*/ | ||
return res; | ||
} | ||
|
||
/** | ||
* find_first_zero_bit - find the first zero bit in a memory region | ||
* @addr: The address to start the search at | ||
* @size: The maximum size to search | ||
* | ||
* Returns the bit-number of the first zero bit, not the number of the byte | ||
* containing a bit. | ||
*/ | ||
long find_first_zero_bit(const unsigned long * addr, unsigned long size) | ||
{ | ||
return __find_first_zero_bit (addr, size); | ||
} | ||
|
||
/** | ||
* find_next_zero_bit - find the next zero bit in a memory region | ||
* @addr: The address to base the search on | ||
* @offset: The bitnumber to start searching at | ||
* @size: The maximum size to search | ||
*/ | ||
long find_next_zero_bit (const unsigned long * addr, long size, long offset) | ||
{ | ||
const unsigned long * p = addr + (offset >> 6); | ||
unsigned long set = 0; | ||
unsigned long res, bit = offset&63; | ||
|
||
if (bit) { | ||
/* | ||
* Look for zero in first word | ||
*/ | ||
asm("bsfq %1,%0\n\t" | ||
"cmoveq %2,%0" | ||
: "=r" (set) | ||
: "r" (~(*p >> bit)), "r"(64L)); | ||
if (set < (64 - bit)) | ||
return set + offset; | ||
set = 64 - bit; | ||
p++; | ||
} | ||
/* | ||
* No zero yet, search remaining full words for a zero | ||
*/ | ||
res = __find_first_zero_bit (p, size - 64 * (p - addr)); | ||
|
||
return (offset + set + res); | ||
} | ||
|
||
static inline long | ||
__find_first_bit(const unsigned long * addr, unsigned long size) | ||
{ | ||
long d0, d1; | ||
long res; | ||
|
||
/* | ||
* We must test the size in words, not in bits, because | ||
* otherwise incoming sizes in the range -63..-1 will not run | ||
* any scasq instructions, and then the flags used by the jz | ||
* instruction will have whatever random value was in place | ||
* before. Nobody should call us like that, but | ||
* find_next_bit() does when offset and size are at the same | ||
* word and it fails to find a one itself. | ||
*/ | ||
size += 63; | ||
size >>= 6; | ||
if (!size) | ||
return 0; | ||
asm volatile( | ||
" repe; scasq\n" | ||
" jz 1f\n" | ||
" subq $8,%%rdi\n" | ||
" bsfq (%%rdi),%%rax\n" | ||
"1: subq %[addr],%%rdi\n" | ||
" shlq $3,%%rdi\n" | ||
" addq %%rdi,%%rax" | ||
:"=a" (res), "=&c" (d0), "=&D" (d1) | ||
:"0" (0ULL), "1" (size), "2" (addr), | ||
[addr] "r" (addr) : "memory"); | ||
return res; | ||
} | ||
|
||
/** | ||
* find_first_bit - find the first set bit in a memory region | ||
* @addr: The address to start the search at | ||
* @size: The maximum size to search | ||
* | ||
* Returns the bit-number of the first set bit, not the number of the byte | ||
* containing a bit. | ||
*/ | ||
long find_first_bit(const unsigned long * addr, unsigned long size) | ||
{ | ||
return __find_first_bit(addr,size); | ||
} | ||
|
||
/** | ||
* find_next_bit - find the first set bit in a memory region | ||
* @addr: The address to base the search on | ||
* @offset: The bitnumber to start searching at | ||
* @size: The maximum size to search | ||
*/ | ||
long find_next_bit(const unsigned long * addr, long size, long offset) | ||
{ | ||
const unsigned long * p = addr + (offset >> 6); | ||
unsigned long set = 0, bit = offset & 63, res; | ||
|
||
if (bit) { | ||
/* | ||
* Look for nonzero in the first 64 bits: | ||
*/ | ||
asm("bsfq %1,%0\n\t" | ||
"cmoveq %2,%0\n\t" | ||
: "=r" (set) | ||
: "r" (*p >> bit), "r" (64L)); | ||
if (set < (64 - bit)) | ||
return set + offset; | ||
set = 64 - bit; | ||
p++; | ||
} | ||
/* | ||
* No set bit yet, search remaining full words for a bit | ||
*/ | ||
res = __find_first_bit (p, size - 64 * (p - addr)); | ||
return (offset + set + res); | ||
} | ||
|
||
#include <linux/module.h> | ||
|
||
EXPORT_SYMBOL(find_next_bit); | ||
EXPORT_SYMBOL(find_first_bit); | ||
EXPORT_SYMBOL(find_first_zero_bit); | ||
EXPORT_SYMBOL(find_next_zero_bit); |
Oops, something went wrong.