mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-11-23 01:11:19 +03:00
ddk: v4.6.7
git-svn-id: svn://kolibrios.org@7143 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
b165e4f6b6
commit
66fbaa74b0
@ -7,12 +7,16 @@
|
|||||||
*/
|
*/
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
//#include <linux/thread_info.h>
|
#include <linux/thread_info.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/bitmap.h>
|
#include <linux/bitmap.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
|
#include <asm/page.h>
|
||||||
//#include <asm/uaccess.h>
|
//#include <asm/uaccess.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -304,9 +308,9 @@ EXPORT_SYMBOL(bitmap_clear);
|
|||||||
* is multiple of that power of 2.
|
* is multiple of that power of 2.
|
||||||
*/
|
*/
|
||||||
unsigned long bitmap_find_next_zero_area_off(unsigned long *map,
|
unsigned long bitmap_find_next_zero_area_off(unsigned long *map,
|
||||||
unsigned long size,
|
unsigned long size,
|
||||||
unsigned long start,
|
unsigned long start,
|
||||||
unsigned int nr,
|
unsigned int nr,
|
||||||
unsigned long align_mask,
|
unsigned long align_mask,
|
||||||
unsigned long align_offset)
|
unsigned long align_offset)
|
||||||
{
|
{
|
||||||
@ -393,7 +397,7 @@ unsigned int bitmap_ord_to_pos(const unsigned long *buf, unsigned int ord, unsig
|
|||||||
for (pos = find_first_bit(buf, nbits);
|
for (pos = find_first_bit(buf, nbits);
|
||||||
pos < nbits && ord;
|
pos < nbits && ord;
|
||||||
pos = find_next_bit(buf, nbits, pos + 1))
|
pos = find_next_bit(buf, nbits, pos + 1))
|
||||||
ord--;
|
ord--;
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
@ -63,19 +63,19 @@ EXPORT_SYMBOL(__div64_32);
|
|||||||
#ifndef div_s64_rem
|
#ifndef div_s64_rem
|
||||||
s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
|
s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
|
||||||
{
|
{
|
||||||
u64 quotient;
|
u64 quotient;
|
||||||
|
|
||||||
if (dividend < 0) {
|
if (dividend < 0) {
|
||||||
quotient = div_u64_rem(-dividend, abs(divisor), (u32 *)remainder);
|
quotient = div_u64_rem(-dividend, abs(divisor), (u32 *)remainder);
|
||||||
*remainder = -*remainder;
|
*remainder = -*remainder;
|
||||||
if (divisor > 0)
|
if (divisor > 0)
|
||||||
quotient = -quotient;
|
quotient = -quotient;
|
||||||
} else {
|
} else {
|
||||||
quotient = div_u64_rem(dividend, abs(divisor), (u32 *)remainder);
|
quotient = div_u64_rem(dividend, abs(divisor), (u32 *)remainder);
|
||||||
if (divisor < 0)
|
if (divisor < 0)
|
||||||
quotient = -quotient;
|
quotient = -quotient;
|
||||||
}
|
}
|
||||||
return quotient;
|
return quotient;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(div_s64_rem);
|
EXPORT_SYMBOL(div_s64_rem);
|
||||||
#endif
|
#endif
|
||||||
|
1049
drivers/ddk/linux/dmi_scan.c
Normal file
1049
drivers/ddk/linux/dmi_scan.c
Normal file
File diff suppressed because it is too large
Load Diff
193
drivers/ddk/linux/find_bit.c
Normal file
193
drivers/ddk/linux/find_bit.c
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
/* bit search implementation
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
|
||||||
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 IBM Corporation
|
||||||
|
* 'find_last_bit' is written by Rusty Russell <rusty@rustcorp.com.au>
|
||||||
|
* (Inspired by David Howell's find_next_bit implementation)
|
||||||
|
*
|
||||||
|
* Rewritten by Yury Norov <yury.norov@gmail.com> to decrease
|
||||||
|
* size and improve performance, 2015.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/bitmap.h>
|
||||||
|
#include <linux/export.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
|
||||||
|
#if !defined(find_next_bit) || !defined(find_next_zero_bit)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a common helper function for find_next_bit and
|
||||||
|
* find_next_zero_bit. The difference is the "invert" argument, which
|
||||||
|
* is XORed with each fetched word before searching it for one bits.
|
||||||
|
*/
|
||||||
|
static unsigned long _find_next_bit(const unsigned long *addr,
|
||||||
|
unsigned long nbits, unsigned long start, unsigned long invert)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
if (!nbits || start >= nbits)
|
||||||
|
return nbits;
|
||||||
|
|
||||||
|
tmp = addr[start / BITS_PER_LONG] ^ invert;
|
||||||
|
|
||||||
|
/* Handle 1st word. */
|
||||||
|
tmp &= BITMAP_FIRST_WORD_MASK(start);
|
||||||
|
start = round_down(start, BITS_PER_LONG);
|
||||||
|
|
||||||
|
while (!tmp) {
|
||||||
|
start += BITS_PER_LONG;
|
||||||
|
if (start >= nbits)
|
||||||
|
return nbits;
|
||||||
|
|
||||||
|
tmp = addr[start / BITS_PER_LONG] ^ invert;
|
||||||
|
}
|
||||||
|
|
||||||
|
return min(start + __ffs(tmp), nbits);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef find_next_bit
|
||||||
|
/*
|
||||||
|
* Find the next set bit in a memory region.
|
||||||
|
*/
|
||||||
|
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
|
||||||
|
unsigned long offset)
|
||||||
|
{
|
||||||
|
return _find_next_bit(addr, size, offset, 0UL);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(find_next_bit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef find_next_zero_bit
|
||||||
|
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
|
||||||
|
unsigned long offset)
|
||||||
|
{
|
||||||
|
return _find_next_bit(addr, size, offset, ~0UL);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(find_next_zero_bit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef find_first_bit
|
||||||
|
/*
|
||||||
|
* Find the first set bit in a memory region.
|
||||||
|
*/
|
||||||
|
unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
|
||||||
|
{
|
||||||
|
unsigned long idx;
|
||||||
|
|
||||||
|
for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
|
||||||
|
if (addr[idx])
|
||||||
|
return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(find_first_bit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef find_first_zero_bit
|
||||||
|
/*
|
||||||
|
* Find the first cleared bit in a memory region.
|
||||||
|
*/
|
||||||
|
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
|
||||||
|
{
|
||||||
|
unsigned long idx;
|
||||||
|
|
||||||
|
for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
|
||||||
|
if (addr[idx] != ~0UL)
|
||||||
|
return min(idx * BITS_PER_LONG + ffz(addr[idx]), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(find_first_zero_bit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef find_last_bit
|
||||||
|
unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
|
||||||
|
{
|
||||||
|
if (size) {
|
||||||
|
unsigned long val = BITMAP_LAST_WORD_MASK(size);
|
||||||
|
unsigned long idx = (size-1) / BITS_PER_LONG;
|
||||||
|
|
||||||
|
do {
|
||||||
|
val &= addr[idx];
|
||||||
|
if (val)
|
||||||
|
return idx * BITS_PER_LONG + __fls(val);
|
||||||
|
|
||||||
|
val = ~0ul;
|
||||||
|
} while (idx--);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(find_last_bit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __BIG_ENDIAN
|
||||||
|
|
||||||
|
/* include/linux/byteorder does not support "unsigned long" type */
|
||||||
|
static inline unsigned long ext2_swab(const unsigned long y)
|
||||||
|
{
|
||||||
|
#if BITS_PER_LONG == 64
|
||||||
|
return (unsigned long) __swab64((u64) y);
|
||||||
|
#elif BITS_PER_LONG == 32
|
||||||
|
return (unsigned long) __swab32((u32) y);
|
||||||
|
#else
|
||||||
|
#error BITS_PER_LONG not defined
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(find_next_bit_le) || !defined(find_next_zero_bit_le)
|
||||||
|
static unsigned long _find_next_bit_le(const unsigned long *addr,
|
||||||
|
unsigned long nbits, unsigned long start, unsigned long invert)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
if (!nbits || start >= nbits)
|
||||||
|
return nbits;
|
||||||
|
|
||||||
|
tmp = addr[start / BITS_PER_LONG] ^ invert;
|
||||||
|
|
||||||
|
/* Handle 1st word. */
|
||||||
|
tmp &= ext2_swab(BITMAP_FIRST_WORD_MASK(start));
|
||||||
|
start = round_down(start, BITS_PER_LONG);
|
||||||
|
|
||||||
|
while (!tmp) {
|
||||||
|
start += BITS_PER_LONG;
|
||||||
|
if (start >= nbits)
|
||||||
|
return nbits;
|
||||||
|
|
||||||
|
tmp = addr[start / BITS_PER_LONG] ^ invert;
|
||||||
|
}
|
||||||
|
|
||||||
|
return min(start + __ffs(ext2_swab(tmp)), nbits);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef find_next_zero_bit_le
|
||||||
|
unsigned long find_next_zero_bit_le(const void *addr, unsigned
|
||||||
|
long size, unsigned long offset)
|
||||||
|
{
|
||||||
|
return _find_next_bit_le(addr, size, offset, ~0UL);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(find_next_zero_bit_le);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef find_next_bit_le
|
||||||
|
unsigned long find_next_bit_le(const void *addr, unsigned
|
||||||
|
long size, unsigned long offset)
|
||||||
|
{
|
||||||
|
return _find_next_bit_le(addr, size, offset, 0UL);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(find_next_bit_le);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __BIG_ENDIAN */
|
@ -345,8 +345,8 @@ static void idr_fill_slot(struct idr *idr, void *ptr, int id,
|
|||||||
rcu_assign_pointer(idr->hint, pa[0]);
|
rcu_assign_pointer(idr->hint, pa[0]);
|
||||||
|
|
||||||
rcu_assign_pointer(pa[0]->ary[id & IDR_MASK], (struct idr_layer *)ptr);
|
rcu_assign_pointer(pa[0]->ary[id & IDR_MASK], (struct idr_layer *)ptr);
|
||||||
pa[0]->count++;
|
pa[0]->count++;
|
||||||
idr_mark_full(pa, id);
|
idr_mark_full(pa, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,8 +102,8 @@ static void merge_and_restore_back_links(void *priv,
|
|||||||
* ordering is to be preserved, @cmp must return 0.
|
* ordering is to be preserved, @cmp must return 0.
|
||||||
*/
|
*/
|
||||||
void list_sort(void *priv, struct list_head *head,
|
void list_sort(void *priv, struct list_head *head,
|
||||||
int (*cmp)(void *priv, struct list_head *a,
|
int (*cmp)(void *priv, struct list_head *a,
|
||||||
struct list_head *b))
|
struct list_head *b))
|
||||||
{
|
{
|
||||||
struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
|
struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
|
||||||
-- last slot is a sentinel */
|
-- last slot is a sentinel */
|
||||||
@ -132,11 +132,11 @@ void list_sort(void *priv, struct list_head *head,
|
|||||||
if (unlikely(lev >= ARRAY_SIZE(part)-1)) {
|
if (unlikely(lev >= ARRAY_SIZE(part)-1)) {
|
||||||
printk_once(KERN_DEBUG "list too long for efficiency\n");
|
printk_once(KERN_DEBUG "list too long for efficiency\n");
|
||||||
lev--;
|
lev--;
|
||||||
}
|
|
||||||
max_lev = lev;
|
|
||||||
}
|
}
|
||||||
part[lev] = cur;
|
max_lev = lev;
|
||||||
}
|
}
|
||||||
|
part[lev] = cur;
|
||||||
|
}
|
||||||
|
|
||||||
for (lev = 0; lev < max_lev; lev++)
|
for (lev = 0; lev < max_lev; lev++)
|
||||||
if (part[lev])
|
if (part[lev])
|
||||||
@ -145,3 +145,149 @@ void list_sort(void *priv, struct list_head *head,
|
|||||||
merge_and_restore_back_links(priv, cmp, head, part[max_lev], list);
|
merge_and_restore_back_links(priv, cmp, head, part[max_lev], list);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(list_sort);
|
EXPORT_SYMBOL(list_sort);
|
||||||
|
|
||||||
|
#ifdef CONFIG_TEST_LIST_SORT
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/random.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The pattern of set bits in the list length determines which cases
|
||||||
|
* are hit in list_sort().
|
||||||
|
*/
|
||||||
|
#define TEST_LIST_LEN (512+128+2) /* not including head */
|
||||||
|
|
||||||
|
#define TEST_POISON1 0xDEADBEEF
|
||||||
|
#define TEST_POISON2 0xA324354C
|
||||||
|
|
||||||
|
struct debug_el {
|
||||||
|
unsigned int poison1;
|
||||||
|
struct list_head list;
|
||||||
|
unsigned int poison2;
|
||||||
|
int value;
|
||||||
|
unsigned serial;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Array, containing pointers to all elements in the test list */
|
||||||
|
static struct debug_el **elts __initdata;
|
||||||
|
|
||||||
|
static int __init check(struct debug_el *ela, struct debug_el *elb)
|
||||||
|
{
|
||||||
|
if (ela->serial >= TEST_LIST_LEN) {
|
||||||
|
pr_err("error: incorrect serial %d\n", ela->serial);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (elb->serial >= TEST_LIST_LEN) {
|
||||||
|
pr_err("error: incorrect serial %d\n", elb->serial);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (elts[ela->serial] != ela || elts[elb->serial] != elb) {
|
||||||
|
pr_err("error: phantom element\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (ela->poison1 != TEST_POISON1 || ela->poison2 != TEST_POISON2) {
|
||||||
|
pr_err("error: bad poison: %#x/%#x\n",
|
||||||
|
ela->poison1, ela->poison2);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (elb->poison1 != TEST_POISON1 || elb->poison2 != TEST_POISON2) {
|
||||||
|
pr_err("error: bad poison: %#x/%#x\n",
|
||||||
|
elb->poison1, elb->poison2);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init cmp(void *priv, struct list_head *a, struct list_head *b)
|
||||||
|
{
|
||||||
|
struct debug_el *ela, *elb;
|
||||||
|
|
||||||
|
ela = container_of(a, struct debug_el, list);
|
||||||
|
elb = container_of(b, struct debug_el, list);
|
||||||
|
|
||||||
|
check(ela, elb);
|
||||||
|
return ela->value - elb->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init list_sort_test(void)
|
||||||
|
{
|
||||||
|
int i, count = 1, err = -ENOMEM;
|
||||||
|
struct debug_el *el;
|
||||||
|
struct list_head *cur;
|
||||||
|
LIST_HEAD(head);
|
||||||
|
|
||||||
|
pr_debug("start testing list_sort()\n");
|
||||||
|
|
||||||
|
elts = kcalloc(TEST_LIST_LEN, sizeof(*elts), GFP_KERNEL);
|
||||||
|
if (!elts) {
|
||||||
|
pr_err("error: cannot allocate memory\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < TEST_LIST_LEN; i++) {
|
||||||
|
el = kmalloc(sizeof(*el), GFP_KERNEL);
|
||||||
|
if (!el) {
|
||||||
|
pr_err("error: cannot allocate memory\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
/* force some equivalencies */
|
||||||
|
el->value = prandom_u32() % (TEST_LIST_LEN / 3);
|
||||||
|
el->serial = i;
|
||||||
|
el->poison1 = TEST_POISON1;
|
||||||
|
el->poison2 = TEST_POISON2;
|
||||||
|
elts[i] = el;
|
||||||
|
list_add_tail(&el->list, &head);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_sort(NULL, &head, cmp);
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
|
for (cur = head.next; cur->next != &head; cur = cur->next) {
|
||||||
|
struct debug_el *el1;
|
||||||
|
int cmp_result;
|
||||||
|
|
||||||
|
if (cur->next->prev != cur) {
|
||||||
|
pr_err("error: list is corrupted\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmp_result = cmp(NULL, cur, cur->next);
|
||||||
|
if (cmp_result > 0) {
|
||||||
|
pr_err("error: list is not sorted\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
el = container_of(cur, struct debug_el, list);
|
||||||
|
el1 = container_of(cur->next, struct debug_el, list);
|
||||||
|
if (cmp_result == 0 && el->serial >= el1->serial) {
|
||||||
|
pr_err("error: order of equivalent elements not "
|
||||||
|
"preserved\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check(el, el1)) {
|
||||||
|
pr_err("error: element check failed\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if (head.prev != cur) {
|
||||||
|
pr_err("error: list is corrupted\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (count != TEST_LIST_LEN) {
|
||||||
|
pr_err("error: bad list length %d", count);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
exit:
|
||||||
|
for (i = 0; i < TEST_LIST_LEN; i++)
|
||||||
|
kfree(elts[i]);
|
||||||
|
kfree(elts);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
late_initcall(list_sort_test);
|
||||||
|
#endif /* CONFIG_TEST_LIST_SORT */
|
||||||
|
@ -90,20 +90,20 @@ size_t strlcpy(char *dest, const char *src, size_t size)
|
|||||||
*/
|
*/
|
||||||
size_t strlcat(char *dest, const char *src, size_t count)
|
size_t strlcat(char *dest, const char *src, size_t count)
|
||||||
{
|
{
|
||||||
size_t dsize = strlen(dest);
|
size_t dsize = strlen(dest);
|
||||||
size_t len = strlen(src);
|
size_t len = strlen(src);
|
||||||
size_t res = dsize + len;
|
size_t res = dsize + len;
|
||||||
|
|
||||||
/* This would be a bug */
|
/* This would be a bug */
|
||||||
BUG_ON(dsize >= count);
|
BUG_ON(dsize >= count);
|
||||||
|
|
||||||
dest += dsize;
|
dest += dsize;
|
||||||
count -= dsize;
|
count -= dsize;
|
||||||
if (len >= count)
|
if (len >= count)
|
||||||
len = count-1;
|
len = count-1;
|
||||||
memcpy(dest, src, len);
|
memcpy(dest, src, len);
|
||||||
dest[len] = 0;
|
dest[len] = 0;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ void __stdcall delayed_work_timer_fn(unsigned long __data)
|
|||||||
queue_work(wq, &dwork->work);
|
queue_work(wq, &dwork->work);
|
||||||
}
|
}
|
||||||
|
|
||||||
int queue_delayed_work(struct workqueue_struct *wq,
|
bool queue_delayed_work(struct workqueue_struct *wq,
|
||||||
struct delayed_work *dwork, unsigned long delay)
|
struct delayed_work *dwork, unsigned long delay)
|
||||||
{
|
{
|
||||||
struct work_struct *work = &dwork->work;
|
struct work_struct *work = &dwork->work;
|
||||||
@ -138,12 +138,12 @@ bool schedule_delayed_work(struct delayed_work *dwork, unsigned long delay)
|
|||||||
return queue_delayed_work(system_wq, dwork, delay);
|
return queue_delayed_work(system_wq, dwork, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mod_delayed_work(struct workqueue_struct *wq,
|
//bool mod_delayed_work(struct workqueue_struct *wq,
|
||||||
struct delayed_work *dwork,
|
// struct delayed_work *dwork,
|
||||||
unsigned long delay)
|
// unsigned long delay)
|
||||||
{
|
//{
|
||||||
return queue_delayed_work(wq, dwork, delay);
|
// return queue_delayed_work(wq, dwork, delay);
|
||||||
}
|
//}
|
||||||
|
|
||||||
int del_timer(struct timer_list *timer)
|
int del_timer(struct timer_list *timer)
|
||||||
{
|
{
|
||||||
|
@ -649,9 +649,9 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
|
|||||||
#define NO_SEGMENT_TRAVERSAL 1
|
#define NO_SEGMENT_TRAVERSAL 1
|
||||||
#define MALLOC_ALIGNMENT ((size_t)8U)
|
#define MALLOC_ALIGNMENT ((size_t)8U)
|
||||||
#define CHUNK_OVERHEAD (SIZE_T_SIZE)
|
#define CHUNK_OVERHEAD (SIZE_T_SIZE)
|
||||||
#define DEFAULT_GRANULARITY ((size_t)128U * (size_t)1024U)
|
#define DEFAULT_GRANULARITY ((size_t)256U * (size_t)1024U)
|
||||||
#define DEFAULT_MMAP_THRESHOLD ((size_t)512U * (size_t)1024U)
|
#define DEFAULT_MMAP_THRESHOLD ((size_t)1024U * (size_t)1024U)
|
||||||
#define DEFAULT_TRIM_THRESHOLD ((size_t)1024U * (size_t)1024U)
|
#define DEFAULT_TRIM_THRESHOLD ((size_t)2048U * (size_t)1024U)
|
||||||
|
|
||||||
/* The bit mask value corresponding to MALLOC_ALIGNMENT */
|
/* The bit mask value corresponding to MALLOC_ALIGNMENT */
|
||||||
#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE)
|
#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -126,8 +126,9 @@ struct acpi_exception_info {
|
|||||||
#define AE_OWNER_ID_LIMIT EXCEP_ENV (0x001B)
|
#define AE_OWNER_ID_LIMIT EXCEP_ENV (0x001B)
|
||||||
#define AE_NOT_CONFIGURED EXCEP_ENV (0x001C)
|
#define AE_NOT_CONFIGURED EXCEP_ENV (0x001C)
|
||||||
#define AE_ACCESS EXCEP_ENV (0x001D)
|
#define AE_ACCESS EXCEP_ENV (0x001D)
|
||||||
|
#define AE_IO_ERROR EXCEP_ENV (0x001E)
|
||||||
|
|
||||||
#define AE_CODE_ENV_MAX 0x001D
|
#define AE_CODE_ENV_MAX 0x001E
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Programmer exceptions
|
* Programmer exceptions
|
||||||
@ -263,7 +264,8 @@ static const struct acpi_exception_info acpi_gbl_exception_names_env[] = {
|
|||||||
"There are no more Owner IDs available for ACPI tables or control methods"),
|
"There are no more Owner IDs available for ACPI tables or control methods"),
|
||||||
EXCEP_TXT("AE_NOT_CONFIGURED",
|
EXCEP_TXT("AE_NOT_CONFIGURED",
|
||||||
"The interface is not part of the current subsystem configuration"),
|
"The interface is not part of the current subsystem configuration"),
|
||||||
EXCEP_TXT("AE_ACCESS", "Permission denied for the requested operation")
|
EXCEP_TXT("AE_ACCESS", "Permission denied for the requested operation"),
|
||||||
|
EXCEP_TXT("AE_IO_ERROR", "An I/O error occurred")
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct acpi_exception_info acpi_gbl_exception_names_pgm[] = {
|
static const struct acpi_exception_info acpi_gbl_exception_names_pgm[] = {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -262,7 +262,7 @@
|
|||||||
#define ACPI_GET_FUNCTION_NAME _acpi_function_name
|
#define ACPI_GET_FUNCTION_NAME _acpi_function_name
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Name parameter should be the procedure name as a quoted string.
|
* The Name parameter should be the procedure name as a non-quoted string.
|
||||||
* The function name is also used by the function exit macros below.
|
* The function name is also used by the function exit macros below.
|
||||||
* Note: (const char) is used to be compatible with the debug interfaces
|
* Note: (const char) is used to be compatible with the debug interfaces
|
||||||
* and macros such as __func__.
|
* and macros such as __func__.
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -87,6 +87,8 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, int rev, int func,
|
|||||||
.package.elements = (eles) \
|
.package.elements = (eles) \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool acpi_dev_present(const char *hid);
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
|
|
||||||
#define ACPI_BUS_FILE_ROOT "acpi"
|
#define ACPI_BUS_FILE_ROOT "acpi"
|
||||||
@ -389,13 +391,13 @@ struct acpi_data_node {
|
|||||||
|
|
||||||
static inline bool is_acpi_node(struct fwnode_handle *fwnode)
|
static inline bool is_acpi_node(struct fwnode_handle *fwnode)
|
||||||
{
|
{
|
||||||
return fwnode && (fwnode->type == FWNODE_ACPI
|
return !IS_ERR_OR_NULL(fwnode) && (fwnode->type == FWNODE_ACPI
|
||||||
|| fwnode->type == FWNODE_ACPI_DATA);
|
|| fwnode->type == FWNODE_ACPI_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
|
static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
|
||||||
{
|
{
|
||||||
return fwnode && fwnode->type == FWNODE_ACPI;
|
return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_ACPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)
|
static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)
|
||||||
@ -626,7 +628,9 @@ static inline bool acpi_device_can_wakeup(struct acpi_device *adev)
|
|||||||
|
|
||||||
static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
|
static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
|
||||||
{
|
{
|
||||||
return adev->power.states[ACPI_STATE_D3_COLD].flags.valid;
|
return adev->power.states[ACPI_STATE_D3_COLD].flags.valid ||
|
||||||
|
((acpi_gbl_FADT.header.revision < 6) &&
|
||||||
|
adev->power.states[ACPI_STATE_D3_HOT].flags.explicit_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CONFIG_ACPI */
|
#else /* CONFIG_ACPI */
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
#include <asm/acpi.h>
|
#include <asm/acpi.h>
|
||||||
|
|
||||||
|
|
||||||
void acpi_os_map_iomem(acpi_physical_address phys, acpi_size size);
|
acpi_os_map_iomem(acpi_physical_address phys, acpi_size size);
|
||||||
void acpi_os_unmap_iomem(void __iomem *virt, acpi_size size);
|
void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size);
|
||||||
void *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
|
void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
|
||||||
|
|
||||||
int acpi_os_map_generic_address(struct acpi_generic_address *addr);
|
int acpi_os_map_generic_address(struct acpi_generic_address *addr);
|
||||||
void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
|
void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -349,12 +349,28 @@ void acpi_os_redirect_output(void *destination);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Debug input
|
* Debug IO
|
||||||
*/
|
*/
|
||||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line
|
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line
|
||||||
acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read);
|
acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
|
||||||
|
acpi_status acpi_os_initialize_command_signals(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
|
||||||
|
void acpi_os_terminate_command_signals(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
|
||||||
|
acpi_status acpi_os_wait_command_ready(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
|
||||||
|
acpi_status acpi_os_notify_command_complete(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtain ACPI table(s)
|
* Obtain ACPI table(s)
|
||||||
*/
|
*/
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||||||
|
|
||||||
#define ACPI_CA_VERSION 0x20150930
|
#define ACPI_CA_VERSION 0x20160108
|
||||||
|
|
||||||
#include <acpi/acconfig.h>
|
#include <acpi/acconfig.h>
|
||||||
#include <acpi/actypes.h>
|
#include <acpi/actypes.h>
|
||||||
@ -189,6 +189,11 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_copy_dsdt_locally, FALSE);
|
|||||||
*/
|
*/
|
||||||
ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE);
|
ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Optionally support group module level code.
|
||||||
|
*/
|
||||||
|
ACPI_INIT_GLOBAL(u8, acpi_gbl_group_module_level_code, TRUE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optionally use 32-bit FADT addresses if and when there is a conflict
|
* Optionally use 32-bit FADT addresses if and when there is a conflict
|
||||||
* (address mismatch) between the 32-bit and 64-bit versions of the
|
* (address mismatch) between the 32-bit and 64-bit versions of the
|
||||||
@ -263,6 +268,19 @@ ACPI_INIT_GLOBAL(u32, acpi_gbl_trace_dbg_layer, ACPI_TRACE_LAYER_DEFAULT);
|
|||||||
ACPI_INIT_GLOBAL(u32, acpi_dbg_level, ACPI_DEBUG_DEFAULT);
|
ACPI_INIT_GLOBAL(u32, acpi_dbg_level, ACPI_DEBUG_DEFAULT);
|
||||||
ACPI_INIT_GLOBAL(u32, acpi_dbg_layer, 0);
|
ACPI_INIT_GLOBAL(u32, acpi_dbg_layer, 0);
|
||||||
|
|
||||||
|
/* Optionally enable timer output with Debug Object output */
|
||||||
|
|
||||||
|
ACPI_INIT_GLOBAL(u8, acpi_gbl_display_debug_timer, FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debugger command handshake globals. Host OSes need to access these
|
||||||
|
* variables to implement their own command handshake mechanism.
|
||||||
|
*/
|
||||||
|
#ifdef ACPI_DEBUGGER
|
||||||
|
ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
|
||||||
|
ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Other miscellaneous globals
|
* Other miscellaneous globals
|
||||||
*/
|
*/
|
||||||
@ -366,6 +384,29 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running);
|
|||||||
|
|
||||||
#endif /* ACPI_APPLICATION */
|
#endif /* ACPI_APPLICATION */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debugger prototypes
|
||||||
|
*
|
||||||
|
* All interfaces used by debugger will be configured
|
||||||
|
* out of the ACPICA build unless the ACPI_DEBUGGER
|
||||||
|
* flag is defined.
|
||||||
|
*/
|
||||||
|
#ifdef ACPI_DEBUGGER
|
||||||
|
#define ACPI_DBR_DEPENDENT_RETURN_OK(prototype) \
|
||||||
|
ACPI_EXTERNAL_RETURN_OK(prototype)
|
||||||
|
|
||||||
|
#define ACPI_DBR_DEPENDENT_RETURN_VOID(prototype) \
|
||||||
|
ACPI_EXTERNAL_RETURN_VOID(prototype)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define ACPI_DBR_DEPENDENT_RETURN_OK(prototype) \
|
||||||
|
static ACPI_INLINE prototype {return(AE_OK);}
|
||||||
|
|
||||||
|
#define ACPI_DBR_DEPENDENT_RETURN_VOID(prototype) \
|
||||||
|
static ACPI_INLINE prototype {return;}
|
||||||
|
|
||||||
|
#endif /* ACPI_DEBUGGER */
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* ACPICA public interface prototypes
|
* ACPICA public interface prototypes
|
||||||
@ -822,17 +863,9 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
|||||||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_leave_sleep_state(u8 sleep_state))
|
ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_leave_sleep_state(u8 sleep_state))
|
||||||
|
|
||||||
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
|
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
|
||||||
acpi_set_firmware_waking_vectors
|
acpi_set_firmware_waking_vector
|
||||||
(acpi_physical_address physical_address,
|
(acpi_physical_address physical_address,
|
||||||
acpi_physical_address physical_address64))
|
acpi_physical_address physical_address64))
|
||||||
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
|
|
||||||
acpi_set_firmware_waking_vector(u32
|
|
||||||
physical_address))
|
|
||||||
#if ACPI_MACHINE_WIDTH == 64
|
|
||||||
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
|
|
||||||
acpi_set_firmware_waking_vector64(u64
|
|
||||||
physical_address))
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* ACPI Timer interfaces
|
* ACPI Timer interfaces
|
||||||
*/
|
*/
|
||||||
@ -864,11 +897,9 @@ ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3)
|
|||||||
acpi_warning(const char *module_name,
|
acpi_warning(const char *module_name,
|
||||||
u32 line_number,
|
u32 line_number,
|
||||||
const char *format, ...))
|
const char *format, ...))
|
||||||
ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3)
|
ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(1)
|
||||||
void ACPI_INTERNAL_VAR_XFACE
|
void ACPI_INTERNAL_VAR_XFACE
|
||||||
acpi_info(const char *module_name,
|
acpi_info(const char *format, ...))
|
||||||
u32 line_number,
|
|
||||||
const char *format, ...))
|
|
||||||
ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3)
|
ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3)
|
||||||
void ACPI_INTERNAL_VAR_XFACE
|
void ACPI_INTERNAL_VAR_XFACE
|
||||||
acpi_bios_error(const char *module_name,
|
acpi_bios_error(const char *module_name,
|
||||||
@ -929,6 +960,8 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
|||||||
void **data,
|
void **data,
|
||||||
void (*callback)(void *)))
|
void (*callback)(void *)))
|
||||||
|
|
||||||
|
void acpi_run_debugger(char *batch_buffer);
|
||||||
|
|
||||||
void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
|
void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
|
||||||
|
|
||||||
#endif /* __ACXFACE_H__ */
|
#endif /* __ACXFACE_H__ */
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -1148,7 +1148,7 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);
|
|||||||
|
|
||||||
#define ACPI_PCICLS_STRING_SIZE 7 /* Includes null terminator */
|
#define ACPI_PCICLS_STRING_SIZE 7 /* Includes null terminator */
|
||||||
|
|
||||||
/* Structures used for device/processor HID, UID, CID, and SUB */
|
/* Structures used for device/processor HID, UID, CID */
|
||||||
|
|
||||||
struct acpi_pnp_device_id {
|
struct acpi_pnp_device_id {
|
||||||
u32 length; /* Length of string + null */
|
u32 length; /* Length of string + null */
|
||||||
@ -1178,7 +1178,6 @@ struct acpi_device_info {
|
|||||||
u64 address; /* _ADR value */
|
u64 address; /* _ADR value */
|
||||||
struct acpi_pnp_device_id hardware_id; /* _HID value */
|
struct acpi_pnp_device_id hardware_id; /* _HID value */
|
||||||
struct acpi_pnp_device_id unique_id; /* _UID value */
|
struct acpi_pnp_device_id unique_id; /* _UID value */
|
||||||
struct acpi_pnp_device_id subsystem_id; /* _SUB value */
|
|
||||||
struct acpi_pnp_device_id class_code; /* _CLS value */
|
struct acpi_pnp_device_id class_code; /* _CLS value */
|
||||||
struct acpi_pnp_device_id_list compatible_id_list; /* _CID list <must be last> */
|
struct acpi_pnp_device_id_list compatible_id_list; /* _CID list <must be last> */
|
||||||
};
|
};
|
||||||
@ -1193,13 +1192,12 @@ struct acpi_device_info {
|
|||||||
#define ACPI_VALID_ADR 0x0002
|
#define ACPI_VALID_ADR 0x0002
|
||||||
#define ACPI_VALID_HID 0x0004
|
#define ACPI_VALID_HID 0x0004
|
||||||
#define ACPI_VALID_UID 0x0008
|
#define ACPI_VALID_UID 0x0008
|
||||||
#define ACPI_VALID_SUB 0x0010
|
|
||||||
#define ACPI_VALID_CID 0x0020
|
#define ACPI_VALID_CID 0x0020
|
||||||
#define ACPI_VALID_CLS 0x0040
|
#define ACPI_VALID_CLS 0x0040
|
||||||
#define ACPI_VALID_SXDS 0x0100
|
#define ACPI_VALID_SXDS 0x0100
|
||||||
#define ACPI_VALID_SXWS 0x0200
|
#define ACPI_VALID_SXWS 0x0200
|
||||||
|
|
||||||
/* Flags for _STA return value (current_status above) */
|
/* Flags for _STA method */
|
||||||
|
|
||||||
#define ACPI_STA_DEVICE_PRESENT 0x01
|
#define ACPI_STA_DEVICE_PRESENT 0x01
|
||||||
#define ACPI_STA_DEVICE_ENABLED 0x02
|
#define ACPI_STA_DEVICE_ENABLED 0x02
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -150,6 +150,8 @@
|
|||||||
*/
|
*/
|
||||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
|
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
|
||||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
|
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
|
||||||
|
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
|
||||||
|
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OSL interfaces used by utilities
|
* OSL interfaces used by utilities
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2000 - 2015, Intel Corp.
|
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -127,6 +127,16 @@ static inline u8 acpi_os_readable(void *pointer, acpi_size length)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline acpi_status acpi_os_initialize_command_signals(void)
|
||||||
|
{
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void acpi_os_terminate_command_signals(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OSL interfaces added by Linux
|
* OSL interfaces added by Linux
|
||||||
*/
|
*/
|
||||||
|
@ -98,14 +98,14 @@ ATOMIC_LONG_ADD_SUB_OP(sub, _release)
|
|||||||
#define atomic_long_xchg(v, new) \
|
#define atomic_long_xchg(v, new) \
|
||||||
(ATOMIC_LONG_PFX(_xchg)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
|
(ATOMIC_LONG_PFX(_xchg)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
|
||||||
|
|
||||||
static inline void atomic_long_inc(atomic_long_t *l)
|
static __always_inline void atomic_long_inc(atomic_long_t *l)
|
||||||
{
|
{
|
||||||
ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
|
ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
|
||||||
|
|
||||||
ATOMIC_LONG_PFX(_inc)(v);
|
ATOMIC_LONG_PFX(_inc)(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void atomic_long_dec(atomic_long_t *l)
|
static __always_inline void atomic_long_dec(atomic_long_t *l)
|
||||||
{
|
{
|
||||||
ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
|
ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ static inline void atomic_long_dec(atomic_long_t *l)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define ATOMIC_LONG_OP(op) \
|
#define ATOMIC_LONG_OP(op) \
|
||||||
static inline void \
|
static __always_inline void \
|
||||||
atomic_long_##op(long i, atomic_long_t *l) \
|
atomic_long_##op(long i, atomic_long_t *l) \
|
||||||
{ \
|
{ \
|
||||||
ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
|
ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
|
||||||
|
@ -81,6 +81,12 @@ extern void warn_slowpath_null(const char *file, const int line);
|
|||||||
do { printk(arg); __WARN_TAINT(taint); } while (0)
|
do { printk(arg); __WARN_TAINT(taint); } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* used internally by panic.c */
|
||||||
|
struct warn_args;
|
||||||
|
|
||||||
|
void __warn(const char *file, int line, void *caller, unsigned taint,
|
||||||
|
struct pt_regs *regs, struct warn_args *args);
|
||||||
|
|
||||||
#ifndef WARN_ON
|
#ifndef WARN_ON
|
||||||
#define WARN_ON(condition) ({ \
|
#define WARN_ON(condition) ({ \
|
||||||
int __ret_warn_on = !!(condition); \
|
int __ret_warn_on = !!(condition); \
|
||||||
@ -110,9 +116,10 @@ extern void warn_slowpath_null(const char *file, const int line);
|
|||||||
static bool __section(.data.unlikely) __warned; \
|
static bool __section(.data.unlikely) __warned; \
|
||||||
int __ret_warn_once = !!(condition); \
|
int __ret_warn_once = !!(condition); \
|
||||||
\
|
\
|
||||||
if (unlikely(__ret_warn_once)) \
|
if (unlikely(__ret_warn_once && !__warned)) { \
|
||||||
if (WARN_ON(!__warned)) \
|
__warned = true; \
|
||||||
__warned = true; \
|
WARN_ON(1); \
|
||||||
|
} \
|
||||||
unlikely(__ret_warn_once); \
|
unlikely(__ret_warn_once); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -120,9 +127,10 @@ extern void warn_slowpath_null(const char *file, const int line);
|
|||||||
static bool __section(.data.unlikely) __warned; \
|
static bool __section(.data.unlikely) __warned; \
|
||||||
int __ret_warn_once = !!(condition); \
|
int __ret_warn_once = !!(condition); \
|
||||||
\
|
\
|
||||||
if (unlikely(__ret_warn_once)) \
|
if (unlikely(__ret_warn_once && !__warned)) { \
|
||||||
if (WARN(!__warned, format)) \
|
__warned = true; \
|
||||||
__warned = true; \
|
WARN(1, format); \
|
||||||
|
} \
|
||||||
unlikely(__ret_warn_once); \
|
unlikely(__ret_warn_once); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -130,9 +138,10 @@ extern void warn_slowpath_null(const char *file, const int line);
|
|||||||
static bool __section(.data.unlikely) __warned; \
|
static bool __section(.data.unlikely) __warned; \
|
||||||
int __ret_warn_once = !!(condition); \
|
int __ret_warn_once = !!(condition); \
|
||||||
\
|
\
|
||||||
if (unlikely(__ret_warn_once)) \
|
if (unlikely(__ret_warn_once && !__warned)) { \
|
||||||
if (WARN_TAINT(!__warned, taint, format)) \
|
__warned = true; \
|
||||||
__warned = true; \
|
WARN_TAINT(1, taint, format); \
|
||||||
|
} \
|
||||||
unlikely(__ret_warn_once); \
|
unlikely(__ret_warn_once); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -142,7 +151,7 @@ extern void warn_slowpath_null(const char *file, const int line);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_ARCH_BUG_ON
|
#ifndef HAVE_ARCH_BUG_ON
|
||||||
#define BUG_ON(condition) do { if (condition) ; } while (0)
|
#define BUG_ON(condition) do { if (condition) BUG(); } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_ARCH_WARN_ON
|
#ifndef HAVE_ARCH_WARN_ON
|
||||||
|
@ -70,12 +70,12 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Return a pointer with offset calculated */
|
/* Return a pointer with offset calculated */
|
||||||
#define __set_fixmap_offset(idx, phys, flags) \
|
#define __set_fixmap_offset(idx, phys, flags) \
|
||||||
({ \
|
({ \
|
||||||
unsigned long addr; \
|
unsigned long ________addr; \
|
||||||
__set_fixmap(idx, phys, flags); \
|
__set_fixmap(idx, phys, flags); \
|
||||||
addr = fix_to_virt(idx) + ((phys) & (PAGE_SIZE - 1)); \
|
________addr = fix_to_virt(idx) + ((phys) & (PAGE_SIZE - 1)); \
|
||||||
addr; \
|
________addr; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define set_fixmap_offset(idx, phys) \
|
#define set_fixmap_offset(idx, phys) \
|
||||||
|
@ -54,10 +54,6 @@ pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
#define pci_map_page(dev, page, offset, size, direction) \
|
|
||||||
(dma_addr_t)( (offset)+page_to_phys(page))
|
|
||||||
|
|
||||||
#define pci_unmap_page(dev, dma_address, size, direction)
|
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
|
pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
|
||||||
|
@ -151,12 +151,6 @@ static inline int alternatives_text_reserved(void *start, void *end)
|
|||||||
ALTINSTR_REPLACEMENT(newinstr2, feature2, 2) \
|
ALTINSTR_REPLACEMENT(newinstr2, feature2, 2) \
|
||||||
".popsection"
|
".popsection"
|
||||||
|
|
||||||
/*
|
|
||||||
* This must be included *after* the definition of ALTERNATIVE due to
|
|
||||||
* <asm/arch_hweight.h>
|
|
||||||
*/
|
|
||||||
#include <asm/cpufeature.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Alternative instructions for different CPU types or capabilities.
|
* Alternative instructions for different CPU types or capabilities.
|
||||||
*
|
*
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef _ASM_X86_HWEIGHT_H
|
#ifndef _ASM_X86_HWEIGHT_H
|
||||||
#define _ASM_X86_HWEIGHT_H
|
#define _ASM_X86_HWEIGHT_H
|
||||||
|
|
||||||
|
#include <asm/cpufeatures.h>
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
/* popcnt %edi, %eax -- redundant REX prefix for alignment */
|
/* popcnt %edi, %eax -- redundant REX prefix for alignment */
|
||||||
#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
|
#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
|
||||||
|
@ -44,19 +44,22 @@
|
|||||||
|
|
||||||
/* Exception table entry */
|
/* Exception table entry */
|
||||||
#ifdef __ASSEMBLY__
|
#ifdef __ASSEMBLY__
|
||||||
# define _ASM_EXTABLE(from,to) \
|
# define _ASM_EXTABLE_HANDLE(from, to, handler) \
|
||||||
.pushsection "__ex_table","a" ; \
|
.pushsection "__ex_table","a" ; \
|
||||||
.balign 8 ; \
|
.balign 4 ; \
|
||||||
.long (from) - . ; \
|
.long (from) - . ; \
|
||||||
.long (to) - . ; \
|
.long (to) - . ; \
|
||||||
|
.long (handler) - . ; \
|
||||||
.popsection
|
.popsection
|
||||||
|
|
||||||
# define _ASM_EXTABLE_EX(from,to) \
|
# define _ASM_EXTABLE(from, to) \
|
||||||
.pushsection "__ex_table","a" ; \
|
_ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
|
||||||
.balign 8 ; \
|
|
||||||
.long (from) - . ; \
|
# define _ASM_EXTABLE_FAULT(from, to) \
|
||||||
.long (to) - . + 0x7ffffff0 ; \
|
_ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
|
||||||
.popsection
|
|
||||||
|
# define _ASM_EXTABLE_EX(from, to) \
|
||||||
|
_ASM_EXTABLE_HANDLE(from, to, ex_handler_ext)
|
||||||
|
|
||||||
# define _ASM_NOKPROBE(entry) \
|
# define _ASM_NOKPROBE(entry) \
|
||||||
.pushsection "_kprobe_blacklist","aw" ; \
|
.pushsection "_kprobe_blacklist","aw" ; \
|
||||||
@ -89,19 +92,24 @@
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# define _ASM_EXTABLE(from,to) \
|
# define _EXPAND_EXTABLE_HANDLE(x) #x
|
||||||
|
# define _ASM_EXTABLE_HANDLE(from, to, handler) \
|
||||||
" .pushsection \"__ex_table\",\"a\"\n" \
|
" .pushsection \"__ex_table\",\"a\"\n" \
|
||||||
" .balign 8\n" \
|
" .balign 4\n" \
|
||||||
" .long (" #from ") - .\n" \
|
" .long (" #from ") - .\n" \
|
||||||
" .long (" #to ") - .\n" \
|
" .long (" #to ") - .\n" \
|
||||||
|
" .long (" _EXPAND_EXTABLE_HANDLE(handler) ") - .\n" \
|
||||||
" .popsection\n"
|
" .popsection\n"
|
||||||
|
|
||||||
# define _ASM_EXTABLE_EX(from,to) \
|
# define _ASM_EXTABLE(from, to) \
|
||||||
" .pushsection \"__ex_table\",\"a\"\n" \
|
_ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
|
||||||
" .balign 8\n" \
|
|
||||||
" .long (" #from ") - .\n" \
|
# define _ASM_EXTABLE_FAULT(from, to) \
|
||||||
" .long (" #to ") - . + 0x7ffffff0\n" \
|
_ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
|
||||||
" .popsection\n"
|
|
||||||
|
# define _ASM_EXTABLE_EX(from, to) \
|
||||||
|
_ASM_EXTABLE_HANDLE(from, to, ex_handler_ext)
|
||||||
|
|
||||||
/* For C file, we already have NOKPROBE_SYMBOL macro */
|
/* For C file, we already have NOKPROBE_SYMBOL macro */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,441 +0,0 @@
|
|||||||
#ifndef _ASM_X86_ATOMIC_32_H
|
|
||||||
#define _ASM_X86_ATOMIC_32_H
|
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
#include <asm/cmpxchg.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Atomic operations that C can't guarantee us. Useful for
|
|
||||||
* resource counting etc..
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ATOMIC_INIT(i) { (i) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_read - read atomic variable
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
*
|
|
||||||
* Atomically reads the value of @v.
|
|
||||||
*/
|
|
||||||
static inline int atomic_read(const atomic_t *v)
|
|
||||||
{
|
|
||||||
return v->counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_set - set atomic variable
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
* @i: required value
|
|
||||||
*
|
|
||||||
* Atomically sets the value of @v to @i.
|
|
||||||
*/
|
|
||||||
static inline void atomic_set(atomic_t *v, int i)
|
|
||||||
{
|
|
||||||
v->counter = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_add - add integer to atomic variable
|
|
||||||
* @i: integer value to add
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
*
|
|
||||||
* Atomically adds @i to @v.
|
|
||||||
*/
|
|
||||||
static inline void atomic_add(int i, atomic_t *v)
|
|
||||||
{
|
|
||||||
asm volatile(LOCK_PREFIX "addl %1,%0"
|
|
||||||
: "+m" (v->counter)
|
|
||||||
: "ir" (i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_sub - subtract integer from atomic variable
|
|
||||||
* @i: integer value to subtract
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
*
|
|
||||||
* Atomically subtracts @i from @v.
|
|
||||||
*/
|
|
||||||
static inline void atomic_sub(int i, atomic_t *v)
|
|
||||||
{
|
|
||||||
asm volatile(LOCK_PREFIX "subl %1,%0"
|
|
||||||
: "+m" (v->counter)
|
|
||||||
: "ir" (i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_sub_and_test - subtract value from variable and test result
|
|
||||||
* @i: integer value to subtract
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
*
|
|
||||||
* Atomically subtracts @i from @v and returns
|
|
||||||
* true if the result is zero, or false for all
|
|
||||||
* other cases.
|
|
||||||
*/
|
|
||||||
static inline int atomic_sub_and_test(int i, atomic_t *v)
|
|
||||||
{
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
|
|
||||||
: "+m" (v->counter), "=qm" (c)
|
|
||||||
: "ir" (i) : "memory");
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_inc - increment atomic variable
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
*
|
|
||||||
* Atomically increments @v by 1.
|
|
||||||
*/
|
|
||||||
static inline void atomic_inc(atomic_t *v)
|
|
||||||
{
|
|
||||||
asm volatile(LOCK_PREFIX "incl %0"
|
|
||||||
: "+m" (v->counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_dec - decrement atomic variable
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
*
|
|
||||||
* Atomically decrements @v by 1.
|
|
||||||
*/
|
|
||||||
static inline void atomic_dec(atomic_t *v)
|
|
||||||
{
|
|
||||||
asm volatile(LOCK_PREFIX "decl %0"
|
|
||||||
: "+m" (v->counter));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_dec_and_test - decrement and test
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
*
|
|
||||||
* Atomically decrements @v by 1 and
|
|
||||||
* returns true if the result is 0, or false for all other
|
|
||||||
* cases.
|
|
||||||
*/
|
|
||||||
static inline int atomic_dec_and_test(atomic_t *v)
|
|
||||||
{
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
asm volatile(LOCK_PREFIX "decl %0; sete %1"
|
|
||||||
: "+m" (v->counter), "=qm" (c)
|
|
||||||
: : "memory");
|
|
||||||
return c != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_inc_and_test - increment and test
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
*
|
|
||||||
* Atomically increments @v by 1
|
|
||||||
* and returns true if the result is zero, or false for all
|
|
||||||
* other cases.
|
|
||||||
*/
|
|
||||||
static inline int atomic_inc_and_test(atomic_t *v)
|
|
||||||
{
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
asm volatile(LOCK_PREFIX "incl %0; sete %1"
|
|
||||||
: "+m" (v->counter), "=qm" (c)
|
|
||||||
: : "memory");
|
|
||||||
return c != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_add_negative - add and test if negative
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
* @i: integer value to add
|
|
||||||
*
|
|
||||||
* Atomically adds @i to @v and returns true
|
|
||||||
* if the result is negative, or false when
|
|
||||||
* result is greater than or equal to zero.
|
|
||||||
*/
|
|
||||||
static inline int atomic_add_negative(int i, atomic_t *v)
|
|
||||||
{
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
|
|
||||||
: "+m" (v->counter), "=qm" (c)
|
|
||||||
: "ir" (i) : "memory");
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_add_return - add integer and return
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
* @i: integer value to add
|
|
||||||
*
|
|
||||||
* Atomically adds @i to @v and returns @i + @v
|
|
||||||
*/
|
|
||||||
static inline int atomic_add_return(int i, atomic_t *v)
|
|
||||||
{
|
|
||||||
int __i;
|
|
||||||
#ifdef CONFIG_M386
|
|
||||||
unsigned long flags;
|
|
||||||
if (unlikely(boot_cpu_data.x86 <= 3))
|
|
||||||
goto no_xadd;
|
|
||||||
#endif
|
|
||||||
/* Modern 486+ processor */
|
|
||||||
__i = i;
|
|
||||||
asm volatile(LOCK_PREFIX "xaddl %0, %1"
|
|
||||||
: "+r" (i), "+m" (v->counter)
|
|
||||||
: : "memory");
|
|
||||||
return i + __i;
|
|
||||||
|
|
||||||
#ifdef CONFIG_M386
|
|
||||||
no_xadd: /* Legacy 386 processor */
|
|
||||||
local_irq_save(flags);
|
|
||||||
__i = atomic_read(v);
|
|
||||||
atomic_set(v, i + __i);
|
|
||||||
local_irq_restore(flags);
|
|
||||||
return i + __i;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_sub_return - subtract integer and return
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
* @i: integer value to subtract
|
|
||||||
*
|
|
||||||
* Atomically subtracts @i from @v and returns @v - @i
|
|
||||||
*/
|
|
||||||
static inline int atomic_sub_return(int i, atomic_t *v)
|
|
||||||
{
|
|
||||||
return atomic_add_return(-i, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
|
|
||||||
{
|
|
||||||
return cmpxchg(&v->counter, old, new);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int atomic_xchg(atomic_t *v, int new)
|
|
||||||
{
|
|
||||||
return xchg(&v->counter, new);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic_add_unless - add unless the number is already a given value
|
|
||||||
* @v: pointer of type atomic_t
|
|
||||||
* @a: the amount to add to v...
|
|
||||||
* @u: ...unless v is equal to u.
|
|
||||||
*
|
|
||||||
* Atomically adds @a to @v, so long as @v was not already @u.
|
|
||||||
* Returns non-zero if @v was not @u, and zero otherwise.
|
|
||||||
*/
|
|
||||||
static inline int atomic_add_unless(atomic_t *v, int a, int u)
|
|
||||||
{
|
|
||||||
int c, old;
|
|
||||||
c = atomic_read(v);
|
|
||||||
for (;;) {
|
|
||||||
if (unlikely(c == (u)))
|
|
||||||
break;
|
|
||||||
old = atomic_cmpxchg((v), c, c + (a));
|
|
||||||
if (likely(old == c))
|
|
||||||
break;
|
|
||||||
c = old;
|
|
||||||
}
|
|
||||||
return c != (u);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
|
|
||||||
|
|
||||||
#define atomic_inc_return(v) (atomic_add_return(1, v))
|
|
||||||
#define atomic_dec_return(v) (atomic_sub_return(1, v))
|
|
||||||
|
|
||||||
/* These are x86-specific, used by some header files */
|
|
||||||
#define atomic_clear_mask(mask, addr) \
|
|
||||||
asm volatile(LOCK_PREFIX "andl %0,%1" \
|
|
||||||
: : "r" (~(mask)), "m" (*(addr)) : "memory")
|
|
||||||
|
|
||||||
#define atomic_set_mask(mask, addr) \
|
|
||||||
asm volatile(LOCK_PREFIX "orl %0,%1" \
|
|
||||||
: : "r" (mask), "m" (*(addr)) : "memory")
|
|
||||||
|
|
||||||
/* Atomic operations are already serializing on x86 */
|
|
||||||
#define smp_mb__before_atomic_dec() barrier()
|
|
||||||
#define smp_mb__after_atomic_dec() barrier()
|
|
||||||
#define smp_mb__before_atomic_inc() barrier()
|
|
||||||
#define smp_mb__after_atomic_inc() barrier()
|
|
||||||
|
|
||||||
/* An 64bit atomic type */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u64 __aligned(8) counter;
|
|
||||||
} atomic64_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_xchg - xchg atomic64 variable
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
* @new_val: value to assign
|
|
||||||
*
|
|
||||||
* Atomically xchgs the value of @ptr to @new_val and returns
|
|
||||||
* the old value.
|
|
||||||
*/
|
|
||||||
static inline long long atomic64_xchg(atomic64_t *v, long long n)
|
|
||||||
{
|
|
||||||
long long o;
|
|
||||||
unsigned high = (unsigned)(n >> 32);
|
|
||||||
unsigned low = (unsigned)n;
|
|
||||||
|
|
||||||
asm volatile(
|
|
||||||
"1: \n\t"
|
|
||||||
"cmpxchg8b (%%esi) \n\t"
|
|
||||||
"jnz 1b \n\t"
|
|
||||||
:"=&A" (o)
|
|
||||||
:"S" (v), "b" (low), "c" (high)
|
|
||||||
: "memory", "cc");
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_set - set atomic64 variable
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
* @new_val: value to assign
|
|
||||||
*
|
|
||||||
* Atomically sets the value of @ptr to @new_val.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void atomic64_set(atomic64_t *v, long long i)
|
|
||||||
{
|
|
||||||
unsigned high = (unsigned)(i >> 32);
|
|
||||||
unsigned low = (unsigned)i;
|
|
||||||
asm volatile (
|
|
||||||
"1: \n\t"
|
|
||||||
"cmpxchg8b (%%esi) \n\t"
|
|
||||||
"jnz 1b \n\t"
|
|
||||||
:
|
|
||||||
:"S" (v), "b" (low), "c" (high)
|
|
||||||
: "eax", "edx", "memory", "cc");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_read - read atomic64 variable
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically reads the value of @ptr and returns it.
|
|
||||||
*/
|
|
||||||
static inline u64 atomic64_read(atomic64_t *ptr)
|
|
||||||
{
|
|
||||||
u64 res;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note, we inline this atomic64_t primitive because
|
|
||||||
* it only clobbers EAX/EDX and leaves the others
|
|
||||||
* untouched. We also (somewhat subtly) rely on the
|
|
||||||
* fact that cmpxchg8b returns the current 64-bit value
|
|
||||||
* of the memory location we are touching:
|
|
||||||
*/
|
|
||||||
asm volatile(
|
|
||||||
"mov %%ebx, %%eax\n\t"
|
|
||||||
"mov %%ecx, %%edx\n\t"
|
|
||||||
LOCK_PREFIX "cmpxchg8b %1\n"
|
|
||||||
: "=&A" (res)
|
|
||||||
: "m" (*ptr)
|
|
||||||
);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_add_return - add and return
|
|
||||||
* @delta: integer value to add
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically adds @delta to @ptr and returns @delta + *@ptr
|
|
||||||
*/
|
|
||||||
extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Other variants with different arithmetic operators:
|
|
||||||
*/
|
|
||||||
extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr);
|
|
||||||
extern u64 atomic64_inc_return(atomic64_t *ptr);
|
|
||||||
extern u64 atomic64_dec_return(atomic64_t *ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_add - add integer to atomic64 variable
|
|
||||||
* @delta: integer value to add
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically adds @delta to @ptr.
|
|
||||||
*/
|
|
||||||
extern void atomic64_add(u64 delta, atomic64_t *ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_sub - subtract the atomic64 variable
|
|
||||||
* @delta: integer value to subtract
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically subtracts @delta from @ptr.
|
|
||||||
*/
|
|
||||||
extern void atomic64_sub(u64 delta, atomic64_t *ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_sub_and_test - subtract value from variable and test result
|
|
||||||
* @delta: integer value to subtract
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically subtracts @delta from @ptr and returns
|
|
||||||
* true if the result is zero, or false for all
|
|
||||||
* other cases.
|
|
||||||
*/
|
|
||||||
extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_inc - increment atomic64 variable
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically increments @ptr by 1.
|
|
||||||
*/
|
|
||||||
extern void atomic64_inc(atomic64_t *ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_dec - decrement atomic64 variable
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically decrements @ptr by 1.
|
|
||||||
*/
|
|
||||||
extern void atomic64_dec(atomic64_t *ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_dec_and_test - decrement and test
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically decrements @ptr by 1 and
|
|
||||||
* returns true if the result is 0, or false for all other
|
|
||||||
* cases.
|
|
||||||
*/
|
|
||||||
extern int atomic64_dec_and_test(atomic64_t *ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_inc_and_test - increment and test
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically increments @ptr by 1
|
|
||||||
* and returns true if the result is zero, or false for all
|
|
||||||
* other cases.
|
|
||||||
*/
|
|
||||||
extern int atomic64_inc_and_test(atomic64_t *ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* atomic64_add_negative - add and test if negative
|
|
||||||
* @delta: integer value to add
|
|
||||||
* @ptr: pointer to type atomic64_t
|
|
||||||
*
|
|
||||||
* Atomically adds @delta to @ptr and returns true
|
|
||||||
* if the result is negative, or false when
|
|
||||||
* result is greater than or equal to zero.
|
|
||||||
*/
|
|
||||||
extern int atomic64_add_negative(u64 delta, atomic64_t *ptr);
|
|
||||||
|
|
||||||
#include <asm-generic/atomic-long.h>
|
|
||||||
#endif /* _ASM_X86_ATOMIC_32_H */
|
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Force strict CPU ordering.
|
* Force strict CPU ordering.
|
||||||
* And yes, this is required on UP too when we're talking
|
* And yes, this might be required on UP too when we're talking
|
||||||
* to devices.
|
* to devices.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -31,20 +31,10 @@
|
|||||||
#endif
|
#endif
|
||||||
#define dma_wmb() barrier()
|
#define dma_wmb() barrier()
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#define __smp_mb() mb()
|
||||||
#define smp_mb() mb()
|
#define __smp_rmb() dma_rmb()
|
||||||
#define smp_rmb() dma_rmb()
|
#define __smp_wmb() barrier()
|
||||||
#define smp_wmb() barrier()
|
#define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
|
||||||
#define smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
|
|
||||||
#else /* !SMP */
|
|
||||||
#define smp_mb() barrier()
|
|
||||||
#define smp_rmb() barrier()
|
|
||||||
#define smp_wmb() barrier()
|
|
||||||
#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); barrier(); } while (0)
|
|
||||||
#endif /* SMP */
|
|
||||||
|
|
||||||
#define read_barrier_depends() do { } while (0)
|
|
||||||
#define smp_read_barrier_depends() do { } while (0)
|
|
||||||
|
|
||||||
#if defined(CONFIG_X86_PPRO_FENCE)
|
#if defined(CONFIG_X86_PPRO_FENCE)
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ set_bit(long nr, volatile unsigned long *addr)
|
|||||||
* If it's called on the same region of memory simultaneously, the effect
|
* If it's called on the same region of memory simultaneously, the effect
|
||||||
* may be that only one operation succeeds.
|
* may be that only one operation succeeds.
|
||||||
*/
|
*/
|
||||||
static inline void __set_bit(long nr, volatile unsigned long *addr)
|
static __always_inline void __set_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory");
|
asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory");
|
||||||
}
|
}
|
||||||
@ -128,13 +128,13 @@ clear_bit(long nr, volatile unsigned long *addr)
|
|||||||
* clear_bit() is atomic and implies release semantics before the memory
|
* clear_bit() is atomic and implies release semantics before the memory
|
||||||
* operation. It can be used for an unlock.
|
* operation. It can be used for an unlock.
|
||||||
*/
|
*/
|
||||||
static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
|
static __always_inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
barrier();
|
barrier();
|
||||||
clear_bit(nr, addr);
|
clear_bit(nr, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __clear_bit(long nr, volatile unsigned long *addr)
|
static __always_inline void __clear_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
|
asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ static inline void __clear_bit(long nr, volatile unsigned long *addr)
|
|||||||
* No memory barrier is required here, because x86 cannot reorder stores past
|
* No memory barrier is required here, because x86 cannot reorder stores past
|
||||||
* older loads. Same principle as spin_unlock.
|
* older loads. Same principle as spin_unlock.
|
||||||
*/
|
*/
|
||||||
static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
|
static __always_inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
barrier();
|
barrier();
|
||||||
__clear_bit(nr, addr);
|
__clear_bit(nr, addr);
|
||||||
@ -166,7 +166,7 @@ static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
|
|||||||
* If it's called on the same region of memory simultaneously, the effect
|
* If it's called on the same region of memory simultaneously, the effect
|
||||||
* may be that only one operation succeeds.
|
* may be that only one operation succeeds.
|
||||||
*/
|
*/
|
||||||
static inline void __change_bit(long nr, volatile unsigned long *addr)
|
static __always_inline void __change_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
|
asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
|
||||||
}
|
}
|
||||||
@ -180,7 +180,7 @@ static inline void __change_bit(long nr, volatile unsigned long *addr)
|
|||||||
* Note that @nr may be almost arbitrarily large; this function is not
|
* Note that @nr may be almost arbitrarily large; this function is not
|
||||||
* restricted to acting on a single-word quantity.
|
* restricted to acting on a single-word quantity.
|
||||||
*/
|
*/
|
||||||
static inline void change_bit(long nr, volatile unsigned long *addr)
|
static __always_inline void change_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
if (IS_IMMEDIATE(nr)) {
|
if (IS_IMMEDIATE(nr)) {
|
||||||
asm volatile(LOCK_PREFIX "xorb %1,%0"
|
asm volatile(LOCK_PREFIX "xorb %1,%0"
|
||||||
@ -201,7 +201,7 @@ static inline void change_bit(long nr, volatile unsigned long *addr)
|
|||||||
* This operation is atomic and cannot be reordered.
|
* This operation is atomic and cannot be reordered.
|
||||||
* It also implies a memory barrier.
|
* It also implies a memory barrier.
|
||||||
*/
|
*/
|
||||||
static inline int test_and_set_bit(long nr, volatile unsigned long *addr)
|
static __always_inline int test_and_set_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c");
|
GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c");
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ test_and_set_bit_lock(long nr, volatile unsigned long *addr)
|
|||||||
* If two examples of this operation race, one can appear to succeed
|
* If two examples of this operation race, one can appear to succeed
|
||||||
* but actually fail. You must protect multiple accesses with a lock.
|
* but actually fail. You must protect multiple accesses with a lock.
|
||||||
*/
|
*/
|
||||||
static inline int __test_and_set_bit(long nr, volatile unsigned long *addr)
|
static __always_inline int __test_and_set_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
int oldbit;
|
int oldbit;
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ static inline int __test_and_set_bit(long nr, volatile unsigned long *addr)
|
|||||||
* This operation is atomic and cannot be reordered.
|
* This operation is atomic and cannot be reordered.
|
||||||
* It also implies a memory barrier.
|
* It also implies a memory barrier.
|
||||||
*/
|
*/
|
||||||
static inline int test_and_clear_bit(long nr, volatile unsigned long *addr)
|
static __always_inline int test_and_clear_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", "c");
|
GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", "c");
|
||||||
}
|
}
|
||||||
@ -268,7 +268,7 @@ static inline int test_and_clear_bit(long nr, volatile unsigned long *addr)
|
|||||||
* accessed from a hypervisor on the same CPU if running in a VM: don't change
|
* accessed from a hypervisor on the same CPU if running in a VM: don't change
|
||||||
* this without also updating arch/x86/kernel/kvm.c
|
* this without also updating arch/x86/kernel/kvm.c
|
||||||
*/
|
*/
|
||||||
static inline int __test_and_clear_bit(long nr, volatile unsigned long *addr)
|
static __always_inline int __test_and_clear_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
int oldbit;
|
int oldbit;
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ static inline int __test_and_clear_bit(long nr, volatile unsigned long *addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* WARNING: non atomic and it can be reordered! */
|
/* WARNING: non atomic and it can be reordered! */
|
||||||
static inline int __test_and_change_bit(long nr, volatile unsigned long *addr)
|
static __always_inline int __test_and_change_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
int oldbit;
|
int oldbit;
|
||||||
|
|
||||||
@ -300,7 +300,7 @@ static inline int __test_and_change_bit(long nr, volatile unsigned long *addr)
|
|||||||
* This operation is atomic and cannot be reordered.
|
* This operation is atomic and cannot be reordered.
|
||||||
* It also implies a memory barrier.
|
* It also implies a memory barrier.
|
||||||
*/
|
*/
|
||||||
static inline int test_and_change_bit(long nr, volatile unsigned long *addr)
|
static __always_inline int test_and_change_bit(long nr, volatile unsigned long *addr)
|
||||||
{
|
{
|
||||||
GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", "c");
|
GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", "c");
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ static __always_inline int constant_test_bit(long nr, const volatile unsigned lo
|
|||||||
(addr[nr >> _BITOPS_LONG_SHIFT])) != 0;
|
(addr[nr >> _BITOPS_LONG_SHIFT])) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int variable_test_bit(long nr, volatile const unsigned long *addr)
|
static __always_inline int variable_test_bit(long nr, volatile const unsigned long *addr)
|
||||||
{
|
{
|
||||||
int oldbit;
|
int oldbit;
|
||||||
|
|
||||||
@ -343,7 +343,7 @@ static int test_bit(int nr, const volatile unsigned long *addr);
|
|||||||
*
|
*
|
||||||
* Undefined if no bit exists, so code should check against 0 first.
|
* Undefined if no bit exists, so code should check against 0 first.
|
||||||
*/
|
*/
|
||||||
static inline unsigned long __ffs(unsigned long word)
|
static __always_inline unsigned long __ffs(unsigned long word)
|
||||||
{
|
{
|
||||||
asm("rep; bsf %1,%0"
|
asm("rep; bsf %1,%0"
|
||||||
: "=r" (word)
|
: "=r" (word)
|
||||||
@ -357,7 +357,7 @@ static inline unsigned long __ffs(unsigned long word)
|
|||||||
*
|
*
|
||||||
* Undefined if no zero exists, so code should check against ~0UL first.
|
* Undefined if no zero exists, so code should check against ~0UL first.
|
||||||
*/
|
*/
|
||||||
static inline unsigned long ffz(unsigned long word)
|
static __always_inline unsigned long ffz(unsigned long word)
|
||||||
{
|
{
|
||||||
asm("rep; bsf %1,%0"
|
asm("rep; bsf %1,%0"
|
||||||
: "=r" (word)
|
: "=r" (word)
|
||||||
@ -371,7 +371,7 @@ static inline unsigned long ffz(unsigned long word)
|
|||||||
*
|
*
|
||||||
* Undefined if no set bit exists, so code should check against 0 first.
|
* Undefined if no set bit exists, so code should check against 0 first.
|
||||||
*/
|
*/
|
||||||
static inline unsigned long __fls(unsigned long word)
|
static __always_inline unsigned long __fls(unsigned long word)
|
||||||
{
|
{
|
||||||
asm("bsr %1,%0"
|
asm("bsr %1,%0"
|
||||||
: "=r" (word)
|
: "=r" (word)
|
||||||
@ -393,7 +393,7 @@ static inline unsigned long __fls(unsigned long word)
|
|||||||
* set bit if value is nonzero. The first (least significant) bit
|
* set bit if value is nonzero. The first (least significant) bit
|
||||||
* is at position 1.
|
* is at position 1.
|
||||||
*/
|
*/
|
||||||
static inline int ffs(int x)
|
static __always_inline int ffs(int x)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ static inline int ffs(int x)
|
|||||||
* set bit if value is nonzero. The last (most significant) bit is
|
* set bit if value is nonzero. The last (most significant) bit is
|
||||||
* at position 32.
|
* at position 32.
|
||||||
*/
|
*/
|
||||||
static inline int fls(int x)
|
static __always_inline int fls(int x)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
/* Caches aren't brain-dead on the intel. */
|
/* Caches aren't brain-dead on the intel. */
|
||||||
#include <asm-generic/cacheflush.h>
|
#include <asm-generic/cacheflush.h>
|
||||||
#include <asm/special_insns.h>
|
#include <asm/special_insns.h>
|
||||||
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The set_memory_* API can be used to change various attributes of a virtual
|
* The set_memory_* API can be used to change various attributes of a virtual
|
||||||
@ -113,16 +114,10 @@ void clflush_cache_range(void *addr, unsigned int size);
|
|||||||
|
|
||||||
#define mmio_flush_range(addr, size) clflush_cache_range(addr, size)
|
#define mmio_flush_range(addr, size) clflush_cache_range(addr, size)
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_RODATA
|
|
||||||
void mark_rodata_ro(void);
|
|
||||||
extern const int rodata_test_data;
|
extern const int rodata_test_data;
|
||||||
extern int kernel_set_to_readonly;
|
extern int kernel_set_to_readonly;
|
||||||
void set_kernel_text_rw(void);
|
void set_kernel_text_rw(void);
|
||||||
void set_kernel_text_ro(void);
|
void set_kernel_text_ro(void);
|
||||||
#else
|
|
||||||
static inline void set_kernel_text_rw(void) { }
|
|
||||||
static inline void set_kernel_text_ro(void) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_RODATA_TEST
|
#ifdef CONFIG_DEBUG_RODATA_TEST
|
||||||
int rodata_test(void);
|
int rodata_test(void);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define ASM_X86_CMPXCHG_H
|
#define ASM_X86_CMPXCHG_H
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
#include <asm/cpufeatures.h>
|
||||||
#include <asm/alternative.h> /* Provides LOCK_PREFIX */
|
#include <asm/alternative.h> /* Provides LOCK_PREFIX */
|
||||||
|
|
||||||
#define __HAVE_ARCH_CMPXCHG 1
|
#define __HAVE_ARCH_CMPXCHG 1
|
||||||
|
@ -1,288 +1,7 @@
|
|||||||
/*
|
|
||||||
* Defines x86 CPU feature bits
|
|
||||||
*/
|
|
||||||
#ifndef _ASM_X86_CPUFEATURE_H
|
#ifndef _ASM_X86_CPUFEATURE_H
|
||||||
#define _ASM_X86_CPUFEATURE_H
|
#define _ASM_X86_CPUFEATURE_H
|
||||||
|
|
||||||
#ifndef _ASM_X86_REQUIRED_FEATURES_H
|
#include <asm/processor.h>
|
||||||
#include <asm/required-features.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _ASM_X86_DISABLED_FEATURES_H
|
|
||||||
#include <asm/disabled-features.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NCAPINTS 16 /* N 32-bit words worth of info */
|
|
||||||
#define NBUGINTS 1 /* N 32-bit bug flags */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note: If the comment begins with a quoted string, that string is used
|
|
||||||
* in /proc/cpuinfo instead of the macro name. If the string is "",
|
|
||||||
* this feature bit is not displayed in /proc/cpuinfo at all.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
|
|
||||||
#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */
|
|
||||||
#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */
|
|
||||||
#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */
|
|
||||||
#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */
|
|
||||||
#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */
|
|
||||||
#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */
|
|
||||||
#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */
|
|
||||||
#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */
|
|
||||||
#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */
|
|
||||||
#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */
|
|
||||||
#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */
|
|
||||||
#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */
|
|
||||||
#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */
|
|
||||||
#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */
|
|
||||||
#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */
|
|
||||||
/* (plus FCMOVcc, FCOMI with FPU) */
|
|
||||||
#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */
|
|
||||||
#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */
|
|
||||||
#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */
|
|
||||||
#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */
|
|
||||||
#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */
|
|
||||||
#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */
|
|
||||||
#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */
|
|
||||||
#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */
|
|
||||||
#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */
|
|
||||||
#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */
|
|
||||||
#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */
|
|
||||||
#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */
|
|
||||||
#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */
|
|
||||||
#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */
|
|
||||||
#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */
|
|
||||||
|
|
||||||
/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
|
|
||||||
/* Don't duplicate feature flags which are redundant with Intel! */
|
|
||||||
#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */
|
|
||||||
#define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */
|
|
||||||
#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */
|
|
||||||
#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */
|
|
||||||
#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */
|
|
||||||
#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */
|
|
||||||
#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */
|
|
||||||
#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */
|
|
||||||
#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */
|
|
||||||
#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */
|
|
||||||
|
|
||||||
/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
|
|
||||||
#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */
|
|
||||||
#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */
|
|
||||||
#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */
|
|
||||||
|
|
||||||
/* Other features, Linux-defined mapping, word 3 */
|
|
||||||
/* This range is used for feature bits which conflict or are synthesized */
|
|
||||||
#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */
|
|
||||||
#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */
|
|
||||||
#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */
|
|
||||||
#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */
|
|
||||||
/* cpu types for specific tunings: */
|
|
||||||
#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */
|
|
||||||
#define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */
|
|
||||||
#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */
|
|
||||||
#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */
|
|
||||||
#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */
|
|
||||||
#define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */
|
|
||||||
/* free, was #define X86_FEATURE_FXSAVE_LEAK ( 3*32+10) * "" FXSAVE leaks FOP/FIP/FOP */
|
|
||||||
#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */
|
|
||||||
#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */
|
|
||||||
#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */
|
|
||||||
#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */
|
|
||||||
#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */
|
|
||||||
#define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */
|
|
||||||
#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */
|
|
||||||
#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */
|
|
||||||
/* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */
|
|
||||||
#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */
|
|
||||||
#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */
|
|
||||||
#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */
|
|
||||||
#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */
|
|
||||||
#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */
|
|
||||||
/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */
|
|
||||||
#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */
|
|
||||||
#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */
|
|
||||||
#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
|
|
||||||
#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
|
|
||||||
#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
|
|
||||||
|
|
||||||
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
|
|
||||||
#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */
|
|
||||||
#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */
|
|
||||||
#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */
|
|
||||||
#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */
|
|
||||||
#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */
|
|
||||||
#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */
|
|
||||||
#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */
|
|
||||||
#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */
|
|
||||||
#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */
|
|
||||||
#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */
|
|
||||||
#define X86_FEATURE_CID ( 4*32+10) /* Context ID */
|
|
||||||
#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */
|
|
||||||
#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */
|
|
||||||
#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */
|
|
||||||
#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */
|
|
||||||
#define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */
|
|
||||||
#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */
|
|
||||||
#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */
|
|
||||||
#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */
|
|
||||||
#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */
|
|
||||||
#define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */
|
|
||||||
#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */
|
|
||||||
#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */
|
|
||||||
#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */
|
|
||||||
#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */
|
|
||||||
#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
|
|
||||||
#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */
|
|
||||||
#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */
|
|
||||||
#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */
|
|
||||||
#define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */
|
|
||||||
#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */
|
|
||||||
|
|
||||||
/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
|
|
||||||
#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */
|
|
||||||
#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */
|
|
||||||
#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
|
|
||||||
#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */
|
|
||||||
#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */
|
|
||||||
#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */
|
|
||||||
#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */
|
|
||||||
#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */
|
|
||||||
#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */
|
|
||||||
#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */
|
|
||||||
|
|
||||||
/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
|
|
||||||
#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */
|
|
||||||
#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */
|
|
||||||
#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */
|
|
||||||
#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */
|
|
||||||
#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */
|
|
||||||
#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */
|
|
||||||
#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */
|
|
||||||
#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */
|
|
||||||
#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */
|
|
||||||
#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */
|
|
||||||
#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */
|
|
||||||
#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */
|
|
||||||
#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */
|
|
||||||
#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */
|
|
||||||
#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */
|
|
||||||
#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */
|
|
||||||
#define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */
|
|
||||||
#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */
|
|
||||||
#define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */
|
|
||||||
#define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */
|
|
||||||
#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */
|
|
||||||
#define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */
|
|
||||||
#define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */
|
|
||||||
#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */
|
|
||||||
#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auxiliary flags: Linux defined - For features scattered in various
|
|
||||||
* CPUID levels like 0x6, 0xA etc, word 7.
|
|
||||||
*
|
|
||||||
* Reuse free bits when adding new feature flags!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */
|
|
||||||
#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
|
|
||||||
|
|
||||||
#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
|
|
||||||
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
|
|
||||||
|
|
||||||
#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
|
|
||||||
|
|
||||||
/* Virtualization flags: Linux defined, word 8 */
|
|
||||||
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
|
|
||||||
#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */
|
|
||||||
#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */
|
|
||||||
#define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */
|
|
||||||
#define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */
|
|
||||||
|
|
||||||
#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */
|
|
||||||
#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */
|
|
||||||
|
|
||||||
|
|
||||||
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
|
|
||||||
#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
|
|
||||||
#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */
|
|
||||||
#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */
|
|
||||||
#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */
|
|
||||||
#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */
|
|
||||||
#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */
|
|
||||||
#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */
|
|
||||||
#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */
|
|
||||||
#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */
|
|
||||||
#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */
|
|
||||||
#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */
|
|
||||||
#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */
|
|
||||||
#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */
|
|
||||||
#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */
|
|
||||||
#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */
|
|
||||||
#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */
|
|
||||||
#define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */
|
|
||||||
#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
|
|
||||||
#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
|
|
||||||
#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
|
|
||||||
#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */
|
|
||||||
#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */
|
|
||||||
#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */
|
|
||||||
|
|
||||||
/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */
|
|
||||||
#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */
|
|
||||||
#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */
|
|
||||||
#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */
|
|
||||||
#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */
|
|
||||||
|
|
||||||
/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */
|
|
||||||
#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */
|
|
||||||
|
|
||||||
/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
|
|
||||||
#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
|
|
||||||
|
|
||||||
/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
|
|
||||||
#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
|
|
||||||
|
|
||||||
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */
|
|
||||||
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
|
|
||||||
#define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */
|
|
||||||
#define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */
|
|
||||||
#define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */
|
|
||||||
#define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */
|
|
||||||
#define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */
|
|
||||||
#define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */
|
|
||||||
#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */
|
|
||||||
#define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */
|
|
||||||
#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */
|
|
||||||
|
|
||||||
/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */
|
|
||||||
#define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */
|
|
||||||
#define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */
|
|
||||||
#define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */
|
|
||||||
#define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */
|
|
||||||
#define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */
|
|
||||||
#define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */
|
|
||||||
#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */
|
|
||||||
#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */
|
|
||||||
#define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */
|
|
||||||
#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BUG word(s)
|
|
||||||
*/
|
|
||||||
#define X86_BUG(x) (NCAPINTS*32 + (x))
|
|
||||||
|
|
||||||
#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */
|
|
||||||
#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */
|
|
||||||
#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */
|
|
||||||
#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */
|
|
||||||
#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */
|
|
||||||
#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */
|
|
||||||
#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
|
|
||||||
#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
|
|
||||||
#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
|
|
||||||
|
|
||||||
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
||||||
|
|
||||||
@ -307,6 +26,7 @@ enum cpuid_leafs
|
|||||||
CPUID_8000_0008_EBX,
|
CPUID_8000_0008_EBX,
|
||||||
CPUID_6_EAX,
|
CPUID_6_EAX,
|
||||||
CPUID_8000_000A_EDX,
|
CPUID_8000_000A_EDX,
|
||||||
|
CPUID_7_ECX,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_X86_FEATURE_NAMES
|
#ifdef CONFIG_X86_FEATURE_NAMES
|
||||||
@ -329,28 +49,42 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
|
|||||||
test_bit(bit, (unsigned long *)((c)->x86_capability))
|
test_bit(bit, (unsigned long *)((c)->x86_capability))
|
||||||
|
|
||||||
#define REQUIRED_MASK_BIT_SET(bit) \
|
#define REQUIRED_MASK_BIT_SET(bit) \
|
||||||
( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) || \
|
( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0 )) || \
|
||||||
(((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) || \
|
(((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1 )) || \
|
||||||
(((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) || \
|
(((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2 )) || \
|
||||||
(((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) || \
|
(((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3 )) || \
|
||||||
(((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) || \
|
(((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4 )) || \
|
||||||
(((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) || \
|
(((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5 )) || \
|
||||||
(((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \
|
(((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6 )) || \
|
||||||
(((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) || \
|
(((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7 )) || \
|
||||||
(((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8)) || \
|
(((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8 )) || \
|
||||||
(((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) )
|
(((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9 )) || \
|
||||||
|
(((bit)>>5)==10 && (1UL<<((bit)&31) & REQUIRED_MASK10)) || \
|
||||||
|
(((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) || \
|
||||||
|
(((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) || \
|
||||||
|
(((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) || \
|
||||||
|
(((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK14)) || \
|
||||||
|
(((bit)>>5)==15 && (1UL<<((bit)&31) & REQUIRED_MASK15)) || \
|
||||||
|
(((bit)>>5)==16 && (1UL<<((bit)&31) & REQUIRED_MASK16)) )
|
||||||
|
|
||||||
#define DISABLED_MASK_BIT_SET(bit) \
|
#define DISABLED_MASK_BIT_SET(bit) \
|
||||||
( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0)) || \
|
( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0 )) || \
|
||||||
(((bit)>>5)==1 && (1UL<<((bit)&31) & DISABLED_MASK1)) || \
|
(((bit)>>5)==1 && (1UL<<((bit)&31) & DISABLED_MASK1 )) || \
|
||||||
(((bit)>>5)==2 && (1UL<<((bit)&31) & DISABLED_MASK2)) || \
|
(((bit)>>5)==2 && (1UL<<((bit)&31) & DISABLED_MASK2 )) || \
|
||||||
(((bit)>>5)==3 && (1UL<<((bit)&31) & DISABLED_MASK3)) || \
|
(((bit)>>5)==3 && (1UL<<((bit)&31) & DISABLED_MASK3 )) || \
|
||||||
(((bit)>>5)==4 && (1UL<<((bit)&31) & DISABLED_MASK4)) || \
|
(((bit)>>5)==4 && (1UL<<((bit)&31) & DISABLED_MASK4 )) || \
|
||||||
(((bit)>>5)==5 && (1UL<<((bit)&31) & DISABLED_MASK5)) || \
|
(((bit)>>5)==5 && (1UL<<((bit)&31) & DISABLED_MASK5 )) || \
|
||||||
(((bit)>>5)==6 && (1UL<<((bit)&31) & DISABLED_MASK6)) || \
|
(((bit)>>5)==6 && (1UL<<((bit)&31) & DISABLED_MASK6 )) || \
|
||||||
(((bit)>>5)==7 && (1UL<<((bit)&31) & DISABLED_MASK7)) || \
|
(((bit)>>5)==7 && (1UL<<((bit)&31) & DISABLED_MASK7 )) || \
|
||||||
(((bit)>>5)==8 && (1UL<<((bit)&31) & DISABLED_MASK8)) || \
|
(((bit)>>5)==8 && (1UL<<((bit)&31) & DISABLED_MASK8 )) || \
|
||||||
(((bit)>>5)==9 && (1UL<<((bit)&31) & DISABLED_MASK9)) )
|
(((bit)>>5)==9 && (1UL<<((bit)&31) & DISABLED_MASK9 )) || \
|
||||||
|
(((bit)>>5)==10 && (1UL<<((bit)&31) & DISABLED_MASK10)) || \
|
||||||
|
(((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) || \
|
||||||
|
(((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) || \
|
||||||
|
(((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) || \
|
||||||
|
(((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK14)) || \
|
||||||
|
(((bit)>>5)==15 && (1UL<<((bit)&31) & DISABLED_MASK15)) || \
|
||||||
|
(((bit)>>5)==16 && (1UL<<((bit)&31) & DISABLED_MASK16)) )
|
||||||
|
|
||||||
#define cpu_has(c, bit) \
|
#define cpu_has(c, bit) \
|
||||||
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
|
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
|
||||||
@ -369,8 +103,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
|
|||||||
* is not relevant.
|
* is not relevant.
|
||||||
*/
|
*/
|
||||||
#define cpu_feature_enabled(bit) \
|
#define cpu_feature_enabled(bit) \
|
||||||
(__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : \
|
(__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit))
|
||||||
cpu_has(&boot_cpu_data, bit))
|
|
||||||
|
|
||||||
#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
|
#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
|
||||||
|
|
||||||
@ -406,106 +139,19 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
|
|||||||
#define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE)
|
#define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE)
|
||||||
#define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR)
|
#define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR)
|
||||||
/*
|
/*
|
||||||
* Do not add any more of those clumsy macros - use static_cpu_has_safe() for
|
* Do not add any more of those clumsy macros - use static_cpu_has() for
|
||||||
* fast paths and boot_cpu_has() otherwise!
|
* fast paths and boot_cpu_has() otherwise!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if __GNUC__ >= 4 && defined(CONFIG_X86_FAST_FEATURE_TESTS)
|
#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_X86_FAST_FEATURE_TESTS)
|
||||||
extern void warn_pre_alternatives(void);
|
|
||||||
extern bool __static_cpu_has_safe(u16 bit);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Static testing of CPU features. Used the same as boot_cpu_has().
|
* Static testing of CPU features. Used the same as boot_cpu_has().
|
||||||
* These are only valid after alternatives have run, but will statically
|
* These will statically patch the target code for additional
|
||||||
* patch the target code for additional performance.
|
* performance.
|
||||||
*/
|
*/
|
||||||
static __always_inline __pure bool __static_cpu_has(u16 bit)
|
static __always_inline __pure bool _static_cpu_has(u16 bit)
|
||||||
{
|
{
|
||||||
#ifdef CC_HAVE_ASM_GOTO
|
asm_volatile_goto("1: jmp 6f\n"
|
||||||
|
|
||||||
#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Catch too early usage of this before alternatives
|
|
||||||
* have run.
|
|
||||||
*/
|
|
||||||
asm_volatile_goto("1: jmp %l[t_warn]\n"
|
|
||||||
"2:\n"
|
|
||||||
".section .altinstructions,\"a\"\n"
|
|
||||||
" .long 1b - .\n"
|
|
||||||
" .long 0\n" /* no replacement */
|
|
||||||
" .word %P0\n" /* 1: do replace */
|
|
||||||
" .byte 2b - 1b\n" /* source len */
|
|
||||||
" .byte 0\n" /* replacement len */
|
|
||||||
" .byte 0\n" /* pad len */
|
|
||||||
".previous\n"
|
|
||||||
/* skipping size check since replacement size = 0 */
|
|
||||||
: : "i" (X86_FEATURE_ALWAYS) : : t_warn);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
asm_volatile_goto("1: jmp %l[t_no]\n"
|
|
||||||
"2:\n"
|
|
||||||
".section .altinstructions,\"a\"\n"
|
|
||||||
" .long 1b - .\n"
|
|
||||||
" .long 0\n" /* no replacement */
|
|
||||||
" .word %P0\n" /* feature bit */
|
|
||||||
" .byte 2b - 1b\n" /* source len */
|
|
||||||
" .byte 0\n" /* replacement len */
|
|
||||||
" .byte 0\n" /* pad len */
|
|
||||||
".previous\n"
|
|
||||||
/* skipping size check since replacement size = 0 */
|
|
||||||
: : "i" (bit) : : t_no);
|
|
||||||
return true;
|
|
||||||
t_no:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
|
|
||||||
t_warn:
|
|
||||||
warn_pre_alternatives();
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* CC_HAVE_ASM_GOTO */
|
|
||||||
|
|
||||||
u8 flag;
|
|
||||||
/* Open-coded due to __stringify() in ALTERNATIVE() */
|
|
||||||
asm volatile("1: movb $0,%0\n"
|
|
||||||
"2:\n"
|
|
||||||
".section .altinstructions,\"a\"\n"
|
|
||||||
" .long 1b - .\n"
|
|
||||||
" .long 3f - .\n"
|
|
||||||
" .word %P1\n" /* feature bit */
|
|
||||||
" .byte 2b - 1b\n" /* source len */
|
|
||||||
" .byte 4f - 3f\n" /* replacement len */
|
|
||||||
" .byte 0\n" /* pad len */
|
|
||||||
".previous\n"
|
|
||||||
".section .discard,\"aw\",@progbits\n"
|
|
||||||
" .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
|
|
||||||
".previous\n"
|
|
||||||
".section .altinstr_replacement,\"ax\"\n"
|
|
||||||
"3: movb $1,%0\n"
|
|
||||||
"4:\n"
|
|
||||||
".previous\n"
|
|
||||||
: "=qm" (flag) : "i" (bit));
|
|
||||||
return flag;
|
|
||||||
|
|
||||||
#endif /* CC_HAVE_ASM_GOTO */
|
|
||||||
}
|
|
||||||
|
|
||||||
#define static_cpu_has(bit) \
|
|
||||||
( \
|
|
||||||
__builtin_constant_p(boot_cpu_has(bit)) ? \
|
|
||||||
boot_cpu_has(bit) : \
|
|
||||||
__builtin_constant_p(bit) ? \
|
|
||||||
__static_cpu_has(bit) : \
|
|
||||||
boot_cpu_has(bit) \
|
|
||||||
)
|
|
||||||
|
|
||||||
static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
|
|
||||||
{
|
|
||||||
#ifdef CC_HAVE_ASM_GOTO
|
|
||||||
asm_volatile_goto("1: jmp %l[t_dynamic]\n"
|
|
||||||
"2:\n"
|
"2:\n"
|
||||||
".skip -(((5f-4f) - (2b-1b)) > 0) * "
|
".skip -(((5f-4f) - (2b-1b)) > 0) * "
|
||||||
"((5f-4f) - (2b-1b)),0x90\n"
|
"((5f-4f) - (2b-1b)),0x90\n"
|
||||||
@ -530,66 +176,34 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
|
|||||||
" .byte 0\n" /* repl len */
|
" .byte 0\n" /* repl len */
|
||||||
" .byte 0\n" /* pad len */
|
" .byte 0\n" /* pad len */
|
||||||
".previous\n"
|
".previous\n"
|
||||||
: : "i" (bit), "i" (X86_FEATURE_ALWAYS)
|
".section .altinstr_aux,\"ax\"\n"
|
||||||
: : t_dynamic, t_no);
|
"6:\n"
|
||||||
|
" testb %[bitnum],%[cap_byte]\n"
|
||||||
|
" jnz %l[t_yes]\n"
|
||||||
|
" jmp %l[t_no]\n"
|
||||||
|
".previous\n"
|
||||||
|
: : "i" (bit), "i" (X86_FEATURE_ALWAYS),
|
||||||
|
[bitnum] "i" (1 << (bit & 7)),
|
||||||
|
[cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3])
|
||||||
|
: : t_yes, t_no);
|
||||||
|
t_yes:
|
||||||
return true;
|
return true;
|
||||||
t_no:
|
t_no:
|
||||||
return false;
|
return false;
|
||||||
t_dynamic:
|
|
||||||
return __static_cpu_has_safe(bit);
|
|
||||||
#else
|
|
||||||
u8 flag;
|
|
||||||
/* Open-coded due to __stringify() in ALTERNATIVE() */
|
|
||||||
asm volatile("1: movb $2,%0\n"
|
|
||||||
"2:\n"
|
|
||||||
".section .altinstructions,\"a\"\n"
|
|
||||||
" .long 1b - .\n" /* src offset */
|
|
||||||
" .long 3f - .\n" /* repl offset */
|
|
||||||
" .word %P2\n" /* always replace */
|
|
||||||
" .byte 2b - 1b\n" /* source len */
|
|
||||||
" .byte 4f - 3f\n" /* replacement len */
|
|
||||||
" .byte 0\n" /* pad len */
|
|
||||||
".previous\n"
|
|
||||||
".section .discard,\"aw\",@progbits\n"
|
|
||||||
" .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
|
|
||||||
".previous\n"
|
|
||||||
".section .altinstr_replacement,\"ax\"\n"
|
|
||||||
"3: movb $0,%0\n"
|
|
||||||
"4:\n"
|
|
||||||
".previous\n"
|
|
||||||
".section .altinstructions,\"a\"\n"
|
|
||||||
" .long 1b - .\n" /* src offset */
|
|
||||||
" .long 5f - .\n" /* repl offset */
|
|
||||||
" .word %P1\n" /* feature bit */
|
|
||||||
" .byte 4b - 3b\n" /* src len */
|
|
||||||
" .byte 6f - 5f\n" /* repl len */
|
|
||||||
" .byte 0\n" /* pad len */
|
|
||||||
".previous\n"
|
|
||||||
".section .discard,\"aw\",@progbits\n"
|
|
||||||
" .byte 0xff + (6f-5f) - (4b-3b)\n" /* size check */
|
|
||||||
".previous\n"
|
|
||||||
".section .altinstr_replacement,\"ax\"\n"
|
|
||||||
"5: movb $1,%0\n"
|
|
||||||
"6:\n"
|
|
||||||
".previous\n"
|
|
||||||
: "=qm" (flag)
|
|
||||||
: "i" (bit), "i" (X86_FEATURE_ALWAYS));
|
|
||||||
return (flag == 2 ? __static_cpu_has_safe(bit) : flag);
|
|
||||||
#endif /* CC_HAVE_ASM_GOTO */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define static_cpu_has_safe(bit) \
|
#define static_cpu_has(bit) \
|
||||||
( \
|
( \
|
||||||
__builtin_constant_p(boot_cpu_has(bit)) ? \
|
__builtin_constant_p(boot_cpu_has(bit)) ? \
|
||||||
boot_cpu_has(bit) : \
|
boot_cpu_has(bit) : \
|
||||||
_static_cpu_has_safe(bit) \
|
_static_cpu_has(bit) \
|
||||||
)
|
)
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* gcc 3.x is too stupid to do the static test; fall back to dynamic.
|
* Fall back to dynamic for gcc versions which don't support asm goto. Should be
|
||||||
|
* a minority now anyway.
|
||||||
*/
|
*/
|
||||||
#define static_cpu_has(bit) boot_cpu_has(bit)
|
#define static_cpu_has(bit) boot_cpu_has(bit)
|
||||||
#define static_cpu_has_safe(bit) boot_cpu_has(bit)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define cpu_has_bug(c, bit) cpu_has(c, (bit))
|
#define cpu_has_bug(c, bit) cpu_has(c, (bit))
|
||||||
@ -597,7 +211,6 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
|
|||||||
#define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit))
|
#define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit))
|
||||||
|
|
||||||
#define static_cpu_has_bug(bit) static_cpu_has((bit))
|
#define static_cpu_has_bug(bit) static_cpu_has((bit))
|
||||||
#define static_cpu_has_bug_safe(bit) static_cpu_has_safe((bit))
|
|
||||||
#define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
|
#define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
|
||||||
|
|
||||||
#define MAX_CPU_FEATURES (NCAPINTS * 32)
|
#define MAX_CPU_FEATURES (NCAPINTS * 32)
|
||||||
|
306
drivers/include/asm/cpufeatures.h
Normal file
306
drivers/include/asm/cpufeatures.h
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
#ifndef _ASM_X86_CPUFEATURES_H
|
||||||
|
#define _ASM_X86_CPUFEATURES_H
|
||||||
|
|
||||||
|
#ifndef _ASM_X86_REQUIRED_FEATURES_H
|
||||||
|
#include <asm/required-features.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _ASM_X86_DISABLED_FEATURES_H
|
||||||
|
#include <asm/disabled-features.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines x86 CPU feature bits
|
||||||
|
*/
|
||||||
|
#define NCAPINTS 17 /* N 32-bit words worth of info */
|
||||||
|
#define NBUGINTS 1 /* N 32-bit bug flags */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: If the comment begins with a quoted string, that string is used
|
||||||
|
* in /proc/cpuinfo instead of the macro name. If the string is "",
|
||||||
|
* this feature bit is not displayed in /proc/cpuinfo at all.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
|
||||||
|
#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */
|
||||||
|
#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */
|
||||||
|
#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */
|
||||||
|
#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */
|
||||||
|
#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */
|
||||||
|
#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */
|
||||||
|
#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */
|
||||||
|
#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */
|
||||||
|
#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */
|
||||||
|
#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */
|
||||||
|
#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */
|
||||||
|
#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */
|
||||||
|
#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */
|
||||||
|
#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */
|
||||||
|
#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */
|
||||||
|
/* (plus FCMOVcc, FCOMI with FPU) */
|
||||||
|
#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */
|
||||||
|
#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */
|
||||||
|
#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */
|
||||||
|
#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */
|
||||||
|
#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */
|
||||||
|
#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */
|
||||||
|
#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */
|
||||||
|
#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */
|
||||||
|
#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */
|
||||||
|
#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */
|
||||||
|
#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */
|
||||||
|
#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */
|
||||||
|
#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */
|
||||||
|
#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */
|
||||||
|
#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */
|
||||||
|
|
||||||
|
/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
|
||||||
|
/* Don't duplicate feature flags which are redundant with Intel! */
|
||||||
|
#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */
|
||||||
|
#define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */
|
||||||
|
#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */
|
||||||
|
#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */
|
||||||
|
#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */
|
||||||
|
#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */
|
||||||
|
#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */
|
||||||
|
#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */
|
||||||
|
#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */
|
||||||
|
#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */
|
||||||
|
|
||||||
|
/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
|
||||||
|
#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */
|
||||||
|
#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */
|
||||||
|
#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */
|
||||||
|
|
||||||
|
/* Other features, Linux-defined mapping, word 3 */
|
||||||
|
/* This range is used for feature bits which conflict or are synthesized */
|
||||||
|
#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */
|
||||||
|
#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */
|
||||||
|
#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */
|
||||||
|
#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */
|
||||||
|
/* cpu types for specific tunings: */
|
||||||
|
#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */
|
||||||
|
#define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */
|
||||||
|
#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */
|
||||||
|
#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */
|
||||||
|
#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */
|
||||||
|
#define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */
|
||||||
|
#define X86_FEATURE_ART ( 3*32+10) /* Platform has always running timer (ART) */
|
||||||
|
#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */
|
||||||
|
#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */
|
||||||
|
#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */
|
||||||
|
#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */
|
||||||
|
#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */
|
||||||
|
#define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */
|
||||||
|
#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */
|
||||||
|
#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */
|
||||||
|
#define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */
|
||||||
|
#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */
|
||||||
|
#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */
|
||||||
|
#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */
|
||||||
|
#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */
|
||||||
|
#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */
|
||||||
|
/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */
|
||||||
|
#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */
|
||||||
|
#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */
|
||||||
|
#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
|
||||||
|
#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
|
||||||
|
#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
|
||||||
|
#define X86_FEATURE_MCE_RECOVERY ( 3*32+31) /* cpu has recoverable machine checks */
|
||||||
|
|
||||||
|
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
|
||||||
|
#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */
|
||||||
|
#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */
|
||||||
|
#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */
|
||||||
|
#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */
|
||||||
|
#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */
|
||||||
|
#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */
|
||||||
|
#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */
|
||||||
|
#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */
|
||||||
|
#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */
|
||||||
|
#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */
|
||||||
|
#define X86_FEATURE_CID ( 4*32+10) /* Context ID */
|
||||||
|
#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */
|
||||||
|
#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */
|
||||||
|
#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */
|
||||||
|
#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */
|
||||||
|
#define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */
|
||||||
|
#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */
|
||||||
|
#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */
|
||||||
|
#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */
|
||||||
|
#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */
|
||||||
|
#define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */
|
||||||
|
#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */
|
||||||
|
#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */
|
||||||
|
#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */
|
||||||
|
#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */
|
||||||
|
#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
|
||||||
|
#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */
|
||||||
|
#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */
|
||||||
|
#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */
|
||||||
|
#define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */
|
||||||
|
#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */
|
||||||
|
|
||||||
|
/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
|
||||||
|
#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */
|
||||||
|
#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */
|
||||||
|
#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
|
||||||
|
#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */
|
||||||
|
#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */
|
||||||
|
#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */
|
||||||
|
#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */
|
||||||
|
#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */
|
||||||
|
#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */
|
||||||
|
#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */
|
||||||
|
|
||||||
|
/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
|
||||||
|
#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */
|
||||||
|
#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */
|
||||||
|
#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */
|
||||||
|
#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */
|
||||||
|
#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */
|
||||||
|
#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */
|
||||||
|
#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */
|
||||||
|
#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */
|
||||||
|
#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */
|
||||||
|
#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */
|
||||||
|
#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */
|
||||||
|
#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */
|
||||||
|
#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */
|
||||||
|
#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */
|
||||||
|
#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */
|
||||||
|
#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */
|
||||||
|
#define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */
|
||||||
|
#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */
|
||||||
|
#define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */
|
||||||
|
#define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */
|
||||||
|
#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */
|
||||||
|
#define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */
|
||||||
|
#define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */
|
||||||
|
#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */
|
||||||
|
#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auxiliary flags: Linux defined - For features scattered in various
|
||||||
|
* CPUID levels like 0x6, 0xA etc, word 7.
|
||||||
|
*
|
||||||
|
* Reuse free bits when adding new feature flags!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */
|
||||||
|
#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
|
||||||
|
|
||||||
|
#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
|
||||||
|
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
|
||||||
|
|
||||||
|
#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
|
||||||
|
|
||||||
|
/* Virtualization flags: Linux defined, word 8 */
|
||||||
|
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
|
||||||
|
#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */
|
||||||
|
#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */
|
||||||
|
#define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */
|
||||||
|
#define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */
|
||||||
|
|
||||||
|
#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */
|
||||||
|
#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */
|
||||||
|
|
||||||
|
|
||||||
|
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
|
||||||
|
#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
|
||||||
|
#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */
|
||||||
|
#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */
|
||||||
|
#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */
|
||||||
|
#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */
|
||||||
|
#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */
|
||||||
|
#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */
|
||||||
|
#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */
|
||||||
|
#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */
|
||||||
|
#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */
|
||||||
|
#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */
|
||||||
|
#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */
|
||||||
|
#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */
|
||||||
|
#define X86_FEATURE_AVX512DQ ( 9*32+17) /* AVX-512 DQ (Double/Quad granular) Instructions */
|
||||||
|
#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */
|
||||||
|
#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */
|
||||||
|
#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */
|
||||||
|
#define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */
|
||||||
|
#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
|
||||||
|
#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
|
||||||
|
#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
|
||||||
|
#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */
|
||||||
|
#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */
|
||||||
|
#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */
|
||||||
|
#define X86_FEATURE_AVX512BW ( 9*32+30) /* AVX-512 BW (Byte/Word granular) Instructions */
|
||||||
|
#define X86_FEATURE_AVX512VL ( 9*32+31) /* AVX-512 VL (128/256 Vector Length) Extensions */
|
||||||
|
|
||||||
|
/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */
|
||||||
|
#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */
|
||||||
|
#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */
|
||||||
|
#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */
|
||||||
|
#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */
|
||||||
|
|
||||||
|
/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */
|
||||||
|
#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */
|
||||||
|
|
||||||
|
/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
|
||||||
|
#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
|
||||||
|
#define X86_FEATURE_CQM_MBM_TOTAL (12*32+ 1) /* LLC Total MBM monitoring */
|
||||||
|
#define X86_FEATURE_CQM_MBM_LOCAL (12*32+ 2) /* LLC Local MBM monitoring */
|
||||||
|
|
||||||
|
/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
|
||||||
|
#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
|
||||||
|
|
||||||
|
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */
|
||||||
|
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
|
||||||
|
#define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */
|
||||||
|
#define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */
|
||||||
|
#define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */
|
||||||
|
#define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */
|
||||||
|
#define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */
|
||||||
|
#define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */
|
||||||
|
#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */
|
||||||
|
#define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */
|
||||||
|
#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */
|
||||||
|
|
||||||
|
/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */
|
||||||
|
#define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */
|
||||||
|
#define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */
|
||||||
|
#define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */
|
||||||
|
#define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */
|
||||||
|
#define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */
|
||||||
|
#define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */
|
||||||
|
#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */
|
||||||
|
#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */
|
||||||
|
#define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */
|
||||||
|
#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */
|
||||||
|
#define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */
|
||||||
|
|
||||||
|
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */
|
||||||
|
#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
|
||||||
|
#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BUG word(s)
|
||||||
|
*/
|
||||||
|
#define X86_BUG(x) (NCAPINTS*32 + (x))
|
||||||
|
|
||||||
|
#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */
|
||||||
|
#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */
|
||||||
|
#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */
|
||||||
|
#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */
|
||||||
|
#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */
|
||||||
|
#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */
|
||||||
|
#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
|
||||||
|
#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
|
||||||
|
#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
/*
|
||||||
|
* 64-bit kernels don't use X86_BUG_ESPFIX. Make the define conditional
|
||||||
|
* to avoid confusion.
|
||||||
|
*/
|
||||||
|
#define X86_BUG_ESPFIX X86_BUG(9) /* "" IRET to 16-bit SS corrupts ESP/RSP high bits */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_CPUFEATURES_H */
|
@ -98,4 +98,27 @@ struct desc_ptr {
|
|||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
/* Access rights as returned by LAR */
|
||||||
|
#define AR_TYPE_RODATA (0 * (1 << 9))
|
||||||
|
#define AR_TYPE_RWDATA (1 * (1 << 9))
|
||||||
|
#define AR_TYPE_RODATA_EXPDOWN (2 * (1 << 9))
|
||||||
|
#define AR_TYPE_RWDATA_EXPDOWN (3 * (1 << 9))
|
||||||
|
#define AR_TYPE_XOCODE (4 * (1 << 9))
|
||||||
|
#define AR_TYPE_XRCODE (5 * (1 << 9))
|
||||||
|
#define AR_TYPE_XOCODE_CONF (6 * (1 << 9))
|
||||||
|
#define AR_TYPE_XRCODE_CONF (7 * (1 << 9))
|
||||||
|
#define AR_TYPE_MASK (7 * (1 << 9))
|
||||||
|
|
||||||
|
#define AR_DPL0 (0 * (1 << 13))
|
||||||
|
#define AR_DPL3 (3 * (1 << 13))
|
||||||
|
#define AR_DPL_MASK (3 * (1 << 13))
|
||||||
|
|
||||||
|
#define AR_A (1 << 8) /* "Accessed" */
|
||||||
|
#define AR_S (1 << 12) /* If clear, "System" segment */
|
||||||
|
#define AR_P (1 << 15) /* "Present" */
|
||||||
|
#define AR_AVL (1 << 20) /* "AVaiLable" (no HW effect) */
|
||||||
|
#define AR_L (1 << 21) /* "Long mode" for code segments */
|
||||||
|
#define AR_DB (1 << 22) /* D/B, effect depends on type */
|
||||||
|
#define AR_G (1 << 23) /* "Granularity" (limit in pages) */
|
||||||
|
|
||||||
#endif /* _ASM_X86_DESC_DEFS_H */
|
#endif /* _ASM_X86_DESC_DEFS_H */
|
||||||
|
@ -28,6 +28,14 @@
|
|||||||
# define DISABLE_CENTAUR_MCR 0
|
# define DISABLE_CENTAUR_MCR 0
|
||||||
#endif /* CONFIG_X86_64 */
|
#endif /* CONFIG_X86_64 */
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
|
||||||
|
# define DISABLE_PKU 0
|
||||||
|
# define DISABLE_OSPKE 0
|
||||||
|
#else
|
||||||
|
# define DISABLE_PKU (1<<(X86_FEATURE_PKU & 31))
|
||||||
|
# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE & 31))
|
||||||
|
#endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure to add features to the correct mask
|
* Make sure to add features to the correct mask
|
||||||
*/
|
*/
|
||||||
@ -41,5 +49,12 @@
|
|||||||
#define DISABLED_MASK7 0
|
#define DISABLED_MASK7 0
|
||||||
#define DISABLED_MASK8 0
|
#define DISABLED_MASK8 0
|
||||||
#define DISABLED_MASK9 (DISABLE_MPX)
|
#define DISABLED_MASK9 (DISABLE_MPX)
|
||||||
|
#define DISABLED_MASK10 0
|
||||||
|
#define DISABLED_MASK11 0
|
||||||
|
#define DISABLED_MASK12 0
|
||||||
|
#define DISABLED_MASK13 0
|
||||||
|
#define DISABLED_MASK14 0
|
||||||
|
#define DISABLED_MASK15 0
|
||||||
|
#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE)
|
||||||
|
|
||||||
#endif /* _ASM_X86_DISABLED_FEATURES_H */
|
#endif /* _ASM_X86_DISABLED_FEATURES_H */
|
||||||
|
@ -46,8 +46,6 @@ bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp);
|
|||||||
#define HAVE_ARCH_DMA_SUPPORTED 1
|
#define HAVE_ARCH_DMA_SUPPORTED 1
|
||||||
extern int dma_supported(struct device *hwdev, u64 mask);
|
extern int dma_supported(struct device *hwdev, u64 mask);
|
||||||
|
|
||||||
#include <asm-generic/dma-mapping-common.h>
|
|
||||||
|
|
||||||
extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
|
extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
|
||||||
dma_addr_t *dma_addr, gfp_t flag,
|
dma_addr_t *dma_addr, gfp_t flag,
|
||||||
struct dma_attrs *attrs);
|
struct dma_attrs *attrs);
|
||||||
|
@ -138,7 +138,7 @@ extern void reserve_top_address(unsigned long reserve);
|
|||||||
extern int fixmaps_set;
|
extern int fixmaps_set;
|
||||||
|
|
||||||
extern pte_t *kmap_pte;
|
extern pte_t *kmap_pte;
|
||||||
extern pgprot_t kmap_prot;
|
#define kmap_prot PAGE_KERNEL
|
||||||
extern pte_t *pkmap_page_table;
|
extern pte_t *pkmap_page_table;
|
||||||
|
|
||||||
void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
|
void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
|
||||||
|
@ -108,6 +108,8 @@ enum xfeature {
|
|||||||
XFEATURE_OPMASK,
|
XFEATURE_OPMASK,
|
||||||
XFEATURE_ZMM_Hi256,
|
XFEATURE_ZMM_Hi256,
|
||||||
XFEATURE_Hi16_ZMM,
|
XFEATURE_Hi16_ZMM,
|
||||||
|
XFEATURE_PT_UNIMPLEMENTED_SO_FAR,
|
||||||
|
XFEATURE_PKRU,
|
||||||
|
|
||||||
XFEATURE_MAX,
|
XFEATURE_MAX,
|
||||||
};
|
};
|
||||||
@ -120,6 +122,7 @@ enum xfeature {
|
|||||||
#define XFEATURE_MASK_OPMASK (1 << XFEATURE_OPMASK)
|
#define XFEATURE_MASK_OPMASK (1 << XFEATURE_OPMASK)
|
||||||
#define XFEATURE_MASK_ZMM_Hi256 (1 << XFEATURE_ZMM_Hi256)
|
#define XFEATURE_MASK_ZMM_Hi256 (1 << XFEATURE_ZMM_Hi256)
|
||||||
#define XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM)
|
#define XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM)
|
||||||
|
#define XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU)
|
||||||
|
|
||||||
#define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
|
#define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
|
||||||
#define XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK \
|
#define XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK \
|
||||||
@ -212,6 +215,15 @@ struct avx_512_hi16_state {
|
|||||||
struct reg_512_bit hi16_zmm[16];
|
struct reg_512_bit hi16_zmm[16];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* State component 9: 32-bit PKRU register. The state is
|
||||||
|
* 8 bytes long but only 4 bytes is used currently.
|
||||||
|
*/
|
||||||
|
struct pkru_state {
|
||||||
|
u32 pkru;
|
||||||
|
u32 pad;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct xstate_header {
|
struct xstate_header {
|
||||||
u64 xfeatures;
|
u64 xfeatures;
|
||||||
u64 xcomp_bv;
|
u64 xcomp_bv;
|
||||||
|
@ -152,7 +152,7 @@ build_mmio_write(writeq, "q", unsigned long, "r", :"memory")
|
|||||||
* If the area you are trying to map is a PCI BAR you should have a
|
* If the area you are trying to map is a PCI BAR you should have a
|
||||||
* look at pci_iomap().
|
* look at pci_iomap().
|
||||||
*/
|
*/
|
||||||
//extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
|
extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
|
||||||
extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
|
extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
|
||||||
#define ioremap_uc ioremap_uc
|
#define ioremap_uc ioremap_uc
|
||||||
|
|
||||||
@ -160,15 +160,15 @@ extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
|
|||||||
extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
|
extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
|
||||||
unsigned long prot_val);
|
unsigned long prot_val);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The default ioremap() behavior is non-cached:
|
* The default ioremap() behavior is non-cached:
|
||||||
*/
|
*/
|
||||||
//static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
|
static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
|
||||||
//{
|
{
|
||||||
// return ioremap_nocache(offset, size);
|
return ioremap_nocache(offset, size);
|
||||||
//}
|
}
|
||||||
|
|
||||||
//extern void iounmap(volatile void __iomem *addr);
|
extern void iounmap(volatile void __iomem *addr);
|
||||||
|
|
||||||
extern void set_iounmap_nonlazy(void);
|
extern void set_iounmap_nonlazy(void);
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
|
|||||||
|
|
||||||
extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
|
extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
|
||||||
enum page_cache_mode pcm);
|
enum page_cache_mode pcm);
|
||||||
//extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
|
extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
|
||||||
extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size);
|
extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size);
|
||||||
|
|
||||||
extern bool is_early_ioremap_ptep(pte_t *ptep);
|
extern bool is_early_ioremap_ptep(pte_t *ptep);
|
||||||
|
40
drivers/include/asm/iomap.h
Normal file
40
drivers/include/asm/iomap.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef _ASM_X86_IOMAP_H
|
||||||
|
#define _ASM_X86_IOMAP_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Ingo Molnar
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <asm/cacheflush.h>
|
||||||
|
#include <asm/pgtable.h>
|
||||||
|
|
||||||
|
void __iomem *
|
||||||
|
iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
|
||||||
|
|
||||||
|
void
|
||||||
|
iounmap_atomic(void __iomem *kvaddr);
|
||||||
|
|
||||||
|
int
|
||||||
|
iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot);
|
||||||
|
|
||||||
|
void
|
||||||
|
iomap_free(resource_size_t base, unsigned long size);
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_IOMAP_H */
|
@ -1,7 +1,12 @@
|
|||||||
#ifndef _ASM_X86_MSR_INDEX_H
|
#ifndef _ASM_X86_MSR_INDEX_H
|
||||||
#define _ASM_X86_MSR_INDEX_H
|
#define _ASM_X86_MSR_INDEX_H
|
||||||
|
|
||||||
/* CPU model specific register (MSR) numbers */
|
/*
|
||||||
|
* CPU model specific register (MSR) numbers.
|
||||||
|
*
|
||||||
|
* Do not add new entries to this file unless the definitions are shared
|
||||||
|
* between multiple compilation units.
|
||||||
|
*/
|
||||||
|
|
||||||
/* x86-64 specific MSRs */
|
/* x86-64 specific MSRs */
|
||||||
#define MSR_EFER 0xc0000080 /* extended feature register */
|
#define MSR_EFER 0xc0000080 /* extended feature register */
|
||||||
@ -162,6 +167,14 @@
|
|||||||
#define MSR_PKG_C9_RESIDENCY 0x00000631
|
#define MSR_PKG_C9_RESIDENCY 0x00000631
|
||||||
#define MSR_PKG_C10_RESIDENCY 0x00000632
|
#define MSR_PKG_C10_RESIDENCY 0x00000632
|
||||||
|
|
||||||
|
/* Interrupt Response Limit */
|
||||||
|
#define MSR_PKGC3_IRTL 0x0000060a
|
||||||
|
#define MSR_PKGC6_IRTL 0x0000060b
|
||||||
|
#define MSR_PKGC7_IRTL 0x0000060c
|
||||||
|
#define MSR_PKGC8_IRTL 0x00000633
|
||||||
|
#define MSR_PKGC9_IRTL 0x00000634
|
||||||
|
#define MSR_PKGC10_IRTL 0x00000635
|
||||||
|
|
||||||
/* Run Time Average Power Limiting (RAPL) Interface */
|
/* Run Time Average Power Limiting (RAPL) Interface */
|
||||||
|
|
||||||
#define MSR_RAPL_POWER_UNIT 0x00000606
|
#define MSR_RAPL_POWER_UNIT 0x00000606
|
||||||
@ -185,6 +198,7 @@
|
|||||||
#define MSR_PP1_ENERGY_STATUS 0x00000641
|
#define MSR_PP1_ENERGY_STATUS 0x00000641
|
||||||
#define MSR_PP1_POLICY 0x00000642
|
#define MSR_PP1_POLICY 0x00000642
|
||||||
|
|
||||||
|
/* Config TDP MSRs */
|
||||||
#define MSR_CONFIG_TDP_NOMINAL 0x00000648
|
#define MSR_CONFIG_TDP_NOMINAL 0x00000648
|
||||||
#define MSR_CONFIG_TDP_LEVEL_1 0x00000649
|
#define MSR_CONFIG_TDP_LEVEL_1 0x00000649
|
||||||
#define MSR_CONFIG_TDP_LEVEL_2 0x0000064A
|
#define MSR_CONFIG_TDP_LEVEL_2 0x0000064A
|
||||||
@ -205,13 +219,6 @@
|
|||||||
#define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0
|
#define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0
|
||||||
#define MSR_RING_PERF_LIMIT_REASONS 0x000006B1
|
#define MSR_RING_PERF_LIMIT_REASONS 0x000006B1
|
||||||
|
|
||||||
/* Config TDP MSRs */
|
|
||||||
#define MSR_CONFIG_TDP_NOMINAL 0x00000648
|
|
||||||
#define MSR_CONFIG_TDP_LEVEL1 0x00000649
|
|
||||||
#define MSR_CONFIG_TDP_LEVEL2 0x0000064A
|
|
||||||
#define MSR_CONFIG_TDP_CONTROL 0x0000064B
|
|
||||||
#define MSR_TURBO_ACTIVATION_RATIO 0x0000064C
|
|
||||||
|
|
||||||
/* Hardware P state interface */
|
/* Hardware P state interface */
|
||||||
#define MSR_PPERF 0x0000064e
|
#define MSR_PPERF 0x0000064e
|
||||||
#define MSR_PERF_LIMIT_REASONS 0x0000064f
|
#define MSR_PERF_LIMIT_REASONS 0x0000064f
|
||||||
@ -230,10 +237,10 @@
|
|||||||
#define HWP_PACKAGE_LEVEL_REQUEST_BIT (1<<11)
|
#define HWP_PACKAGE_LEVEL_REQUEST_BIT (1<<11)
|
||||||
|
|
||||||
/* IA32_HWP_CAPABILITIES */
|
/* IA32_HWP_CAPABILITIES */
|
||||||
#define HWP_HIGHEST_PERF(x) (x & 0xff)
|
#define HWP_HIGHEST_PERF(x) (((x) >> 0) & 0xff)
|
||||||
#define HWP_GUARANTEED_PERF(x) ((x & (0xff << 8)) >>8)
|
#define HWP_GUARANTEED_PERF(x) (((x) >> 8) & 0xff)
|
||||||
#define HWP_MOSTEFFICIENT_PERF(x) ((x & (0xff << 16)) >>16)
|
#define HWP_MOSTEFFICIENT_PERF(x) (((x) >> 16) & 0xff)
|
||||||
#define HWP_LOWEST_PERF(x) ((x & (0xff << 24)) >>24)
|
#define HWP_LOWEST_PERF(x) (((x) >> 24) & 0xff)
|
||||||
|
|
||||||
/* IA32_HWP_REQUEST */
|
/* IA32_HWP_REQUEST */
|
||||||
#define HWP_MIN_PERF(x) (x & 0xff)
|
#define HWP_MIN_PERF(x) (x & 0xff)
|
||||||
|
@ -42,14 +42,6 @@ struct saved_msrs {
|
|||||||
struct saved_msr *array;
|
struct saved_msr *array;
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
|
* both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
|
||||||
* constraint has different meanings. For i386, "A" means exactly
|
* constraint has different meanings. For i386, "A" means exactly
|
||||||
@ -67,11 +59,34 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
|
|||||||
#define EAX_EDX_RET(val, low, high) "=A" (val)
|
#define EAX_EDX_RET(val, low, high) "=A" (val)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_TRACEPOINTS
|
||||||
|
/*
|
||||||
|
* Be very careful with includes. This header is prone to include loops.
|
||||||
|
*/
|
||||||
|
#include <asm/atomic.h>
|
||||||
|
#include <linux/tracepoint-defs.h>
|
||||||
|
|
||||||
|
extern struct tracepoint __tracepoint_read_msr;
|
||||||
|
extern struct tracepoint __tracepoint_write_msr;
|
||||||
|
extern struct tracepoint __tracepoint_rdpmc;
|
||||||
|
#define msr_tracepoint_active(t) static_key_false(&(t).key)
|
||||||
|
extern void do_trace_write_msr(unsigned msr, u64 val, int failed);
|
||||||
|
extern void do_trace_read_msr(unsigned msr, u64 val, int failed);
|
||||||
|
extern void do_trace_rdpmc(unsigned msr, u64 val, int failed);
|
||||||
|
#else
|
||||||
|
#define msr_tracepoint_active(t) false
|
||||||
|
static inline void do_trace_write_msr(unsigned msr, u64 val, int failed) {}
|
||||||
|
static inline void do_trace_read_msr(unsigned msr, u64 val, int failed) {}
|
||||||
|
static inline void do_trace_rdpmc(unsigned msr, u64 val, int failed) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline unsigned long long native_read_msr(unsigned int msr)
|
static inline unsigned long long native_read_msr(unsigned int msr)
|
||||||
{
|
{
|
||||||
DECLARE_ARGS(val, low, high);
|
DECLARE_ARGS(val, low, high);
|
||||||
|
|
||||||
asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
|
asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
|
||||||
|
if (msr_tracepoint_active(__tracepoint_read_msr))
|
||||||
|
do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
|
||||||
return EAX_EDX_VAL(val, low, high);
|
return EAX_EDX_VAL(val, low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +103,8 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
|
|||||||
_ASM_EXTABLE(2b, 3b)
|
_ASM_EXTABLE(2b, 3b)
|
||||||
: [err] "=r" (*err), EAX_EDX_RET(val, low, high)
|
: [err] "=r" (*err), EAX_EDX_RET(val, low, high)
|
||||||
: "c" (msr), [fault] "i" (-EIO));
|
: "c" (msr), [fault] "i" (-EIO));
|
||||||
|
if (msr_tracepoint_active(__tracepoint_read_msr))
|
||||||
|
do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
|
||||||
return EAX_EDX_VAL(val, low, high);
|
return EAX_EDX_VAL(val, low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +112,8 @@ static inline void native_write_msr(unsigned int msr,
|
|||||||
unsigned low, unsigned high)
|
unsigned low, unsigned high)
|
||||||
{
|
{
|
||||||
asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
|
asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
|
||||||
|
if (msr_tracepoint_active(__tracepoint_write_msr))
|
||||||
|
do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can be uninlined because referenced by paravirt */
|
/* Can be uninlined because referenced by paravirt */
|
||||||
@ -112,6 +131,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
|
|||||||
: "c" (msr), "0" (low), "d" (high),
|
: "c" (msr), "0" (low), "d" (high),
|
||||||
[fault] "i" (-EIO)
|
[fault] "i" (-EIO)
|
||||||
: "memory");
|
: "memory");
|
||||||
|
if (msr_tracepoint_active(__tracepoint_write_msr))
|
||||||
|
do_trace_write_msr(msr, ((u64)high << 32 | low), err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,11 +157,42 @@ static __always_inline unsigned long long rdtsc(void)
|
|||||||
return EAX_EDX_VAL(val, low, high);
|
return EAX_EDX_VAL(val, low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rdtsc_ordered() - read the current TSC in program order
|
||||||
|
*
|
||||||
|
* rdtsc_ordered() returns the result of RDTSC as a 64-bit integer.
|
||||||
|
* It is ordered like a load to a global in-memory counter. It should
|
||||||
|
* be impossible to observe non-monotonic rdtsc_unordered() behavior
|
||||||
|
* across multiple CPUs as long as the TSC is synced.
|
||||||
|
*/
|
||||||
|
static __always_inline unsigned long long rdtsc_ordered(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The RDTSC instruction is not ordered relative to memory
|
||||||
|
* access. The Intel SDM and the AMD APM are both vague on this
|
||||||
|
* point, but empirically an RDTSC instruction can be
|
||||||
|
* speculatively executed before prior loads. An RDTSC
|
||||||
|
* immediately after an appropriate barrier appears to be
|
||||||
|
* ordered as a normal load, that is, it provides the same
|
||||||
|
* ordering guarantees as reading from a global memory location
|
||||||
|
* that some other imaginary CPU is updating continuously with a
|
||||||
|
* time stamp.
|
||||||
|
*/
|
||||||
|
alternative_2("", "mfence", X86_FEATURE_MFENCE_RDTSC,
|
||||||
|
"lfence", X86_FEATURE_LFENCE_RDTSC);
|
||||||
|
return rdtsc();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deprecated, keep it for a cycle for easier merging: */
|
||||||
|
#define rdtscll(now) do { (now) = rdtsc_ordered(); } while (0)
|
||||||
|
|
||||||
static inline unsigned long long native_read_pmc(int counter)
|
static inline unsigned long long native_read_pmc(int counter)
|
||||||
{
|
{
|
||||||
DECLARE_ARGS(val, low, high);
|
DECLARE_ARGS(val, low, high);
|
||||||
|
|
||||||
asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
|
asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
|
||||||
|
if (msr_tracepoint_active(__tracepoint_rdpmc))
|
||||||
|
do_trace_rdpmc(counter, EAX_EDX_VAL(val, low, high), 0);
|
||||||
return EAX_EDX_VAL(val, low, high);
|
return EAX_EDX_VAL(val, low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
/* PAGE_SHIFT determines the page size */
|
/* PAGE_SHIFT determines the page size */
|
||||||
#define PAGE_SHIFT 12
|
#define PAGE_SHIFT 12
|
||||||
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
|
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
|
||||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||||
|
|
||||||
#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
|
#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
|
||||||
#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
|
#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
|
||||||
|
@ -20,6 +20,9 @@ struct pci_sysdata {
|
|||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
void *iommu; /* IOMMU private data */
|
void *iommu; /* IOMMU private data */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
|
||||||
|
void *fwnode; /* IRQ domain for MSI assignment */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int pci_routeirq;
|
extern int pci_routeirq;
|
||||||
@ -32,6 +35,7 @@ extern int noioapicreroute;
|
|||||||
static inline int pci_domain_nr(struct pci_bus *bus)
|
static inline int pci_domain_nr(struct pci_bus *bus)
|
||||||
{
|
{
|
||||||
struct pci_sysdata *sd = bus->sysdata;
|
struct pci_sysdata *sd = bus->sysdata;
|
||||||
|
|
||||||
return sd->domain;
|
return sd->domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct pci_bus *bus)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
|
||||||
|
static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
|
||||||
|
{
|
||||||
|
struct pci_sysdata *sd = bus->sysdata;
|
||||||
|
|
||||||
|
return sd->fwnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pci_root_bus_fwnode _pci_root_bus_fwnode
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Can be used to override the logic in pci_scan_bus for skipping
|
/* Can be used to override the logic in pci_scan_bus for skipping
|
||||||
already-configured bus numbers - to be used for buggy BIOSes
|
already-configured bus numbers - to be used for buggy BIOSes
|
||||||
or architectures with incomplete PCI setup by the loader */
|
or architectures with incomplete PCI setup by the loader */
|
||||||
@ -105,9 +120,6 @@ void native_restore_msi_irqs(struct pci_dev *dev);
|
|||||||
#include <asm/pci_64.h>
|
#include <asm/pci_64.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* implement the pci_ DMA API in terms of the generic device dma_ one */
|
|
||||||
#include <asm-generic/pci-dma-compat.h>
|
|
||||||
|
|
||||||
/* generic pci stuff */
|
/* generic pci stuff */
|
||||||
#include <asm-generic/pci.h>
|
#include <asm-generic/pci.h>
|
||||||
|
|
||||||
@ -132,7 +144,7 @@ cpumask_of_pcibus(const struct pci_bus *bus)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct pci_setup_rom {
|
struct pci_setup_rom {
|
||||||
uint16_t vendor;
|
uint16_t vendor;
|
||||||
uint16_t devid;
|
uint16_t devid;
|
||||||
uint64_t pcilen;
|
uint64_t pcilen;
|
||||||
unsigned long segment;
|
unsigned long segment;
|
||||||
|
@ -487,17 +487,6 @@ static inline int pte_devmap(pte_t a)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define pte_accessible pte_accessible
|
#define pte_accessible pte_accessible
|
||||||
static inline bool pte_accessible(struct mm_struct *mm, pte_t a)
|
|
||||||
{
|
|
||||||
if (pte_flags(a) & _PAGE_PRESENT)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if ((pte_flags(a) & _PAGE_PROTNONE) &&
|
|
||||||
mm_tlb_flush_pending(mm))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int pte_hidden(pte_t pte)
|
static inline int pte_hidden(pte_t pte)
|
||||||
{
|
{
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
#include <asm/fixmap.h>
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
|
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
@ -20,13 +20,18 @@
|
|||||||
#define _PAGE_BIT_SOFTW2 10 /* " */
|
#define _PAGE_BIT_SOFTW2 10 /* " */
|
||||||
#define _PAGE_BIT_SOFTW3 11 /* " */
|
#define _PAGE_BIT_SOFTW3 11 /* " */
|
||||||
#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
|
#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
|
||||||
|
#define _PAGE_BIT_SOFTW4 58 /* available for programmer */
|
||||||
|
#define _PAGE_BIT_PKEY_BIT0 59 /* Protection Keys, bit 1/4 */
|
||||||
|
#define _PAGE_BIT_PKEY_BIT1 60 /* Protection Keys, bit 2/4 */
|
||||||
|
#define _PAGE_BIT_PKEY_BIT2 61 /* Protection Keys, bit 3/4 */
|
||||||
|
#define _PAGE_BIT_PKEY_BIT3 62 /* Protection Keys, bit 4/4 */
|
||||||
|
#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
|
||||||
|
|
||||||
#define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1
|
#define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1
|
||||||
#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1
|
#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1
|
||||||
#define _PAGE_BIT_HIDDEN _PAGE_BIT_SOFTW3 /* hidden by kmemcheck */
|
#define _PAGE_BIT_HIDDEN _PAGE_BIT_SOFTW3 /* hidden by kmemcheck */
|
||||||
#define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */
|
#define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */
|
||||||
#define _PAGE_BIT_SOFTW4 58 /* available for programmer */
|
#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4
|
||||||
#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4
|
|
||||||
#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
|
|
||||||
|
|
||||||
/* If _PAGE_BIT_PRESENT is clear, we use these: */
|
/* If _PAGE_BIT_PRESENT is clear, we use these: */
|
||||||
/* - if the user mapped it with PROT_NONE; pte_present gives true */
|
/* - if the user mapped it with PROT_NONE; pte_present gives true */
|
||||||
@ -47,8 +52,24 @@
|
|||||||
#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
|
#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
|
||||||
#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
|
#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
|
||||||
#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
|
#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
|
||||||
|
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
|
||||||
|
#define _PAGE_PKEY_BIT0 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT0)
|
||||||
|
#define _PAGE_PKEY_BIT1 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT1)
|
||||||
|
#define _PAGE_PKEY_BIT2 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT2)
|
||||||
|
#define _PAGE_PKEY_BIT3 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT3)
|
||||||
|
#else
|
||||||
|
#define _PAGE_PKEY_BIT0 (_AT(pteval_t, 0))
|
||||||
|
#define _PAGE_PKEY_BIT1 (_AT(pteval_t, 0))
|
||||||
|
#define _PAGE_PKEY_BIT2 (_AT(pteval_t, 0))
|
||||||
|
#define _PAGE_PKEY_BIT3 (_AT(pteval_t, 0))
|
||||||
|
#endif
|
||||||
#define __HAVE_ARCH_PTE_SPECIAL
|
#define __HAVE_ARCH_PTE_SPECIAL
|
||||||
|
|
||||||
|
#define _PAGE_PKEY_MASK (_PAGE_PKEY_BIT0 | \
|
||||||
|
_PAGE_PKEY_BIT1 | \
|
||||||
|
_PAGE_PKEY_BIT2 | \
|
||||||
|
_PAGE_PKEY_BIT3)
|
||||||
|
|
||||||
#ifdef CONFIG_KMEMCHECK
|
#ifdef CONFIG_KMEMCHECK
|
||||||
#define _PAGE_HIDDEN (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN)
|
#define _PAGE_HIDDEN (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN)
|
||||||
#else
|
#else
|
||||||
@ -99,7 +120,12 @@
|
|||||||
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \
|
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \
|
||||||
_PAGE_DIRTY)
|
_PAGE_DIRTY)
|
||||||
|
|
||||||
/* Set of bits not changed in pte_modify */
|
/*
|
||||||
|
* Set of bits not changed in pte_modify. The pte's
|
||||||
|
* protection key is treated like _PAGE_RW, for
|
||||||
|
* instance, and is *not* included in this mask since
|
||||||
|
* pte_modify() does modify it.
|
||||||
|
*/
|
||||||
#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
|
#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
|
||||||
_PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
_PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
||||||
_PAGE_SOFT_DIRTY)
|
_PAGE_SOFT_DIRTY)
|
||||||
@ -215,7 +241,10 @@ enum page_cache_mode {
|
|||||||
/* Extracts the PFN from a (pte|pmd|pud|pgd)val_t of a 4KB page */
|
/* Extracts the PFN from a (pte|pmd|pud|pgd)val_t of a 4KB page */
|
||||||
#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK)
|
#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK)
|
||||||
|
|
||||||
/* Extracts the flags from a (pte|pmd|pud|pgd)val_t of a 4KB page */
|
/*
|
||||||
|
* Extracts the flags from a (pte|pmd|pud|pgd)val_t
|
||||||
|
* This includes the protection key value.
|
||||||
|
*/
|
||||||
#define PTE_FLAGS_MASK (~PTE_PFN_MASK)
|
#define PTE_FLAGS_MASK (~PTE_PFN_MASK)
|
||||||
|
|
||||||
typedef struct pgprot { pgprotval_t pgprot; } pgprot_t;
|
typedef struct pgprot { pgprotval_t pgprot; } pgprot_t;
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
#ifndef _ASM_X86_POSIX_TYPES_32_H
|
|
||||||
#define _ASM_X86_POSIX_TYPES_32_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is generally used by user-level software, so you need to
|
|
||||||
* be a little careful about namespace pollution etc. Also, we cannot
|
|
||||||
* assume GCC is being used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef unsigned long __kernel_ino_t;
|
|
||||||
typedef unsigned short __kernel_mode_t;
|
|
||||||
typedef unsigned short __kernel_nlink_t;
|
|
||||||
typedef long __kernel_off_t;
|
|
||||||
typedef int __kernel_pid_t;
|
|
||||||
typedef unsigned short __kernel_ipc_pid_t;
|
|
||||||
typedef unsigned short __kernel_uid_t;
|
|
||||||
typedef unsigned short __kernel_gid_t;
|
|
||||||
typedef unsigned int __kernel_size_t;
|
|
||||||
typedef int __kernel_ssize_t;
|
|
||||||
typedef int __kernel_ptrdiff_t;
|
|
||||||
typedef long __kernel_time_t;
|
|
||||||
typedef long __kernel_suseconds_t;
|
|
||||||
typedef long __kernel_clock_t;
|
|
||||||
typedef int __kernel_timer_t;
|
|
||||||
typedef int __kernel_clockid_t;
|
|
||||||
typedef int __kernel_daddr_t;
|
|
||||||
typedef char * __kernel_caddr_t;
|
|
||||||
typedef unsigned short __kernel_uid16_t;
|
|
||||||
typedef unsigned short __kernel_gid16_t;
|
|
||||||
typedef unsigned int __kernel_uid32_t;
|
|
||||||
typedef unsigned int __kernel_gid32_t;
|
|
||||||
|
|
||||||
typedef unsigned short __kernel_old_uid_t;
|
|
||||||
typedef unsigned short __kernel_old_gid_t;
|
|
||||||
typedef unsigned short __kernel_old_dev_t;
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
typedef long long __kernel_loff_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int val[2];
|
|
||||||
} __kernel_fsid_t;
|
|
||||||
|
|
||||||
#if defined(__KERNEL__)
|
|
||||||
|
|
||||||
#undef __FD_SET
|
|
||||||
#define __FD_SET(fd,fdsetp) \
|
|
||||||
asm volatile("btsl %1,%0": \
|
|
||||||
"+m" (*(__kernel_fd_set *)(fdsetp)) \
|
|
||||||
: "r" ((int)(fd)))
|
|
||||||
|
|
||||||
#undef __FD_CLR
|
|
||||||
#define __FD_CLR(fd,fdsetp) \
|
|
||||||
asm volatile("btrl %1,%0": \
|
|
||||||
"+m" (*(__kernel_fd_set *)(fdsetp)) \
|
|
||||||
: "r" ((int) (fd)))
|
|
||||||
|
|
||||||
#undef __FD_ISSET
|
|
||||||
#define __FD_ISSET(fd,fdsetp) \
|
|
||||||
(__extension__ \
|
|
||||||
({ \
|
|
||||||
unsigned char __result; \
|
|
||||||
asm volatile("btl %1,%2 ; setb %0" \
|
|
||||||
: "=q" (__result) \
|
|
||||||
: "r" ((int)(fd)), \
|
|
||||||
"m" (*(__kernel_fd_set *)(fdsetp))); \
|
|
||||||
__result; \
|
|
||||||
}))
|
|
||||||
|
|
||||||
#undef __FD_ZERO
|
|
||||||
#define __FD_ZERO(fdsetp) \
|
|
||||||
do { \
|
|
||||||
int __d0, __d1; \
|
|
||||||
asm volatile("cld ; rep ; stosl" \
|
|
||||||
: "=m" (*(__kernel_fd_set *)(fdsetp)), \
|
|
||||||
"=&c" (__d0), "=&D" (__d1) \
|
|
||||||
: "a" (0), "1" (__FDSET_LONGS), \
|
|
||||||
"2" ((__kernel_fd_set *)(fdsetp)) \
|
|
||||||
: "memory"); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif /* defined(__KERNEL__) */
|
|
||||||
|
|
||||||
#endif /* _ASM_X86_POSIX_TYPES_32_H */
|
|
@ -13,7 +13,7 @@ struct vm86;
|
|||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
#include <uapi/asm/sigcontext.h>
|
#include <uapi/asm/sigcontext.h>
|
||||||
#include <asm/current.h>
|
#include <asm/current.h>
|
||||||
#include <asm/cpufeature.h>
|
#include <asm/cpufeatures.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/pgtable_types.h>
|
#include <asm/pgtable_types.h>
|
||||||
#include <asm/percpu.h>
|
#include <asm/percpu.h>
|
||||||
@ -24,7 +24,6 @@ struct vm86;
|
|||||||
#include <asm/fpu/types.h>
|
#include <asm/fpu/types.h>
|
||||||
|
|
||||||
#include <linux/personality.h>
|
#include <linux/personality.h>
|
||||||
#include <linux/cpumask.h>
|
|
||||||
#include <linux/cache.h>
|
#include <linux/cache.h>
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
#include <linux/math64.h>
|
#include <linux/math64.h>
|
||||||
@ -129,10 +128,10 @@ struct cpuinfo_x86 {
|
|||||||
u16 booted_cores;
|
u16 booted_cores;
|
||||||
/* Physical processor id: */
|
/* Physical processor id: */
|
||||||
u16 phys_proc_id;
|
u16 phys_proc_id;
|
||||||
|
/* Logical processor id: */
|
||||||
|
u16 logical_proc_id;
|
||||||
/* Core id: */
|
/* Core id: */
|
||||||
u16 cpu_core_id;
|
u16 cpu_core_id;
|
||||||
/* Compute unit id */
|
|
||||||
u8 compute_unit_id;
|
|
||||||
/* Index into per_cpu list: */
|
/* Index into per_cpu list: */
|
||||||
u16 cpu_index;
|
u16 cpu_index;
|
||||||
u32 microcode;
|
u32 microcode;
|
||||||
@ -296,10 +295,13 @@ struct tss_struct {
|
|||||||
*/
|
*/
|
||||||
unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
|
unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
/*
|
/*
|
||||||
* Space for the temporary SYSENTER stack:
|
* Space for the temporary SYSENTER stack.
|
||||||
*/
|
*/
|
||||||
|
unsigned long SYSENTER_stack_canary;
|
||||||
unsigned long SYSENTER_stack[64];
|
unsigned long SYSENTER_stack[64];
|
||||||
|
#endif
|
||||||
|
|
||||||
} ____cacheline_aligned;
|
} ____cacheline_aligned;
|
||||||
|
|
||||||
@ -660,10 +662,9 @@ extern char ignore_fpu_irq;
|
|||||||
*/
|
*/
|
||||||
static inline void prefetch(const void *x)
|
static inline void prefetch(const void *x)
|
||||||
{
|
{
|
||||||
alternative_input(BASE_PREFETCH,
|
alternative_input(BASE_PREFETCH, "prefetchnta %P1",
|
||||||
"prefetchnta (%1)",
|
|
||||||
X86_FEATURE_XMM,
|
X86_FEATURE_XMM,
|
||||||
"r" (x));
|
"m" (*(const char *)x));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -673,10 +674,9 @@ static inline void prefetch(const void *x)
|
|||||||
*/
|
*/
|
||||||
static inline void prefetchw(const void *x)
|
static inline void prefetchw(const void *x)
|
||||||
{
|
{
|
||||||
alternative_input(BASE_PREFETCH,
|
alternative_input(BASE_PREFETCH, "prefetchw %P1",
|
||||||
"prefetchw (%1)",
|
X86_FEATURE_3DNOWPREFETCH,
|
||||||
X86_FEATURE_3DNOW,
|
"m" (*(const char *)x));
|
||||||
"r" (x));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spin_lock_prefetch(const void *x)
|
static inline void spin_lock_prefetch(const void *x)
|
||||||
@ -757,7 +757,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
|
|||||||
* Return saved PC of a blocked thread.
|
* Return saved PC of a blocked thread.
|
||||||
* What is this good for? it will be always the scheduler or ret_from_fork.
|
* What is this good for? it will be always the scheduler or ret_from_fork.
|
||||||
*/
|
*/
|
||||||
#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8))
|
#define thread_saved_pc(t) READ_ONCE_NOCHECK(*(unsigned long *)((t)->thread.sp - 8))
|
||||||
|
|
||||||
#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)
|
#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)
|
||||||
extern unsigned long KSTK_ESP(struct task_struct *task);
|
extern unsigned long KSTK_ESP(struct task_struct *task);
|
||||||
|
@ -65,10 +65,5 @@ struct pvclock_vsyscall_time_info {
|
|||||||
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
|
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
|
||||||
|
|
||||||
#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info)
|
#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info)
|
||||||
#define PVCLOCK_VSYSCALL_NR_PAGES (((NR_CPUS-1)/(PAGE_SIZE/PVTI_SIZE))+1)
|
|
||||||
|
|
||||||
int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i,
|
|
||||||
int size);
|
|
||||||
struct pvclock_vcpu_time_info *pvclock_get_vsyscall_time_info(int cpu);
|
|
||||||
|
|
||||||
#endif /* _ASM_X86_PVCLOCK_H */
|
#endif /* _ASM_X86_PVCLOCK_H */
|
||||||
|
@ -92,5 +92,12 @@
|
|||||||
#define REQUIRED_MASK7 0
|
#define REQUIRED_MASK7 0
|
||||||
#define REQUIRED_MASK8 0
|
#define REQUIRED_MASK8 0
|
||||||
#define REQUIRED_MASK9 0
|
#define REQUIRED_MASK9 0
|
||||||
|
#define REQUIRED_MASK10 0
|
||||||
|
#define REQUIRED_MASK11 0
|
||||||
|
#define REQUIRED_MASK12 0
|
||||||
|
#define REQUIRED_MASK13 0
|
||||||
|
#define REQUIRED_MASK14 0
|
||||||
|
#define REQUIRED_MASK15 0
|
||||||
|
#define REQUIRED_MASK16 0
|
||||||
|
|
||||||
#endif /* _ASM_X86_REQUIRED_FEATURES_H */
|
#endif /* _ASM_X86_REQUIRED_FEATURES_H */
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* This should be totally fair - if anything is waiting, a process that wants a
|
* This should be totally fair - if anything is waiting, a process that wants a
|
||||||
* lock will go to the back of the queue. When the currently active lock is
|
* lock will go to the back of the queue. When the currently active lock is
|
||||||
* released, if there's a writer at the front of the queue, then that and only
|
* released, if there's a writer at the front of the queue, then that and only
|
||||||
* that will be woken up; if there's a bunch of consequtive readers at the
|
* that will be woken up; if there's a bunch of consecutive readers at the
|
||||||
* front, then they'll all be woken up, but no other readers will be.
|
* front, then they'll all be woken up, but no other readers will be.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
#ifndef __ASM_GENERIC_SCATTERLIST_H
|
|
||||||
#define __ASM_GENERIC_SCATTERLIST_H
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
struct scatterlist {
|
|
||||||
#ifdef CONFIG_DEBUG_SG
|
|
||||||
unsigned long sg_magic;
|
|
||||||
#endif
|
|
||||||
unsigned long page_link;
|
|
||||||
unsigned int offset;
|
|
||||||
unsigned int length;
|
|
||||||
dma_addr_t dma_address;
|
|
||||||
#ifdef CONFIG_NEED_SG_DMA_LENGTH
|
|
||||||
unsigned int dma_length;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These macros should be used after a dma_map_sg call has been done
|
|
||||||
* to get bus addresses of each of the SG entries and their lengths.
|
|
||||||
* You should only work with the number of sg entries pci_map_sg
|
|
||||||
* returns, or alternatively stop on the first sg_dma_len(sg) which
|
|
||||||
* is 0.
|
|
||||||
*/
|
|
||||||
#define sg_dma_address(sg) ((sg)->dma_address)
|
|
||||||
|
|
||||||
#ifdef CONFIG_NEED_SG_DMA_LENGTH
|
|
||||||
#define sg_dma_len(sg) ((sg)->dma_length)
|
|
||||||
#else
|
|
||||||
#define sg_dma_len(sg) ((sg)->length)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ARCH_HAS_SG_CHAIN
|
|
||||||
|
|
||||||
int dma_map_sg(struct device *dev, struct scatterlist *sglist,
|
|
||||||
int nelems, int dir);
|
|
||||||
|
|
||||||
#endif /* __ASM_GENERIC_SCATTERLIST_H */
|
|
79
drivers/include/asm/smap.h
Normal file
79
drivers/include/asm/smap.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Supervisor Mode Access Prevention support
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Intel Corporation
|
||||||
|
* Author: H. Peter Anvin <hpa@linux.intel.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; version 2
|
||||||
|
* of the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ASM_X86_SMAP_H
|
||||||
|
#define _ASM_X86_SMAP_H
|
||||||
|
|
||||||
|
#include <linux/stringify.h>
|
||||||
|
#include <asm/nops.h>
|
||||||
|
#include <asm/cpufeatures.h>
|
||||||
|
|
||||||
|
/* "Raw" instruction opcodes */
|
||||||
|
#define __ASM_CLAC .byte 0x0f,0x01,0xca
|
||||||
|
#define __ASM_STAC .byte 0x0f,0x01,0xcb
|
||||||
|
|
||||||
|
#ifdef __ASSEMBLY__
|
||||||
|
|
||||||
|
#include <asm/alternative-asm.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_SMAP
|
||||||
|
|
||||||
|
#define ASM_CLAC \
|
||||||
|
ALTERNATIVE "", __stringify(__ASM_CLAC), X86_FEATURE_SMAP
|
||||||
|
|
||||||
|
#define ASM_STAC \
|
||||||
|
ALTERNATIVE "", __stringify(__ASM_STAC), X86_FEATURE_SMAP
|
||||||
|
|
||||||
|
#else /* CONFIG_X86_SMAP */
|
||||||
|
|
||||||
|
#define ASM_CLAC
|
||||||
|
#define ASM_STAC
|
||||||
|
|
||||||
|
#endif /* CONFIG_X86_SMAP */
|
||||||
|
|
||||||
|
#else /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#include <asm/alternative.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_SMAP
|
||||||
|
|
||||||
|
static __always_inline void clac(void)
|
||||||
|
{
|
||||||
|
/* Note: a barrier is implicit in alternative() */
|
||||||
|
alternative("", __stringify(__ASM_CLAC), X86_FEATURE_SMAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline void stac(void)
|
||||||
|
{
|
||||||
|
/* Note: a barrier is implicit in alternative() */
|
||||||
|
alternative("", __stringify(__ASM_STAC), X86_FEATURE_SMAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* These macros can be used in asm() statements */
|
||||||
|
#define ASM_CLAC \
|
||||||
|
ALTERNATIVE("", __stringify(__ASM_CLAC), X86_FEATURE_SMAP)
|
||||||
|
#define ASM_STAC \
|
||||||
|
ALTERNATIVE("", __stringify(__ASM_STAC), X86_FEATURE_SMAP)
|
||||||
|
|
||||||
|
#else /* CONFIG_X86_SMAP */
|
||||||
|
|
||||||
|
static inline void clac(void) { }
|
||||||
|
static inline void stac(void) { }
|
||||||
|
|
||||||
|
#define ASM_CLAC
|
||||||
|
#define ASM_STAC
|
||||||
|
|
||||||
|
#endif /* CONFIG_X86_SMAP */
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_SMAP_H */
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
#include <asm/nops.h>
|
||||||
|
|
||||||
static inline void native_clts(void)
|
static inline void native_clts(void)
|
||||||
{
|
{
|
||||||
asm volatile("clts");
|
asm volatile("clts");
|
||||||
@ -96,6 +98,44 @@ static inline void native_write_cr8(unsigned long val)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
|
||||||
|
static inline u32 __read_pkru(void)
|
||||||
|
{
|
||||||
|
u32 ecx = 0;
|
||||||
|
u32 edx, pkru;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "rdpkru" instruction. Places PKRU contents in to EAX,
|
||||||
|
* clears EDX and requires that ecx=0.
|
||||||
|
*/
|
||||||
|
asm volatile(".byte 0x0f,0x01,0xee\n\t"
|
||||||
|
: "=a" (pkru), "=d" (edx)
|
||||||
|
: "c" (ecx));
|
||||||
|
return pkru;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __write_pkru(u32 pkru)
|
||||||
|
{
|
||||||
|
u32 ecx = 0, edx = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "wrpkru" instruction. Loads contents in EAX to PKRU,
|
||||||
|
* requires that ecx = edx = 0.
|
||||||
|
*/
|
||||||
|
asm volatile(".byte 0x0f,0x01,0xef\n\t"
|
||||||
|
: : "a" (pkru), "c"(ecx), "d"(edx));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline u32 __read_pkru(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __write_pkru(u32 pkru)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void native_wbinvd(void)
|
static inline void native_wbinvd(void)
|
||||||
{
|
{
|
||||||
asm volatile("wbinvd": : :"memory");
|
asm volatile("wbinvd": : :"memory");
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
#ifndef _ASM_X86_SWAB_H
|
|
||||||
#define _ASM_X86_SWAB_H
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
|
|
||||||
static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
|
|
||||||
{
|
|
||||||
#ifdef __i386__
|
|
||||||
# ifdef CONFIG_X86_BSWAP
|
|
||||||
asm("bswap %0" : "=r" (val) : "0" (val));
|
|
||||||
# else
|
|
||||||
asm("xchgb %b0,%h0\n\t" /* swap lower bytes */
|
|
||||||
"rorl $16,%0\n\t" /* swap words */
|
|
||||||
"xchgb %b0,%h0" /* swap higher bytes */
|
|
||||||
: "=q" (val)
|
|
||||||
: "0" (val));
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else /* __i386__ */
|
|
||||||
asm("bswapl %0"
|
|
||||||
: "=r" (val)
|
|
||||||
: "0" (val));
|
|
||||||
#endif
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
#define __arch_swab32 __arch_swab32
|
|
||||||
|
|
||||||
static inline __attribute_const__ __u64 __arch_swab64(__u64 val)
|
|
||||||
{
|
|
||||||
#ifdef __i386__
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
__u32 a;
|
|
||||||
__u32 b;
|
|
||||||
} s;
|
|
||||||
__u64 u;
|
|
||||||
} v;
|
|
||||||
v.u = val;
|
|
||||||
# ifdef CONFIG_X86_BSWAP
|
|
||||||
asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
|
|
||||||
: "=r" (v.s.a), "=r" (v.s.b)
|
|
||||||
: "0" (v.s.a), "1" (v.s.b));
|
|
||||||
# else
|
|
||||||
v.s.a = __arch_swab32(v.s.a);
|
|
||||||
v.s.b = __arch_swab32(v.s.b);
|
|
||||||
asm("xchgl %0,%1"
|
|
||||||
: "=r" (v.s.a), "=r" (v.s.b)
|
|
||||||
: "0" (v.s.a), "1" (v.s.b));
|
|
||||||
# endif
|
|
||||||
return v.u;
|
|
||||||
#else /* __i386__ */
|
|
||||||
asm("bswapq %0"
|
|
||||||
: "=r" (val)
|
|
||||||
: "0" (val));
|
|
||||||
return val;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#define __arch_swab64 __arch_swab64
|
|
||||||
|
|
||||||
#endif /* _ASM_X86_SWAB_H */
|
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef _ASM_X86_TIMEX_H
|
#ifndef _ASM_X86_TIMEX_H
|
||||||
#define _ASM_X86_TIMEX_H
|
#define _ASM_X86_TIMEX_H
|
||||||
|
|
||||||
//#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
//#include <asm/tsc.h>
|
//#include <asm/tsc.h>
|
||||||
|
|
||||||
/* Assume we use the PIT time source for the clock tick */
|
/* Assume we use the PIT time source for the clock tick */
|
||||||
|
@ -119,12 +119,23 @@ static inline void setup_node_to_cpumask_map(void) { }
|
|||||||
|
|
||||||
extern const struct cpumask *cpu_coregroup_mask(int cpu);
|
extern const struct cpumask *cpu_coregroup_mask(int cpu);
|
||||||
|
|
||||||
|
#define topology_logical_package_id(cpu) (cpu_data(cpu).logical_proc_id)
|
||||||
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
|
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
|
||||||
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
|
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
|
||||||
|
|
||||||
#ifdef ENABLE_TOPO_DEFINES
|
#ifdef ENABLE_TOPO_DEFINES
|
||||||
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
|
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
|
||||||
#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
|
#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
|
||||||
|
|
||||||
|
extern unsigned int __max_logical_packages;
|
||||||
|
#define topology_max_packages() (__max_logical_packages)
|
||||||
|
int topology_update_package_map(unsigned int apicid, unsigned int cpu);
|
||||||
|
extern int topology_phys_to_logical_pkg(unsigned int pkg);
|
||||||
|
#else
|
||||||
|
#define topology_max_packages() (1)
|
||||||
|
static inline int
|
||||||
|
topology_update_package_map(unsigned int apicid, unsigned int cpu) { return 0; }
|
||||||
|
static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void arch_fix_phys_package_id(int num, u32 slot)
|
static inline void arch_fix_phys_package_id(int num, u32 slot)
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
#ifndef _ASM_X86_TYPES_H
|
|
||||||
#define _ASM_X86_TYPES_H
|
|
||||||
|
|
||||||
#define dma_addr_t dma_addr_t
|
|
||||||
|
|
||||||
#include <asm-generic/types.h>
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
|
|
||||||
typedef u64 dma64_addr_t;
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
#endif /* __KERNEL__ */
|
|
||||||
|
|
||||||
#endif /* _ASM_X86_TYPES_H */
|
|
808
drivers/include/asm/uaccess.h
Normal file
808
drivers/include/asm/uaccess.h
Normal file
@ -0,0 +1,808 @@
|
|||||||
|
#ifndef _ASM_X86_UACCESS_H
|
||||||
|
#define _ASM_X86_UACCESS_H
|
||||||
|
/*
|
||||||
|
* User space memory access functions
|
||||||
|
*/
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/thread_info.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <asm/asm.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
#include <asm/smap.h>
|
||||||
|
|
||||||
|
#define VERIFY_READ 0
|
||||||
|
#define VERIFY_WRITE 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The fs value determines whether argument validity checking should be
|
||||||
|
* performed or not. If get_fs() == USER_DS, checking is performed, with
|
||||||
|
* get_fs() == KERNEL_DS, checking is bypassed.
|
||||||
|
*
|
||||||
|
* For historical reasons, these macros are grossly misnamed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
|
||||||
|
|
||||||
|
#define KERNEL_DS MAKE_MM_SEG(-1UL)
|
||||||
|
#define USER_DS MAKE_MM_SEG(TASK_SIZE_MAX)
|
||||||
|
|
||||||
|
#define get_ds() (KERNEL_DS)
|
||||||
|
#define get_fs() (current_thread_info()->addr_limit)
|
||||||
|
#define set_fs(x) (current_thread_info()->addr_limit = (x))
|
||||||
|
|
||||||
|
#define segment_eq(a, b) ((a).seg == (b).seg)
|
||||||
|
|
||||||
|
#define user_addr_max() (current_thread_info()->addr_limit.seg)
|
||||||
|
#define __addr_ok(addr) \
|
||||||
|
((unsigned long __force)(addr) < user_addr_max())
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test whether a block of memory is a valid user space address.
|
||||||
|
* Returns 0 if the range is valid, nonzero otherwise.
|
||||||
|
*/
|
||||||
|
static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, unsigned long limit)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we have used "sizeof()" for the size,
|
||||||
|
* we know it won't overflow the limit (but
|
||||||
|
* it might overflow the 'addr', so it's
|
||||||
|
* important to subtract the size from the
|
||||||
|
* limit, not add it to the address).
|
||||||
|
*/
|
||||||
|
if (__builtin_constant_p(size))
|
||||||
|
return unlikely(addr > limit - size);
|
||||||
|
|
||||||
|
/* Arbitrary sizes? Be careful about overflow */
|
||||||
|
addr += size;
|
||||||
|
if (unlikely(addr < size))
|
||||||
|
return true;
|
||||||
|
return unlikely(addr > limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __range_not_ok(addr, size, limit) \
|
||||||
|
({ \
|
||||||
|
__chk_user_ptr(addr); \
|
||||||
|
__chk_range_not_ok((unsigned long __force)(addr), size, limit); \
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* access_ok: - Checks if a user space pointer is valid
|
||||||
|
* @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that
|
||||||
|
* %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
|
||||||
|
* to write to a block, it is always safe to read from it.
|
||||||
|
* @addr: User space pointer to start of block to check
|
||||||
|
* @size: Size of block to check
|
||||||
|
*
|
||||||
|
* Context: User context only. This function may sleep if pagefaults are
|
||||||
|
* enabled.
|
||||||
|
*
|
||||||
|
* Checks if a pointer to a block of memory in user space is valid.
|
||||||
|
*
|
||||||
|
* Returns true (nonzero) if the memory block may be valid, false (zero)
|
||||||
|
* if it is definitely invalid.
|
||||||
|
*
|
||||||
|
* Note that, depending on architecture, this function probably just
|
||||||
|
* checks that the pointer is in the user space range - after calling
|
||||||
|
* this function, memory access functions may still return -EFAULT.
|
||||||
|
*/
|
||||||
|
#define access_ok(type, addr, size) \
|
||||||
|
likely(!__range_not_ok(addr, size, user_addr_max()))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The exception table consists of triples of addresses relative to the
|
||||||
|
* exception table entry itself. The first address is of an instruction
|
||||||
|
* that is allowed to fault, the second is the target at which the program
|
||||||
|
* should continue. The third is a handler function to deal with the fault
|
||||||
|
* caused by the instruction in the first field.
|
||||||
|
*
|
||||||
|
* All the routines below use bits of fixup code that are out of line
|
||||||
|
* with the main instruction path. This means when everything is well,
|
||||||
|
* we don't even have to jump over them. Further, they do not intrude
|
||||||
|
* on our cache or tlb entries.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct exception_table_entry {
|
||||||
|
int insn, fixup, handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ARCH_HAS_RELATIVE_EXTABLE
|
||||||
|
|
||||||
|
#define swap_ex_entry_fixup(a, b, tmp, delta) \
|
||||||
|
do { \
|
||||||
|
(a)->fixup = (b)->fixup + (delta); \
|
||||||
|
(b)->fixup = (tmp).fixup - (delta); \
|
||||||
|
(a)->handler = (b)->handler + (delta); \
|
||||||
|
(b)->handler = (tmp).handler - (delta); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
extern int fixup_exception(struct pt_regs *regs, int trapnr);
|
||||||
|
extern bool ex_has_fault_handler(unsigned long ip);
|
||||||
|
extern int early_fixup_exception(unsigned long *ip);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are the main single-value transfer routines. They automatically
|
||||||
|
* use the right size if we just have the right pointer type.
|
||||||
|
*
|
||||||
|
* This gets kind of ugly. We want to return _two_ values in "get_user()"
|
||||||
|
* and yet we don't want to do any pointers, because that is too much
|
||||||
|
* of a performance impact. Thus we have a few rather ugly macros here,
|
||||||
|
* and hide all the ugliness from the user.
|
||||||
|
*
|
||||||
|
* The "__xxx" versions of the user access functions are versions that
|
||||||
|
* do not verify the address space, that must have been done previously
|
||||||
|
* with a separate "access_ok()" call (this is used when we do multiple
|
||||||
|
* accesses to the same area of user memory).
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int __get_user_1(void);
|
||||||
|
extern int __get_user_2(void);
|
||||||
|
extern int __get_user_4(void);
|
||||||
|
extern int __get_user_8(void);
|
||||||
|
extern int __get_user_bad(void);
|
||||||
|
|
||||||
|
#define __uaccess_begin() stac()
|
||||||
|
#define __uaccess_end() clac()
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
* @x: Variable to store result.
|
||||||
|
* @ptr: Source address, in user space.
|
||||||
|
*
|
||||||
|
* Context: User context only. This function may sleep if pagefaults are
|
||||||
|
* enabled.
|
||||||
|
*
|
||||||
|
* This macro copies a single simple variable from user space to kernel
|
||||||
|
* space. It supports simple types like char and int, but not larger
|
||||||
|
* data types like structures or arrays.
|
||||||
|
*
|
||||||
|
* @ptr must have pointer-to-simple-variable type, and the result of
|
||||||
|
* dereferencing @ptr must be assignable to @x without a cast.
|
||||||
|
*
|
||||||
|
* Returns zero on success, or -EFAULT on error.
|
||||||
|
* On error, the variable @x is set to zero.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Careful: we have to cast the result to the type of the pointer
|
||||||
|
* for sign reasons.
|
||||||
|
*
|
||||||
|
* The use of _ASM_DX 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.
|
||||||
|
*
|
||||||
|
* Clang/LLVM cares about the size of the register, but still wants
|
||||||
|
* the base register for something that ends up being a pair.
|
||||||
|
*/
|
||||||
|
#define get_user(x, ptr) \
|
||||||
|
({ \
|
||||||
|
int __ret_gu; \
|
||||||
|
register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \
|
||||||
|
register void *__sp asm(_ASM_SP); \
|
||||||
|
__chk_user_ptr(ptr); \
|
||||||
|
might_fault(); \
|
||||||
|
asm volatile("call __get_user_%P4" \
|
||||||
|
: "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) \
|
||||||
|
: "0" (ptr), "i" (sizeof(*(ptr)))); \
|
||||||
|
(x) = (__force __typeof__(*(ptr))) __val_gu; \
|
||||||
|
__builtin_expect(__ret_gu, 0); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __put_user_x(size, x, ptr, __ret_pu) \
|
||||||
|
asm volatile("call __put_user_" #size : "=a" (__ret_pu) \
|
||||||
|
: "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
#define __put_user_asm_u64(x, addr, err, errret) \
|
||||||
|
asm volatile("\n" \
|
||||||
|
"1: movl %%eax,0(%2)\n" \
|
||||||
|
"2: movl %%edx,4(%2)\n" \
|
||||||
|
"3:" \
|
||||||
|
".section .fixup,\"ax\"\n" \
|
||||||
|
"4: movl %3,%0\n" \
|
||||||
|
" jmp 3b\n" \
|
||||||
|
".previous\n" \
|
||||||
|
_ASM_EXTABLE(1b, 4b) \
|
||||||
|
_ASM_EXTABLE(2b, 4b) \
|
||||||
|
: "=r" (err) \
|
||||||
|
: "A" (x), "r" (addr), "i" (errret), "0" (err))
|
||||||
|
|
||||||
|
#define __put_user_asm_ex_u64(x, addr) \
|
||||||
|
asm volatile("\n" \
|
||||||
|
"1: movl %%eax,0(%1)\n" \
|
||||||
|
"2: movl %%edx,4(%1)\n" \
|
||||||
|
"3:" \
|
||||||
|
_ASM_EXTABLE_EX(1b, 2b) \
|
||||||
|
_ASM_EXTABLE_EX(2b, 3b) \
|
||||||
|
: : "A" (x), "r" (addr))
|
||||||
|
|
||||||
|
#define __put_user_x8(x, ptr, __ret_pu) \
|
||||||
|
asm volatile("call __put_user_8" : "=a" (__ret_pu) \
|
||||||
|
: "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
|
||||||
|
#else
|
||||||
|
#define __put_user_asm_u64(x, ptr, retval, errret) \
|
||||||
|
__put_user_asm(x, ptr, retval, "q", "", "er", errret)
|
||||||
|
#define __put_user_asm_ex_u64(x, addr) \
|
||||||
|
__put_user_asm_ex(x, addr, "q", "", "er")
|
||||||
|
#define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void __put_user_bad(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Strange magic calling convention: pointer in %ecx,
|
||||||
|
* value in %eax(:%edx), return value in %eax. clobbers %rbx
|
||||||
|
*/
|
||||||
|
extern void __put_user_1(void);
|
||||||
|
extern void __put_user_2(void);
|
||||||
|
extern void __put_user_4(void);
|
||||||
|
extern void __put_user_8(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* put_user: - Write a simple value into user space.
|
||||||
|
* @x: Value to copy to user space.
|
||||||
|
* @ptr: Destination address, in user space.
|
||||||
|
*
|
||||||
|
* Context: User context only. This function may sleep if pagefaults are
|
||||||
|
* enabled.
|
||||||
|
*
|
||||||
|
* This macro copies a single simple value from kernel space to user
|
||||||
|
* space. It supports simple types like char and int, but not larger
|
||||||
|
* data types like structures or arrays.
|
||||||
|
*
|
||||||
|
* @ptr must have pointer-to-simple-variable type, and @x must be assignable
|
||||||
|
* to the result of dereferencing @ptr.
|
||||||
|
*
|
||||||
|
* Returns zero on success, or -EFAULT on error.
|
||||||
|
*/
|
||||||
|
#define put_user(x, ptr) \
|
||||||
|
({ \
|
||||||
|
int __ret_pu; \
|
||||||
|
__typeof__(*(ptr)) __pu_val; \
|
||||||
|
__chk_user_ptr(ptr); \
|
||||||
|
might_fault(); \
|
||||||
|
__pu_val = x; \
|
||||||
|
switch (sizeof(*(ptr))) { \
|
||||||
|
case 1: \
|
||||||
|
__put_user_x(1, __pu_val, ptr, __ret_pu); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
__put_user_x(2, __pu_val, ptr, __ret_pu); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
__put_user_x(4, __pu_val, ptr, __ret_pu); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
__put_user_x8(__pu_val, ptr, __ret_pu); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
__put_user_x(X, __pu_val, ptr, __ret_pu); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
__builtin_expect(__ret_pu, 0); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __put_user_size(x, ptr, size, retval, errret) \
|
||||||
|
do { \
|
||||||
|
retval = 0; \
|
||||||
|
__chk_user_ptr(ptr); \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
__put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
__put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
__put_user_asm(x, ptr, retval, "l", "k", "ir", errret); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
__put_user_asm_u64((__typeof__(*ptr))(x), ptr, retval, \
|
||||||
|
errret); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
__put_user_bad(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This doesn't do __uaccess_begin/end - the exception handling
|
||||||
|
* around it must do that.
|
||||||
|
*/
|
||||||
|
#define __put_user_size_ex(x, ptr, size) \
|
||||||
|
do { \
|
||||||
|
__chk_user_ptr(ptr); \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
__put_user_asm_ex(x, ptr, "b", "b", "iq"); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
__put_user_asm_ex(x, ptr, "w", "w", "ir"); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
__put_user_asm_ex(x, ptr, "l", "k", "ir"); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
__put_user_asm_ex_u64((__typeof__(*ptr))(x), ptr); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
__put_user_bad(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
#define __get_user_asm_u64(x, ptr, retval, errret) (x) = __get_user_bad()
|
||||||
|
#define __get_user_asm_ex_u64(x, ptr) (x) = __get_user_bad()
|
||||||
|
#else
|
||||||
|
#define __get_user_asm_u64(x, ptr, retval, errret) \
|
||||||
|
__get_user_asm(x, ptr, retval, "q", "", "=r", errret)
|
||||||
|
#define __get_user_asm_ex_u64(x, ptr) \
|
||||||
|
__get_user_asm_ex(x, ptr, "q", "", "=r")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __get_user_size(x, ptr, size, retval, errret) \
|
||||||
|
do { \
|
||||||
|
retval = 0; \
|
||||||
|
__chk_user_ptr(ptr); \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
__get_user_asm(x, ptr, retval, "b", "b", "=q", errret); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
__get_user_asm(x, ptr, retval, "w", "w", "=r", errret); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
__get_user_asm(x, ptr, retval, "l", "k", "=r", errret); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
__get_user_asm_u64(x, ptr, retval, errret); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
(x) = __get_user_bad(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
|
||||||
|
asm volatile("\n" \
|
||||||
|
"1: mov"itype" %2,%"rtype"1\n" \
|
||||||
|
"2:\n" \
|
||||||
|
".section .fixup,\"ax\"\n" \
|
||||||
|
"3: mov %3,%0\n" \
|
||||||
|
" xor"itype" %"rtype"1,%"rtype"1\n" \
|
||||||
|
" jmp 2b\n" \
|
||||||
|
".previous\n" \
|
||||||
|
_ASM_EXTABLE(1b, 3b) \
|
||||||
|
: "=r" (err), ltype(x) \
|
||||||
|
: "m" (__m(addr)), "i" (errret), "0" (err))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This doesn't do __uaccess_begin/end - the exception handling
|
||||||
|
* around it must do that.
|
||||||
|
*/
|
||||||
|
#define __get_user_size_ex(x, ptr, size) \
|
||||||
|
do { \
|
||||||
|
__chk_user_ptr(ptr); \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
__get_user_asm_ex(x, ptr, "b", "b", "=q"); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
__get_user_asm_ex(x, ptr, "w", "w", "=r"); \
|
||||||
|
break; \
|
||||||
|
case 4: \
|
||||||
|
__get_user_asm_ex(x, ptr, "l", "k", "=r"); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
__get_user_asm_ex_u64(x, ptr); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
(x) = __get_user_bad(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
|
||||||
|
asm volatile("1: mov"itype" %1,%"rtype"0\n" \
|
||||||
|
"2:\n" \
|
||||||
|
_ASM_EXTABLE_EX(1b, 2b) \
|
||||||
|
: ltype(x) : "m" (__m(addr)))
|
||||||
|
|
||||||
|
#define __put_user_nocheck(x, ptr, size) \
|
||||||
|
({ \
|
||||||
|
int __pu_err; \
|
||||||
|
__uaccess_begin(); \
|
||||||
|
__put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \
|
||||||
|
__uaccess_end(); \
|
||||||
|
__builtin_expect(__pu_err, 0); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __get_user_nocheck(x, ptr, size) \
|
||||||
|
({ \
|
||||||
|
int __gu_err; \
|
||||||
|
unsigned long __gu_val; \
|
||||||
|
__uaccess_begin(); \
|
||||||
|
__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
|
||||||
|
__uaccess_end(); \
|
||||||
|
(x) = (__force __typeof__(*(ptr)))__gu_val; \
|
||||||
|
__builtin_expect(__gu_err, 0); \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* FIXME: this hack is definitely wrong -AK */
|
||||||
|
struct __large_struct { unsigned long buf[100]; };
|
||||||
|
#define __m(x) (*(struct __large_struct __user *)(x))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tell gcc we read from memory instead of writing: this is because
|
||||||
|
* we do not write to any memory gcc knows about, so there are no
|
||||||
|
* aliasing issues.
|
||||||
|
*/
|
||||||
|
#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
|
||||||
|
asm volatile("\n" \
|
||||||
|
"1: mov"itype" %"rtype"1,%2\n" \
|
||||||
|
"2:\n" \
|
||||||
|
".section .fixup,\"ax\"\n" \
|
||||||
|
"3: mov %3,%0\n" \
|
||||||
|
" jmp 2b\n" \
|
||||||
|
".previous\n" \
|
||||||
|
_ASM_EXTABLE(1b, 3b) \
|
||||||
|
: "=r"(err) \
|
||||||
|
: ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
|
||||||
|
|
||||||
|
#define __put_user_asm_ex(x, addr, itype, rtype, ltype) \
|
||||||
|
asm volatile("1: mov"itype" %"rtype"0,%1\n" \
|
||||||
|
"2:\n" \
|
||||||
|
_ASM_EXTABLE_EX(1b, 2b) \
|
||||||
|
: : ltype(x), "m" (__m(addr)))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* uaccess_try and catch
|
||||||
|
*/
|
||||||
|
#define uaccess_try do { \
|
||||||
|
current_thread_info()->uaccess_err = 0; \
|
||||||
|
__uaccess_begin(); \
|
||||||
|
barrier();
|
||||||
|
|
||||||
|
#define uaccess_catch(err) \
|
||||||
|
__uaccess_end(); \
|
||||||
|
(err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __get_user: - Get a simple variable from user space, with less checking.
|
||||||
|
* @x: Variable to store result.
|
||||||
|
* @ptr: Source address, in user space.
|
||||||
|
*
|
||||||
|
* Context: User context only. This function may sleep if pagefaults are
|
||||||
|
* enabled.
|
||||||
|
*
|
||||||
|
* This macro copies a single simple variable from user space to kernel
|
||||||
|
* space. It supports simple types like char and int, but not larger
|
||||||
|
* data types like structures or arrays.
|
||||||
|
*
|
||||||
|
* @ptr must have pointer-to-simple-variable type, and the result of
|
||||||
|
* dereferencing @ptr must be assignable to @x without a cast.
|
||||||
|
*
|
||||||
|
* Caller must check the pointer with access_ok() before calling this
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* Returns zero on success, or -EFAULT on error.
|
||||||
|
* On error, the variable @x is set to zero.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __get_user(x, ptr) \
|
||||||
|
__get_user_nocheck((x), (ptr), sizeof(*(ptr)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __put_user: - Write a simple value into user space, with less checking.
|
||||||
|
* @x: Value to copy to user space.
|
||||||
|
* @ptr: Destination address, in user space.
|
||||||
|
*
|
||||||
|
* Context: User context only. This function may sleep if pagefaults are
|
||||||
|
* enabled.
|
||||||
|
*
|
||||||
|
* This macro copies a single simple value from kernel space to user
|
||||||
|
* space. It supports simple types like char and int, but not larger
|
||||||
|
* data types like structures or arrays.
|
||||||
|
*
|
||||||
|
* @ptr must have pointer-to-simple-variable type, and @x must be assignable
|
||||||
|
* to the result of dereferencing @ptr.
|
||||||
|
*
|
||||||
|
* Caller must check the pointer with access_ok() before calling this
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* Returns zero on success, or -EFAULT on error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __put_user(x, ptr) \
|
||||||
|
__put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
|
||||||
|
|
||||||
|
#define __get_user_unaligned __get_user
|
||||||
|
#define __put_user_unaligned __put_user
|
||||||
|
|
||||||
|
/*
|
||||||
|
* {get|put}_user_try and catch
|
||||||
|
*
|
||||||
|
* get_user_try {
|
||||||
|
* get_user_ex(...);
|
||||||
|
* } get_user_catch(err)
|
||||||
|
*/
|
||||||
|
#define get_user_try uaccess_try
|
||||||
|
#define get_user_catch(err) uaccess_catch(err)
|
||||||
|
|
||||||
|
#define get_user_ex(x, ptr) do { \
|
||||||
|
unsigned long __gue_val; \
|
||||||
|
__get_user_size_ex((__gue_val), (ptr), (sizeof(*(ptr)))); \
|
||||||
|
(x) = (__force __typeof__(*(ptr)))__gue_val; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define put_user_try uaccess_try
|
||||||
|
#define put_user_catch(err) uaccess_catch(err)
|
||||||
|
|
||||||
|
#define put_user_ex(x, ptr) \
|
||||||
|
__put_user_size_ex((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
|
||||||
|
|
||||||
|
extern unsigned long
|
||||||
|
copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
|
||||||
|
extern __must_check long
|
||||||
|
strncpy_from_user(char *dst, const char __user *src, long count);
|
||||||
|
|
||||||
|
extern __must_check long strlen_user(const char __user *str);
|
||||||
|
extern __must_check long strnlen_user(const char __user *str, long n);
|
||||||
|
|
||||||
|
unsigned long __must_check clear_user(void __user *mem, unsigned long len);
|
||||||
|
unsigned long __must_check __clear_user(void __user *mem, unsigned long len);
|
||||||
|
|
||||||
|
extern void __cmpxchg_wrong_size(void)
|
||||||
|
__compiletime_error("Bad argument size for cmpxchg");
|
||||||
|
|
||||||
|
#define __user_atomic_cmpxchg_inatomic(uval, ptr, old, new, size) \
|
||||||
|
({ \
|
||||||
|
int __ret = 0; \
|
||||||
|
__typeof__(ptr) __uval = (uval); \
|
||||||
|
__typeof__(*(ptr)) __old = (old); \
|
||||||
|
__typeof__(*(ptr)) __new = (new); \
|
||||||
|
__uaccess_begin(); \
|
||||||
|
switch (size) { \
|
||||||
|
case 1: \
|
||||||
|
{ \
|
||||||
|
asm volatile("\n" \
|
||||||
|
"1:\t" LOCK_PREFIX "cmpxchgb %4, %2\n" \
|
||||||
|
"2:\n" \
|
||||||
|
"\t.section .fixup, \"ax\"\n" \
|
||||||
|
"3:\tmov %3, %0\n" \
|
||||||
|
"\tjmp 2b\n" \
|
||||||
|
"\t.previous\n" \
|
||||||
|
_ASM_EXTABLE(1b, 3b) \
|
||||||
|
: "+r" (__ret), "=a" (__old), "+m" (*(ptr)) \
|
||||||
|
: "i" (-EFAULT), "q" (__new), "1" (__old) \
|
||||||
|
: "memory" \
|
||||||
|
); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
case 2: \
|
||||||
|
{ \
|
||||||
|
asm volatile("\n" \
|
||||||
|
"1:\t" LOCK_PREFIX "cmpxchgw %4, %2\n" \
|
||||||
|
"2:\n" \
|
||||||
|
"\t.section .fixup, \"ax\"\n" \
|
||||||
|
"3:\tmov %3, %0\n" \
|
||||||
|
"\tjmp 2b\n" \
|
||||||
|
"\t.previous\n" \
|
||||||
|
_ASM_EXTABLE(1b, 3b) \
|
||||||
|
: "+r" (__ret), "=a" (__old), "+m" (*(ptr)) \
|
||||||
|
: "i" (-EFAULT), "r" (__new), "1" (__old) \
|
||||||
|
: "memory" \
|
||||||
|
); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
case 4: \
|
||||||
|
{ \
|
||||||
|
asm volatile("\n" \
|
||||||
|
"1:\t" LOCK_PREFIX "cmpxchgl %4, %2\n" \
|
||||||
|
"2:\n" \
|
||||||
|
"\t.section .fixup, \"ax\"\n" \
|
||||||
|
"3:\tmov %3, %0\n" \
|
||||||
|
"\tjmp 2b\n" \
|
||||||
|
"\t.previous\n" \
|
||||||
|
_ASM_EXTABLE(1b, 3b) \
|
||||||
|
: "+r" (__ret), "=a" (__old), "+m" (*(ptr)) \
|
||||||
|
: "i" (-EFAULT), "r" (__new), "1" (__old) \
|
||||||
|
: "memory" \
|
||||||
|
); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
case 8: \
|
||||||
|
{ \
|
||||||
|
if (!IS_ENABLED(CONFIG_X86_64)) \
|
||||||
|
__cmpxchg_wrong_size(); \
|
||||||
|
\
|
||||||
|
asm volatile("\n" \
|
||||||
|
"1:\t" LOCK_PREFIX "cmpxchgq %4, %2\n" \
|
||||||
|
"2:\n" \
|
||||||
|
"\t.section .fixup, \"ax\"\n" \
|
||||||
|
"3:\tmov %3, %0\n" \
|
||||||
|
"\tjmp 2b\n" \
|
||||||
|
"\t.previous\n" \
|
||||||
|
_ASM_EXTABLE(1b, 3b) \
|
||||||
|
: "+r" (__ret), "=a" (__old), "+m" (*(ptr)) \
|
||||||
|
: "i" (-EFAULT), "r" (__new), "1" (__old) \
|
||||||
|
: "memory" \
|
||||||
|
); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
default: \
|
||||||
|
__cmpxchg_wrong_size(); \
|
||||||
|
} \
|
||||||
|
__uaccess_end(); \
|
||||||
|
*__uval = __old; \
|
||||||
|
__ret; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define user_atomic_cmpxchg_inatomic(uval, ptr, old, new) \
|
||||||
|
({ \
|
||||||
|
access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) ? \
|
||||||
|
__user_atomic_cmpxchg_inatomic((uval), (ptr), \
|
||||||
|
(old), (new), sizeof(*(ptr))) : \
|
||||||
|
-EFAULT; \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* movsl can be slow when source and dest are not both 8-byte aligned
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_X86_INTEL_USERCOPY
|
||||||
|
extern struct movsl_mask {
|
||||||
|
int mask;
|
||||||
|
} ____cacheline_aligned_in_smp movsl_mask;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ARCH_HAS_NOCACHE_UACCESS 1
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
# include <asm/uaccess_32.h>
|
||||||
|
#else
|
||||||
|
# include <asm/uaccess_64.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned long __must_check _copy_from_user(void *to, const void __user *from,
|
||||||
|
unsigned n);
|
||||||
|
unsigned long __must_check _copy_to_user(void __user *to, const void *from,
|
||||||
|
unsigned n);
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
|
||||||
|
# define copy_user_diag __compiletime_error
|
||||||
|
#else
|
||||||
|
# define copy_user_diag __compiletime_warning
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void copy_user_diag("copy_from_user() buffer size is too small")
|
||||||
|
copy_from_user_overflow(void);
|
||||||
|
extern void copy_user_diag("copy_to_user() buffer size is too small")
|
||||||
|
copy_to_user_overflow(void) __asm__("copy_from_user_overflow");
|
||||||
|
|
||||||
|
#undef copy_user_diag
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
|
||||||
|
|
||||||
|
extern void
|
||||||
|
__compiletime_warning("copy_from_user() buffer size is not provably correct")
|
||||||
|
__copy_from_user_overflow(void) __asm__("copy_from_user_overflow");
|
||||||
|
#define __copy_from_user_overflow(size, count) __copy_from_user_overflow()
|
||||||
|
|
||||||
|
extern void
|
||||||
|
__compiletime_warning("copy_to_user() buffer size is not provably correct")
|
||||||
|
__copy_to_user_overflow(void) __asm__("copy_from_user_overflow");
|
||||||
|
#define __copy_to_user_overflow(size, count) __copy_to_user_overflow()
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__copy_from_user_overflow(int size, unsigned long count)
|
||||||
|
{
|
||||||
|
WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __copy_to_user_overflow __copy_from_user_overflow
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline unsigned long __must_check
|
||||||
|
copy_from_user(void *to, const void __user *from, unsigned long n)
|
||||||
|
{
|
||||||
|
int sz = __compiletime_object_size(to);
|
||||||
|
|
||||||
|
might_fault();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* While we would like to have the compiler do the checking for us
|
||||||
|
* even in the non-constant size case, any false positives there are
|
||||||
|
* a problem (especially when DEBUG_STRICT_USER_COPY_CHECKS, but even
|
||||||
|
* without - the [hopefully] dangerous looking nature of the warning
|
||||||
|
* would make people go look at the respecitive call sites over and
|
||||||
|
* over again just to find that there's no problem).
|
||||||
|
*
|
||||||
|
* And there are cases where it's just not realistic for the compiler
|
||||||
|
* to prove the count to be in range. For example when multiple call
|
||||||
|
* sites of a helper function - perhaps in different source files -
|
||||||
|
* all doing proper range checking, yet the helper function not doing
|
||||||
|
* so again.
|
||||||
|
*
|
||||||
|
* Therefore limit the compile time checking to the constant size
|
||||||
|
* case, and do only runtime checking for non-constant sizes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (likely(sz < 0 || sz >= n))
|
||||||
|
n = _copy_from_user(to, from, n);
|
||||||
|
else if(__builtin_constant_p(n))
|
||||||
|
copy_from_user_overflow();
|
||||||
|
else
|
||||||
|
__copy_from_user_overflow(sz, n);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long __must_check
|
||||||
|
copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||||
|
{
|
||||||
|
int sz = __compiletime_object_size(from);
|
||||||
|
|
||||||
|
might_fault();
|
||||||
|
|
||||||
|
/* See the comment in copy_from_user() above. */
|
||||||
|
if (likely(sz < 0 || sz >= n))
|
||||||
|
n = _copy_to_user(to, from, n);
|
||||||
|
else if(__builtin_constant_p(n))
|
||||||
|
copy_to_user_overflow();
|
||||||
|
else
|
||||||
|
__copy_to_user_overflow(sz, n);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef __copy_from_user_overflow
|
||||||
|
#undef __copy_to_user_overflow
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We rely on the nested NMI work to allow atomic faults from the NMI path; the
|
||||||
|
* nested NMI paths are careful to preserve CR2.
|
||||||
|
*
|
||||||
|
* Caller must use pagefault_enable/disable, or run in interrupt context,
|
||||||
|
* and also do a uaccess_ok() check
|
||||||
|
*/
|
||||||
|
#define __copy_from_user_nmi __copy_from_user_inatomic
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The "unsafe" user accesses aren't really "unsafe", but the naming
|
||||||
|
* is a big fat warning: you have to not only do the access_ok()
|
||||||
|
* checking before using them, but you have to surround them with the
|
||||||
|
* user_access_begin/end() pair.
|
||||||
|
*/
|
||||||
|
#define user_access_begin() __uaccess_begin()
|
||||||
|
#define user_access_end() __uaccess_end()
|
||||||
|
|
||||||
|
#define unsafe_put_user(x, ptr) \
|
||||||
|
({ \
|
||||||
|
int __pu_err; \
|
||||||
|
__put_user_size((x), (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \
|
||||||
|
__builtin_expect(__pu_err, 0); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define unsafe_get_user(x, ptr) \
|
||||||
|
({ \
|
||||||
|
int __gu_err; \
|
||||||
|
unsigned long __gu_val; \
|
||||||
|
__get_user_size(__gu_val, (ptr), sizeof(*(ptr)), __gu_err, -EFAULT); \
|
||||||
|
(x) = (__force __typeof__(*(ptr)))__gu_val; \
|
||||||
|
__builtin_expect(__gu_err, 0); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_UACCESS_H */
|
||||||
|
|
208
drivers/include/asm/uaccess_32.h
Normal file
208
drivers/include/asm/uaccess_32.h
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
#ifndef _ASM_X86_UACCESS_32_H
|
||||||
|
#define _ASM_X86_UACCESS_32_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User space memory access functions
|
||||||
|
*/
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/thread_info.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <asm/asm.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
|
unsigned long __must_check __copy_to_user_ll
|
||||||
|
(void __user *to, const void *from, unsigned long n);
|
||||||
|
unsigned long __must_check __copy_from_user_ll
|
||||||
|
(void *to, const void __user *from, unsigned long n);
|
||||||
|
unsigned long __must_check __copy_from_user_ll_nozero
|
||||||
|
(void *to, const void __user *from, unsigned long n);
|
||||||
|
unsigned long __must_check __copy_from_user_ll_nocache
|
||||||
|
(void *to, const void __user *from, unsigned long n);
|
||||||
|
unsigned long __must_check __copy_from_user_ll_nocache_nozero
|
||||||
|
(void *to, const void __user *from, unsigned long n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __copy_to_user_inatomic: - Copy a block of data into user space, with less checking.
|
||||||
|
* @to: Destination address, in user space.
|
||||||
|
* @from: Source address, in kernel space.
|
||||||
|
* @n: Number of bytes to copy.
|
||||||
|
*
|
||||||
|
* Context: User context only.
|
||||||
|
*
|
||||||
|
* Copy data from kernel space to user space. Caller must check
|
||||||
|
* the specified block with access_ok() before calling this function.
|
||||||
|
* The caller should also make sure he pins the user space address
|
||||||
|
* so that we don't result in page fault and sleep.
|
||||||
|
*
|
||||||
|
* Here we special-case 1, 2 and 4-byte copy_*_user invocations. On a fault
|
||||||
|
* we return the initial request size (1, 2 or 4), as copy_*_user should do.
|
||||||
|
* If a store crosses a page boundary and gets a fault, the x86 will not write
|
||||||
|
* anything, so this is accurate.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static __always_inline unsigned long __must_check
|
||||||
|
__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
|
||||||
|
{
|
||||||
|
if (__builtin_constant_p(n)) {
|
||||||
|
switch(n) {
|
||||||
|
case 1:
|
||||||
|
*(u8 __force *)to = *(u8 *)from;
|
||||||
|
return 0;
|
||||||
|
case 2:
|
||||||
|
*(u16 __force *)to = *(u16 *)from;
|
||||||
|
return 0;
|
||||||
|
case 4:
|
||||||
|
*(u32 __force *)to = *(u32 *)from;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
*(u64 __force *)to = *(u64 *)from;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__builtin_memcpy((void __force *)to, from, n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __copy_to_user: - Copy a block of data into user space, with less checking.
|
||||||
|
* @to: Destination address, in user space.
|
||||||
|
* @from: Source address, in kernel space.
|
||||||
|
* @n: Number of bytes to copy.
|
||||||
|
*
|
||||||
|
* Context: User context only. This function may sleep if pagefaults are
|
||||||
|
* enabled.
|
||||||
|
*
|
||||||
|
* Copy data from kernel space to user space. Caller must check
|
||||||
|
* the specified block with access_ok() before calling this function.
|
||||||
|
*
|
||||||
|
* Returns number of bytes that could not be copied.
|
||||||
|
* On success, this will be zero.
|
||||||
|
*/
|
||||||
|
static __always_inline unsigned long __must_check
|
||||||
|
__copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||||
|
{
|
||||||
|
might_fault();
|
||||||
|
return __copy_to_user_inatomic(to, from, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline unsigned long
|
||||||
|
__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
|
||||||
|
{
|
||||||
|
/* Avoid zeroing the tail if the copy fails..
|
||||||
|
* If 'n' is constant and 1, 2, or 4, we do still zero on a failure,
|
||||||
|
* but as the zeroing behaviour is only significant when n is not
|
||||||
|
* constant, that shouldn't be a problem.
|
||||||
|
*/
|
||||||
|
if (__builtin_constant_p(n)) {
|
||||||
|
switch(n) {
|
||||||
|
case 1:
|
||||||
|
*(u8 *)to = *(u8 __force *)from;
|
||||||
|
return 0;
|
||||||
|
case 2:
|
||||||
|
*(u16 *)to = *(u16 __force *)from;
|
||||||
|
return 0;
|
||||||
|
case 4:
|
||||||
|
*(u32 *)to = *(u32 __force *)from;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
*(u64 *)to = *(u64 __force *)from;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__builtin_memcpy(to, (const void __force *)from, n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __copy_from_user: - Copy a block of data from user space, with less checking.
|
||||||
|
* @to: Destination address, in kernel space.
|
||||||
|
* @from: Source address, in user space.
|
||||||
|
* @n: Number of bytes to copy.
|
||||||
|
*
|
||||||
|
* Context: User context only. This function may sleep if pagefaults are
|
||||||
|
* enabled.
|
||||||
|
*
|
||||||
|
* Copy data from user space to kernel space. Caller must check
|
||||||
|
* the specified block with access_ok() before calling this function.
|
||||||
|
*
|
||||||
|
* Returns number of bytes that could not be copied.
|
||||||
|
* On success, this will be zero.
|
||||||
|
*
|
||||||
|
* If some data could not be copied, this function will pad the copied
|
||||||
|
* data to the requested size using zero bytes.
|
||||||
|
*
|
||||||
|
* An alternate version - __copy_from_user_inatomic() - may be called from
|
||||||
|
* atomic context and will fail rather than sleep. In this case the
|
||||||
|
* uncopied bytes will *NOT* be padded with zeros. See fs/filemap.h
|
||||||
|
* for explanation of why this is needed.
|
||||||
|
*/
|
||||||
|
static __always_inline unsigned long
|
||||||
|
__copy_from_user(void *to, const void __user *from, unsigned long n)
|
||||||
|
{
|
||||||
|
might_fault();
|
||||||
|
if (__builtin_constant_p(n)) {
|
||||||
|
switch(n) {
|
||||||
|
case 1:
|
||||||
|
*(u8 *)to = *(u8 __force *)from;
|
||||||
|
return 0;
|
||||||
|
case 2:
|
||||||
|
*(u16 *)to = *(u16 __force *)from;
|
||||||
|
return 0;
|
||||||
|
case 4:
|
||||||
|
*(u32 *)to = *(u32 __force *)from;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
*(u64 *)to = *(u64 __force *)from;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__builtin_memcpy(to, (const void __force *)from, n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline unsigned long __copy_from_user_nocache(void *to,
|
||||||
|
const void __user *from, unsigned long n)
|
||||||
|
{
|
||||||
|
might_fault();
|
||||||
|
if (__builtin_constant_p(n)) {
|
||||||
|
switch(n) {
|
||||||
|
case 1:
|
||||||
|
*(u8 *)to = *(u8 __force *)from;
|
||||||
|
return 0;
|
||||||
|
case 2:
|
||||||
|
*(u16 *)to = *(u16 __force *)from;
|
||||||
|
return 0;
|
||||||
|
case 4:
|
||||||
|
*(u32 *)to = *(u32 __force *)from;
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__builtin_memcpy(to, (const void __force *)from, n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline unsigned long
|
||||||
|
__copy_from_user_inatomic_nocache(void *to, const void __user *from,
|
||||||
|
unsigned long n)
|
||||||
|
{
|
||||||
|
return __copy_from_user_inatomic(to, from, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_UACCESS_32_H */
|
@ -45,8 +45,6 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/kref.h>
|
#include <linux/kref.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
@ -62,6 +60,8 @@
|
|||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
#include <uapi/drm/drm.h>
|
#include <uapi/drm/drm.h>
|
||||||
#include <uapi/drm/drm_mode.h>
|
#include <uapi/drm/drm_mode.h>
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ void drm_err(const char *format, ...);
|
|||||||
* \param arg arguments
|
* \param arg arguments
|
||||||
*/
|
*/
|
||||||
#define DRM_ERROR(fmt, ...) \
|
#define DRM_ERROR(fmt, ...) \
|
||||||
printk("DRM Error" fmt, ##__VA_ARGS__)
|
printk("DRM Error " fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rate limited error output. Like DRM_ERROR() but won't flood the log.
|
* Rate limited error output. Like DRM_ERROR() but won't flood the log.
|
||||||
@ -190,6 +190,8 @@ void drm_err(const char *format, ...);
|
|||||||
drm_err(fmt, ##__VA_ARGS__); \
|
drm_err(fmt, ##__VA_ARGS__); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#if DRM_DEBUG_CODE
|
||||||
|
|
||||||
#define DRM_INFO(fmt, ...) \
|
#define DRM_INFO(fmt, ...) \
|
||||||
printk(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__)
|
printk(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
@ -202,7 +204,6 @@ void drm_err(const char *format, ...);
|
|||||||
* \param fmt printf() like format string.
|
* \param fmt printf() like format string.
|
||||||
* \param arg arguments
|
* \param arg arguments
|
||||||
*/
|
*/
|
||||||
#if DRM_DEBUG_CODE
|
|
||||||
#define DRM_DEBUG(fmt, args...) \
|
#define DRM_DEBUG(fmt, args...) \
|
||||||
do { \
|
do { \
|
||||||
printk(KERN_INFO "[" DRM_NAME "] " fmt, ##args); \
|
printk(KERN_INFO "[" DRM_NAME "] " fmt, ##args); \
|
||||||
@ -230,12 +231,13 @@ void drm_err(const char *format, ...);
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0)
|
#define DRM_INFO(fmt, ...) do { } while (0)
|
||||||
#define DRM_DEBUG_KMS(fmt, args...) do { } while (0)
|
#define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0)
|
||||||
|
#define DRM_DEBUG_KMS(fmt, args...) do { } while (0)
|
||||||
#define DRM_DEBUG_PRIME(fmt, args...) do { } while (0)
|
#define DRM_DEBUG_PRIME(fmt, args...) do { } while (0)
|
||||||
#define DRM_DEBUG(fmt, arg...) do { } while (0)
|
#define DRM_DEBUG(fmt, arg...) do { } while (0)
|
||||||
#define DRM_DEBUG_ATOMIC(fmt, args...) do { } while (0)
|
#define DRM_DEBUG_ATOMIC(fmt, args...) do { } while (0)
|
||||||
#define DRM_DEBUG_VBL(fmt, args...) do { } while (0)
|
#define DRM_DEBUG_VBL(fmt, args...) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
@ -293,6 +295,7 @@ struct drm_ioctl_desc {
|
|||||||
struct drm_pending_event {
|
struct drm_pending_event {
|
||||||
struct drm_event *event;
|
struct drm_event *event;
|
||||||
struct list_head link;
|
struct list_head link;
|
||||||
|
struct list_head pending_link;
|
||||||
struct drm_file *file_priv;
|
struct drm_file *file_priv;
|
||||||
pid_t pid; /* pid of requester, no guarantee it's valid by the time
|
pid_t pid; /* pid of requester, no guarantee it's valid by the time
|
||||||
we deliver the event, for tracing only */
|
we deliver the event, for tracing only */
|
||||||
@ -351,8 +354,11 @@ struct drm_file {
|
|||||||
struct list_head blobs;
|
struct list_head blobs;
|
||||||
|
|
||||||
wait_queue_head_t event_wait;
|
wait_queue_head_t event_wait;
|
||||||
|
struct list_head pending_event_list;
|
||||||
struct list_head event_list;
|
struct list_head event_list;
|
||||||
int event_space;
|
int event_space;
|
||||||
|
|
||||||
|
struct mutex event_read_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -801,15 +807,25 @@ extern long drm_compat_ioctl(struct file *filp,
|
|||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
|
extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
|
||||||
|
|
||||||
/* Device support (drm_fops.h) */
|
/* File Operations (drm_fops.c) */
|
||||||
extern int drm_open(struct inode *inode, struct file *filp);
|
int drm_open(struct inode *inode, struct file *filp);
|
||||||
extern ssize_t drm_read(struct file *filp, char __user *buffer,
|
ssize_t drm_read(struct file *filp, char __user *buffer,
|
||||||
size_t count, loff_t *offset);
|
size_t count, loff_t *offset);
|
||||||
extern int drm_release(struct inode *inode, struct file *filp);
|
int drm_release(struct inode *inode, struct file *filp);
|
||||||
extern int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv);
|
int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv);
|
||||||
|
unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
|
||||||
/* Mapping support (drm_vm.h) */
|
int drm_event_reserve_init_locked(struct drm_device *dev,
|
||||||
extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
|
struct drm_file *file_priv,
|
||||||
|
struct drm_pending_event *p,
|
||||||
|
struct drm_event *e);
|
||||||
|
int drm_event_reserve_init(struct drm_device *dev,
|
||||||
|
struct drm_file *file_priv,
|
||||||
|
struct drm_pending_event *p,
|
||||||
|
struct drm_event *e);
|
||||||
|
void drm_event_cancel_free(struct drm_device *dev,
|
||||||
|
struct drm_pending_event *p);
|
||||||
|
void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e);
|
||||||
|
void drm_send_event(struct drm_device *dev, struct drm_pending_event *e);
|
||||||
|
|
||||||
/* Misc. IOCTL support (drm_ioctl.c) */
|
/* Misc. IOCTL support (drm_ioctl.c) */
|
||||||
int drm_noop(struct drm_device *dev, void *data,
|
int drm_noop(struct drm_device *dev, void *data,
|
||||||
|
@ -146,6 +146,9 @@ __drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
|
|||||||
struct drm_connector_state *state);
|
struct drm_connector_state *state);
|
||||||
void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
|
void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
|
||||||
struct drm_connector_state *state);
|
struct drm_connector_state *state);
|
||||||
|
void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
||||||
|
u16 *red, u16 *green, u16 *blue,
|
||||||
|
uint32_t start, uint32_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC
|
* drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC
|
||||||
|
@ -305,12 +305,20 @@ struct drm_plane_helper_funcs;
|
|||||||
* @mode_changed: crtc_state->mode or crtc_state->enable has been changed
|
* @mode_changed: crtc_state->mode or crtc_state->enable has been changed
|
||||||
* @active_changed: crtc_state->active has been toggled.
|
* @active_changed: crtc_state->active has been toggled.
|
||||||
* @connectors_changed: connectors to this crtc have been updated
|
* @connectors_changed: connectors to this crtc have been updated
|
||||||
|
* @color_mgmt_changed: color management properties have changed (degamma or
|
||||||
|
* gamma LUT or CSC matrix)
|
||||||
* @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
|
* @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
|
||||||
* @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors
|
* @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors
|
||||||
|
* @encoder_mask: bitmask of (1 << drm_encoder_index(encoder)) of attached encoders
|
||||||
* @last_vblank_count: for helpers and drivers to capture the vblank of the
|
* @last_vblank_count: for helpers and drivers to capture the vblank of the
|
||||||
* update to ensure framebuffer cleanup isn't done too early
|
* update to ensure framebuffer cleanup isn't done too early
|
||||||
* @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
|
* @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
|
||||||
* @mode: current mode timings
|
* @mode: current mode timings
|
||||||
|
* @degamma_lut: Lookup table for converting framebuffer pixel data
|
||||||
|
* before apply the conversion matrix
|
||||||
|
* @ctm: Transformation matrix
|
||||||
|
* @gamma_lut: Lookup table for converting pixel data after the
|
||||||
|
* conversion matrix
|
||||||
* @event: optional pointer to a DRM event to signal upon completion of the
|
* @event: optional pointer to a DRM event to signal upon completion of the
|
||||||
* state update
|
* state update
|
||||||
* @state: backpointer to global drm_atomic_state
|
* @state: backpointer to global drm_atomic_state
|
||||||
@ -332,6 +340,7 @@ struct drm_crtc_state {
|
|||||||
bool mode_changed : 1;
|
bool mode_changed : 1;
|
||||||
bool active_changed : 1;
|
bool active_changed : 1;
|
||||||
bool connectors_changed : 1;
|
bool connectors_changed : 1;
|
||||||
|
bool color_mgmt_changed : 1;
|
||||||
|
|
||||||
/* attached planes bitmask:
|
/* attached planes bitmask:
|
||||||
* WARNING: transitional helpers do not maintain plane_mask so
|
* WARNING: transitional helpers do not maintain plane_mask so
|
||||||
@ -341,6 +350,7 @@ struct drm_crtc_state {
|
|||||||
u32 plane_mask;
|
u32 plane_mask;
|
||||||
|
|
||||||
u32 connector_mask;
|
u32 connector_mask;
|
||||||
|
u32 encoder_mask;
|
||||||
|
|
||||||
/* last_vblank_count: for vblank waits before cleanup */
|
/* last_vblank_count: for vblank waits before cleanup */
|
||||||
u32 last_vblank_count;
|
u32 last_vblank_count;
|
||||||
@ -353,6 +363,11 @@ struct drm_crtc_state {
|
|||||||
/* blob property to expose current mode to atomic userspace */
|
/* blob property to expose current mode to atomic userspace */
|
||||||
struct drm_property_blob *mode_blob;
|
struct drm_property_blob *mode_blob;
|
||||||
|
|
||||||
|
/* blob property to expose color management to userspace */
|
||||||
|
struct drm_property_blob *degamma_lut;
|
||||||
|
struct drm_property_blob *ctm;
|
||||||
|
struct drm_property_blob *gamma_lut;
|
||||||
|
|
||||||
struct drm_pending_vblank_event *event;
|
struct drm_pending_vblank_event *event;
|
||||||
|
|
||||||
struct drm_atomic_state *state;
|
struct drm_atomic_state *state;
|
||||||
@ -755,7 +770,7 @@ struct drm_crtc {
|
|||||||
int x, y;
|
int x, y;
|
||||||
const struct drm_crtc_funcs *funcs;
|
const struct drm_crtc_funcs *funcs;
|
||||||
|
|
||||||
/* CRTC gamma size for reporting to userspace */
|
/* Legacy FB CRTC gamma size for reporting to userspace */
|
||||||
uint32_t gamma_size;
|
uint32_t gamma_size;
|
||||||
uint16_t *gamma_store;
|
uint16_t *gamma_store;
|
||||||
|
|
||||||
@ -1582,6 +1597,8 @@ struct drm_bridge_funcs {
|
|||||||
*
|
*
|
||||||
* The bridge can assume that the display pipe (i.e. clocks and timing
|
* The bridge can assume that the display pipe (i.e. clocks and timing
|
||||||
* signals) feeding it is still running when this callback is called.
|
* signals) feeding it is still running when this callback is called.
|
||||||
|
*
|
||||||
|
* The disable callback is optional.
|
||||||
*/
|
*/
|
||||||
void (*disable)(struct drm_bridge *bridge);
|
void (*disable)(struct drm_bridge *bridge);
|
||||||
|
|
||||||
@ -1598,6 +1615,8 @@ struct drm_bridge_funcs {
|
|||||||
* The bridge must assume that the display pipe (i.e. clocks and timing
|
* The bridge must assume that the display pipe (i.e. clocks and timing
|
||||||
* singals) feeding it is no longer running when this callback is
|
* singals) feeding it is no longer running when this callback is
|
||||||
* called.
|
* called.
|
||||||
|
*
|
||||||
|
* The post_disable callback is optional.
|
||||||
*/
|
*/
|
||||||
void (*post_disable)(struct drm_bridge *bridge);
|
void (*post_disable)(struct drm_bridge *bridge);
|
||||||
|
|
||||||
@ -1626,6 +1645,8 @@ struct drm_bridge_funcs {
|
|||||||
* will not yet be running when this callback is called. The bridge must
|
* will not yet be running when this callback is called. The bridge must
|
||||||
* not enable the display link feeding the next bridge in the chain (if
|
* not enable the display link feeding the next bridge in the chain (if
|
||||||
* there is one) when this callback is called.
|
* there is one) when this callback is called.
|
||||||
|
*
|
||||||
|
* The pre_enable callback is optional.
|
||||||
*/
|
*/
|
||||||
void (*pre_enable)(struct drm_bridge *bridge);
|
void (*pre_enable)(struct drm_bridge *bridge);
|
||||||
|
|
||||||
@ -1643,6 +1664,8 @@ struct drm_bridge_funcs {
|
|||||||
* signals) feeding it is running when this callback is called. This
|
* signals) feeding it is running when this callback is called. This
|
||||||
* callback must enable the display link feeding the next bridge in the
|
* callback must enable the display link feeding the next bridge in the
|
||||||
* chain if there is one.
|
* chain if there is one.
|
||||||
|
*
|
||||||
|
* The enable callback is optional.
|
||||||
*/
|
*/
|
||||||
void (*enable)(struct drm_bridge *bridge);
|
void (*enable)(struct drm_bridge *bridge);
|
||||||
};
|
};
|
||||||
@ -1675,6 +1698,7 @@ struct drm_bridge {
|
|||||||
* @dev: parent DRM device
|
* @dev: parent DRM device
|
||||||
* @allow_modeset: allow full modeset
|
* @allow_modeset: allow full modeset
|
||||||
* @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
|
* @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
|
||||||
|
* @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL.
|
||||||
* @planes: pointer to array of plane pointers
|
* @planes: pointer to array of plane pointers
|
||||||
* @plane_states: pointer to array of plane states pointers
|
* @plane_states: pointer to array of plane states pointers
|
||||||
* @crtcs: pointer to array of CRTC pointers
|
* @crtcs: pointer to array of CRTC pointers
|
||||||
@ -1688,6 +1712,7 @@ struct drm_atomic_state {
|
|||||||
struct drm_device *dev;
|
struct drm_device *dev;
|
||||||
bool allow_modeset : 1;
|
bool allow_modeset : 1;
|
||||||
bool legacy_cursor_update : 1;
|
bool legacy_cursor_update : 1;
|
||||||
|
bool legacy_set_config : 1;
|
||||||
struct drm_plane **planes;
|
struct drm_plane **planes;
|
||||||
struct drm_plane_state **plane_states;
|
struct drm_plane_state **plane_states;
|
||||||
struct drm_crtc **crtcs;
|
struct drm_crtc **crtcs;
|
||||||
@ -2024,6 +2049,15 @@ struct drm_mode_config_funcs {
|
|||||||
* @property_blob_list: list of all the blob property objects
|
* @property_blob_list: list of all the blob property objects
|
||||||
* @blob_lock: mutex for blob property allocation and management
|
* @blob_lock: mutex for blob property allocation and management
|
||||||
* @*_property: core property tracking
|
* @*_property: core property tracking
|
||||||
|
* @degamma_lut_property: LUT used to convert the framebuffer's colors to linear
|
||||||
|
* gamma
|
||||||
|
* @degamma_lut_size_property: size of the degamma LUT as supported by the
|
||||||
|
* driver (read-only)
|
||||||
|
* @ctm_property: Matrix used to convert colors after the lookup in the
|
||||||
|
* degamma LUT
|
||||||
|
* @gamma_lut_property: LUT used to convert the colors, after the CSC matrix, to
|
||||||
|
* the gamma space of the connected screen (read-only)
|
||||||
|
* @gamma_lut_size_property: size of the gamma LUT as supported by the driver
|
||||||
* @preferred_depth: preferred RBG pixel depth, used by fb helpers
|
* @preferred_depth: preferred RBG pixel depth, used by fb helpers
|
||||||
* @prefer_shadow: hint to userspace to prefer shadow-fb rendering
|
* @prefer_shadow: hint to userspace to prefer shadow-fb rendering
|
||||||
* @async_page_flip: does this device support async flips on the primary plane?
|
* @async_page_flip: does this device support async flips on the primary plane?
|
||||||
@ -2126,6 +2160,13 @@ struct drm_mode_config {
|
|||||||
struct drm_property *aspect_ratio_property;
|
struct drm_property *aspect_ratio_property;
|
||||||
struct drm_property *dirty_info_property;
|
struct drm_property *dirty_info_property;
|
||||||
|
|
||||||
|
/* Optional color correction properties */
|
||||||
|
struct drm_property *degamma_lut_property;
|
||||||
|
struct drm_property *degamma_lut_size_property;
|
||||||
|
struct drm_property *ctm_property;
|
||||||
|
struct drm_property *gamma_lut_property;
|
||||||
|
struct drm_property *gamma_lut_size_property;
|
||||||
|
|
||||||
/* properties for virtual machine layout */
|
/* properties for virtual machine layout */
|
||||||
struct drm_property *suggested_x_property;
|
struct drm_property *suggested_x_property;
|
||||||
struct drm_property *suggested_y_property;
|
struct drm_property *suggested_y_property;
|
||||||
@ -2155,6 +2196,17 @@ struct drm_mode_config {
|
|||||||
list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \
|
list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \
|
||||||
for_each_if ((plane_mask) & (1 << drm_plane_index(plane)))
|
for_each_if ((plane_mask) & (1 << drm_plane_index(plane)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_for_each_encoder_mask - iterate over encoders specified by bitmask
|
||||||
|
* @encoder: the loop cursor
|
||||||
|
* @dev: the DRM device
|
||||||
|
* @encoder_mask: bitmask of encoder indices
|
||||||
|
*
|
||||||
|
* Iterate over all encoders specified by bitmask.
|
||||||
|
*/
|
||||||
|
#define drm_for_each_encoder_mask(encoder, dev, encoder_mask) \
|
||||||
|
list_for_each_entry((encoder), &(dev)->mode_config.encoder_list, head) \
|
||||||
|
for_each_if ((encoder_mask) & (1 << drm_encoder_index(encoder)))
|
||||||
|
|
||||||
#define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
|
#define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
|
||||||
#define obj_to_connector(x) container_of(x, struct drm_connector, base)
|
#define obj_to_connector(x) container_of(x, struct drm_connector, base)
|
||||||
@ -2172,9 +2224,9 @@ struct drm_prop_enum_list {
|
|||||||
|
|
||||||
extern __printf(6, 7)
|
extern __printf(6, 7)
|
||||||
int drm_crtc_init_with_planes(struct drm_device *dev,
|
int drm_crtc_init_with_planes(struct drm_device *dev,
|
||||||
struct drm_crtc *crtc,
|
struct drm_crtc *crtc,
|
||||||
struct drm_plane *primary,
|
struct drm_plane *primary,
|
||||||
struct drm_plane *cursor,
|
struct drm_plane *cursor,
|
||||||
const struct drm_crtc_funcs *funcs,
|
const struct drm_crtc_funcs *funcs,
|
||||||
const char *name, ...);
|
const char *name, ...);
|
||||||
extern void drm_crtc_cleanup(struct drm_crtc *crtc);
|
extern void drm_crtc_cleanup(struct drm_crtc *crtc);
|
||||||
@ -2228,9 +2280,10 @@ void drm_bridge_enable(struct drm_bridge *bridge);
|
|||||||
|
|
||||||
extern __printf(5, 6)
|
extern __printf(5, 6)
|
||||||
int drm_encoder_init(struct drm_device *dev,
|
int drm_encoder_init(struct drm_device *dev,
|
||||||
struct drm_encoder *encoder,
|
struct drm_encoder *encoder,
|
||||||
const struct drm_encoder_funcs *funcs,
|
const struct drm_encoder_funcs *funcs,
|
||||||
int encoder_type, const char *name, ...);
|
int encoder_type, const char *name, ...);
|
||||||
|
extern unsigned int drm_encoder_index(struct drm_encoder *encoder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_encoder_crtc_ok - can a given crtc drive a given encoder?
|
* drm_encoder_crtc_ok - can a given crtc drive a given encoder?
|
||||||
@ -2247,11 +2300,11 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
|
|||||||
|
|
||||||
extern __printf(8, 9)
|
extern __printf(8, 9)
|
||||||
int drm_universal_plane_init(struct drm_device *dev,
|
int drm_universal_plane_init(struct drm_device *dev,
|
||||||
struct drm_plane *plane,
|
struct drm_plane *plane,
|
||||||
unsigned long possible_crtcs,
|
unsigned long possible_crtcs,
|
||||||
const struct drm_plane_funcs *funcs,
|
const struct drm_plane_funcs *funcs,
|
||||||
const uint32_t *formats,
|
const uint32_t *formats,
|
||||||
unsigned int format_count,
|
unsigned int format_count,
|
||||||
enum drm_plane_type type,
|
enum drm_plane_type type,
|
||||||
const char *name, ...);
|
const char *name, ...);
|
||||||
extern int drm_plane_init(struct drm_device *dev,
|
extern int drm_plane_init(struct drm_device *dev,
|
||||||
@ -2288,6 +2341,8 @@ extern void drm_property_destroy_user_blobs(struct drm_device *dev,
|
|||||||
extern bool drm_probe_ddc(struct i2c_adapter *adapter);
|
extern bool drm_probe_ddc(struct i2c_adapter *adapter);
|
||||||
extern struct edid *drm_get_edid(struct drm_connector *connector,
|
extern struct edid *drm_get_edid(struct drm_connector *connector,
|
||||||
struct i2c_adapter *adapter);
|
struct i2c_adapter *adapter);
|
||||||
|
extern struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
|
||||||
|
struct i2c_adapter *adapter);
|
||||||
extern struct edid *drm_edid_duplicate(const struct edid *edid);
|
extern struct edid *drm_edid_duplicate(const struct edid *edid);
|
||||||
extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
|
extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
|
||||||
extern void drm_mode_config_init(struct drm_device *dev);
|
extern void drm_mode_config_init(struct drm_device *dev);
|
||||||
@ -2488,6 +2543,8 @@ extern int drm_format_num_planes(uint32_t format);
|
|||||||
extern int drm_format_plane_cpp(uint32_t format, int plane);
|
extern int drm_format_plane_cpp(uint32_t format, int plane);
|
||||||
extern int drm_format_horz_chroma_subsampling(uint32_t format);
|
extern int drm_format_horz_chroma_subsampling(uint32_t format);
|
||||||
extern int drm_format_vert_chroma_subsampling(uint32_t format);
|
extern int drm_format_vert_chroma_subsampling(uint32_t format);
|
||||||
|
extern int drm_format_plane_width(int width, uint32_t format, int plane);
|
||||||
|
extern int drm_format_plane_height(int height, uint32_t format, int plane);
|
||||||
extern const char *drm_get_format_name(uint32_t format);
|
extern const char *drm_get_format_name(uint32_t format);
|
||||||
extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
|
extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
|
||||||
unsigned int supported_rotations);
|
unsigned int supported_rotations);
|
||||||
@ -2536,6 +2593,21 @@ static inline struct drm_property *drm_property_find(struct drm_device *dev,
|
|||||||
return mo ? obj_to_property(mo) : NULL;
|
return mo ? obj_to_property(mo) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract a degamma/gamma LUT value provided by user and round it to the
|
||||||
|
* precision supported by the hardware.
|
||||||
|
*/
|
||||||
|
static inline uint32_t drm_color_lut_extract(uint32_t user_input,
|
||||||
|
uint32_t bit_precision)
|
||||||
|
{
|
||||||
|
uint32_t val = user_input + (1 << (16 - bit_precision - 1));
|
||||||
|
uint32_t max = 0xffff >> (16 - bit_precision);
|
||||||
|
|
||||||
|
val >>= 16 - bit_precision;
|
||||||
|
|
||||||
|
return clamp_val(val, 0, max);
|
||||||
|
}
|
||||||
|
|
||||||
/* Plane list iterator for legacy (overlay only) planes. */
|
/* Plane list iterator for legacy (overlay only) planes. */
|
||||||
#define drm_for_each_legacy_plane(plane, dev) \
|
#define drm_for_each_legacy_plane(plane, dev) \
|
||||||
list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \
|
list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \
|
||||||
|
@ -48,6 +48,9 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
|
|||||||
struct drm_display_mode *mode,
|
struct drm_display_mode *mode,
|
||||||
int x, int y,
|
int x, int y,
|
||||||
struct drm_framebuffer *old_fb);
|
struct drm_framebuffer *old_fb);
|
||||||
|
extern void drm_helper_crtc_enable_color_mgmt(struct drm_crtc *crtc,
|
||||||
|
int degamma_lut_size,
|
||||||
|
int gamma_lut_size);
|
||||||
extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
|
extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
|
||||||
extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
|
extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
|
||||||
|
|
||||||
|
62
drivers/include/drm/drm_dp_aux_dev.h
Normal file
62
drivers/include/drm/drm_dp_aux_dev.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2015 Intel Corporation
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Rafael Antognolli <rafael.antognolli@intel.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DRM_DP_AUX_DEV
|
||||||
|
#define DRM_DP_AUX_DEV
|
||||||
|
|
||||||
|
#include <drm/drm_dp_helper.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRM_DP_AUX_CHARDEV
|
||||||
|
|
||||||
|
int drm_dp_aux_dev_init(void);
|
||||||
|
void drm_dp_aux_dev_exit(void);
|
||||||
|
int drm_dp_aux_register_devnode(struct drm_dp_aux *aux);
|
||||||
|
void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline int drm_dp_aux_dev_init(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void drm_dp_aux_dev_exit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
92
drivers/include/drm/drm_dp_dual_mode_helper.h
Normal file
92
drivers/include/drm/drm_dp_dual_mode_helper.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2016 Intel Corporation
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DRM_DP_DUAL_MODE_HELPER_H
|
||||||
|
#define DRM_DP_DUAL_MODE_HELPER_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Optional for type 1 DVI adaptors
|
||||||
|
* Mandatory for type 1 HDMI and type 2 adaptors
|
||||||
|
*/
|
||||||
|
#define DP_DUAL_MODE_HDMI_ID 0x00 /* 00-0f */
|
||||||
|
#define DP_DUAL_MODE_HDMI_ID_LEN 16
|
||||||
|
/*
|
||||||
|
* Optional for type 1 adaptors
|
||||||
|
* Mandatory for type 2 adaptors
|
||||||
|
*/
|
||||||
|
#define DP_DUAL_MODE_ADAPTOR_ID 0x10
|
||||||
|
#define DP_DUAL_MODE_REV_MASK 0x07
|
||||||
|
#define DP_DUAL_MODE_REV_TYPE2 0x00
|
||||||
|
#define DP_DUAL_MODE_TYPE_MASK 0xf0
|
||||||
|
#define DP_DUAL_MODE_TYPE_TYPE2 0xa0
|
||||||
|
#define DP_DUAL_MODE_IEEE_OUI 0x11 /* 11-13*/
|
||||||
|
#define DP_DUAL_IEEE_OUI_LEN 3
|
||||||
|
#define DP_DUAL_DEVICE_ID 0x14 /* 14-19 */
|
||||||
|
#define DP_DUAL_DEVICE_ID_LEN 6
|
||||||
|
#define DP_DUAL_MODE_HARDWARE_REV 0x1a
|
||||||
|
#define DP_DUAL_MODE_FIRMWARE_MAJOR_REV 0x1b
|
||||||
|
#define DP_DUAL_MODE_FIRMWARE_MINOR_REV 0x1c
|
||||||
|
#define DP_DUAL_MODE_MAX_TMDS_CLOCK 0x1d
|
||||||
|
#define DP_DUAL_MODE_I2C_SPEED_CAP 0x1e
|
||||||
|
#define DP_DUAL_MODE_TMDS_OEN 0x20
|
||||||
|
#define DP_DUAL_MODE_TMDS_DISABLE 0x01
|
||||||
|
#define DP_DUAL_MODE_HDMI_PIN_CTRL 0x21
|
||||||
|
#define DP_DUAL_MODE_CEC_ENABLE 0x01
|
||||||
|
#define DP_DUAL_MODE_I2C_SPEED_CTRL 0x22
|
||||||
|
|
||||||
|
struct i2c_adapter;
|
||||||
|
|
||||||
|
ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
|
||||||
|
u8 offset, void *buffer, size_t size);
|
||||||
|
ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
|
||||||
|
u8 offset, const void *buffer, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum drm_dp_dual_mode_type - Type of the DP dual mode adaptor
|
||||||
|
* @DRM_DP_DUAL_MODE_NONE: No DP dual mode adaptor
|
||||||
|
* @DRM_DP_DUAL_MODE_UNKNOWN: Could be either none or type 1 DVI adaptor
|
||||||
|
* @DRM_DP_DUAL_MODE_TYPE1_DVI: Type 1 DVI adaptor
|
||||||
|
* @DRM_DP_DUAL_MODE_TYPE1_HDMI: Type 1 HDMI adaptor
|
||||||
|
* @DRM_DP_DUAL_MODE_TYPE2_DVI: Type 2 DVI adaptor
|
||||||
|
* @DRM_DP_DUAL_MODE_TYPE2_HDMI: Type 2 HDMI adaptor
|
||||||
|
*/
|
||||||
|
enum drm_dp_dual_mode_type {
|
||||||
|
DRM_DP_DUAL_MODE_NONE,
|
||||||
|
DRM_DP_DUAL_MODE_UNKNOWN,
|
||||||
|
DRM_DP_DUAL_MODE_TYPE1_DVI,
|
||||||
|
DRM_DP_DUAL_MODE_TYPE1_HDMI,
|
||||||
|
DRM_DP_DUAL_MODE_TYPE2_DVI,
|
||||||
|
DRM_DP_DUAL_MODE_TYPE2_HDMI,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter);
|
||||||
|
int drm_dp_dual_mode_max_tmds_clock(enum drm_dp_dual_mode_type type,
|
||||||
|
struct i2c_adapter *adapter);
|
||||||
|
int drm_dp_dual_mode_get_tmds_output(enum drm_dp_dual_mode_type type,
|
||||||
|
struct i2c_adapter *adapter, bool *enabled);
|
||||||
|
int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
|
||||||
|
struct i2c_adapter *adapter, bool enable);
|
||||||
|
const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type);
|
||||||
|
|
||||||
|
#endif
|
@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld)
|
|||||||
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
|
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_eld_get_conn_type - Get device type hdmi/dp connected
|
||||||
|
* @eld: pointer to an ELD memory structure
|
||||||
|
*
|
||||||
|
* The caller need to use %DRM_ELD_CONN_TYPE_HDMI or %DRM_ELD_CONN_TYPE_DP to
|
||||||
|
* identify the display type connected.
|
||||||
|
*/
|
||||||
|
static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
|
||||||
|
{
|
||||||
|
return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
struct edid *drm_do_get_edid(struct drm_connector *connector,
|
struct edid *drm_do_get_edid(struct drm_connector *connector,
|
||||||
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
|
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
|
||||||
size_t len),
|
size_t len),
|
||||||
|
@ -162,8 +162,8 @@ struct drm_fb_helper_connector {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* struct drm_fb_helper - main structure to emulate fbdev on top of KMS
|
* struct drm_fb_helper - main structure to emulate fbdev on top of KMS
|
||||||
* @fb: Scanout framebuffer object
|
* @fb: Scanout framebuffer object
|
||||||
* @dev: DRM device
|
* @dev: DRM device
|
||||||
* @crtc_count: number of possible CRTCs
|
* @crtc_count: number of possible CRTCs
|
||||||
* @crtc_info: per-CRTC helper state (mode, x/y offset, etc)
|
* @crtc_info: per-CRTC helper state (mode, x/y offset, etc)
|
||||||
* @connector_count: number of connected connectors
|
* @connector_count: number of connected connectors
|
||||||
@ -219,6 +219,7 @@ struct drm_fb_helper {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||||
|
int drm_fb_helper_modinit(void);
|
||||||
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
|
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
|
||||||
const struct drm_fb_helper_funcs *funcs);
|
const struct drm_fb_helper_funcs *funcs);
|
||||||
int drm_fb_helper_init(struct drm_device *dev,
|
int drm_fb_helper_init(struct drm_device *dev,
|
||||||
@ -283,6 +284,11 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
|
|||||||
int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
|
int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
|
||||||
struct drm_connector *connector);
|
struct drm_connector *connector);
|
||||||
#else
|
#else
|
||||||
|
static inline int drm_fb_helper_modinit(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void drm_fb_helper_prepare(struct drm_device *dev,
|
static inline void drm_fb_helper_prepare(struct drm_device *dev,
|
||||||
struct drm_fb_helper *helper,
|
struct drm_fb_helper *helper,
|
||||||
const struct drm_fb_helper_funcs *funcs)
|
const struct drm_fb_helper_funcs *funcs)
|
||||||
|
@ -96,14 +96,17 @@ struct mipi_dsi_host_ops {
|
|||||||
* struct mipi_dsi_host - DSI host device
|
* struct mipi_dsi_host - DSI host device
|
||||||
* @dev: driver model device node for this DSI host
|
* @dev: driver model device node for this DSI host
|
||||||
* @ops: DSI host operations
|
* @ops: DSI host operations
|
||||||
|
* @list: list management
|
||||||
*/
|
*/
|
||||||
struct mipi_dsi_host {
|
struct mipi_dsi_host {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
const struct mipi_dsi_host_ops *ops;
|
const struct mipi_dsi_host_ops *ops;
|
||||||
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
int mipi_dsi_host_register(struct mipi_dsi_host *host);
|
int mipi_dsi_host_register(struct mipi_dsi_host *host);
|
||||||
void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
|
void mipi_dsi_host_unregister(struct mipi_dsi_host *host);
|
||||||
|
struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
|
||||||
|
|
||||||
/* DSI mode flags */
|
/* DSI mode flags */
|
||||||
|
|
||||||
@ -139,10 +142,28 @@ enum mipi_dsi_pixel_format {
|
|||||||
MIPI_DSI_FMT_RGB565,
|
MIPI_DSI_FMT_RGB565,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DSI_DEV_NAME_SIZE 20
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mipi_dsi_device_info - template for creating a mipi_dsi_device
|
||||||
|
* @type: DSI peripheral chip type
|
||||||
|
* @channel: DSI virtual channel assigned to peripheral
|
||||||
|
* @node: pointer to OF device node or NULL
|
||||||
|
*
|
||||||
|
* This is populated and passed to mipi_dsi_device_new to create a new
|
||||||
|
* DSI device
|
||||||
|
*/
|
||||||
|
struct mipi_dsi_device_info {
|
||||||
|
char type[DSI_DEV_NAME_SIZE];
|
||||||
|
u32 channel;
|
||||||
|
struct device_node *node;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct mipi_dsi_device - DSI peripheral device
|
* struct mipi_dsi_device - DSI peripheral device
|
||||||
* @host: DSI host for this peripheral
|
* @host: DSI host for this peripheral
|
||||||
* @dev: driver model device node for this peripheral
|
* @dev: driver model device node for this peripheral
|
||||||
|
* @name: DSI peripheral chip type
|
||||||
* @channel: virtual channel assigned to the peripheral
|
* @channel: virtual channel assigned to the peripheral
|
||||||
* @format: pixel format for video mode
|
* @format: pixel format for video mode
|
||||||
* @lanes: number of active data lanes
|
* @lanes: number of active data lanes
|
||||||
@ -152,6 +173,7 @@ struct mipi_dsi_device {
|
|||||||
struct mipi_dsi_host *host;
|
struct mipi_dsi_host *host;
|
||||||
struct device dev;
|
struct device dev;
|
||||||
|
|
||||||
|
char name[DSI_DEV_NAME_SIZE];
|
||||||
unsigned int channel;
|
unsigned int channel;
|
||||||
unsigned int lanes;
|
unsigned int lanes;
|
||||||
enum mipi_dsi_pixel_format format;
|
enum mipi_dsi_pixel_format format;
|
||||||
@ -188,6 +210,10 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mipi_dsi_device *
|
||||||
|
mipi_dsi_device_register_full(struct mipi_dsi_host *host,
|
||||||
|
const struct mipi_dsi_device_info *info);
|
||||||
|
void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi);
|
||||||
struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
|
struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
|
||||||
int mipi_dsi_attach(struct mipi_dsi_device *dsi);
|
int mipi_dsi_attach(struct mipi_dsi_device *dsi);
|
||||||
int mipi_dsi_detach(struct mipi_dsi_device *dsi);
|
int mipi_dsi_detach(struct mipi_dsi_device *dsi);
|
||||||
|
@ -439,7 +439,7 @@ struct drm_encoder_helper_funcs {
|
|||||||
* can be modified by this callback and does not need to match mode.
|
* can be modified by this callback and does not need to match mode.
|
||||||
*
|
*
|
||||||
* This function is used by both legacy CRTC helpers and atomic helpers.
|
* This function is used by both legacy CRTC helpers and atomic helpers.
|
||||||
* With atomic helpers it is optional.
|
* This hook is optional.
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
*
|
*
|
||||||
|
@ -139,6 +139,6 @@ struct drm_modeset_acquire_ctx *
|
|||||||
drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc);
|
drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc);
|
||||||
|
|
||||||
int drm_modeset_lock_all_ctx(struct drm_device *dev,
|
int drm_modeset_lock_all_ctx(struct drm_device *dev,
|
||||||
struct drm_modeset_acquire_ctx *ctx);
|
struct drm_modeset_acquire_ctx *ctx);
|
||||||
|
|
||||||
#endif /* DRM_MODESET_LOCK_H_ */
|
#endif /* DRM_MODESET_LOCK_H_ */
|
||||||
|
@ -277,7 +277,9 @@
|
|||||||
INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */
|
INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */
|
||||||
|
|
||||||
#define INTEL_SKL_GT3_IDS(info) \
|
#define INTEL_SKL_GT3_IDS(info) \
|
||||||
|
INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \
|
||||||
INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \
|
INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \
|
||||||
|
INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */ \
|
||||||
INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \
|
INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \
|
||||||
INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */
|
INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */
|
||||||
|
|
||||||
@ -287,7 +289,7 @@
|
|||||||
INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */ \
|
INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */ \
|
||||||
INTEL_VGA_DEVICE(0x193A, info) /* SRV GT4 */
|
INTEL_VGA_DEVICE(0x193A, info) /* SRV GT4 */
|
||||||
|
|
||||||
#define INTEL_SKL_IDS(info) \
|
#define INTEL_SKL_IDS(info) \
|
||||||
INTEL_SKL_GT1_IDS(info), \
|
INTEL_SKL_GT1_IDS(info), \
|
||||||
INTEL_SKL_GT2_IDS(info), \
|
INTEL_SKL_GT2_IDS(info), \
|
||||||
INTEL_SKL_GT3_IDS(info), \
|
INTEL_SKL_GT3_IDS(info), \
|
||||||
@ -296,7 +298,9 @@
|
|||||||
#define INTEL_BXT_IDS(info) \
|
#define INTEL_BXT_IDS(info) \
|
||||||
INTEL_VGA_DEVICE(0x0A84, info), \
|
INTEL_VGA_DEVICE(0x0A84, info), \
|
||||||
INTEL_VGA_DEVICE(0x1A84, info), \
|
INTEL_VGA_DEVICE(0x1A84, info), \
|
||||||
INTEL_VGA_DEVICE(0x5A84, info)
|
INTEL_VGA_DEVICE(0x1A85, info), \
|
||||||
|
INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \
|
||||||
|
INTEL_VGA_DEVICE(0x5A85, info) /* APL HD Graphics 500 */
|
||||||
|
|
||||||
#define INTEL_KBL_GT1_IDS(info) \
|
#define INTEL_KBL_GT1_IDS(info) \
|
||||||
INTEL_VGA_DEVICE(0x5913, info), /* ULT GT1.5 */ \
|
INTEL_VGA_DEVICE(0x5913, info), /* ULT GT1.5 */ \
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2013 Intel Inc.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
||||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _I915_POWERWELL_H_
|
|
||||||
#define _I915_POWERWELL_H_
|
|
||||||
|
|
||||||
/* For use by hda_i915 driver */
|
|
||||||
extern int i915_request_power_well(void);
|
|
||||||
extern int i915_release_power_well(void);
|
|
||||||
extern int i915_get_cdclk_freq(void);
|
|
||||||
|
|
||||||
#endif /* _I915_POWERWELL_H_ */
|
|
@ -316,6 +316,20 @@ ttm_bo_reference(struct ttm_buffer_object *bo)
|
|||||||
*/
|
*/
|
||||||
extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
|
extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
|
||||||
bool interruptible, bool no_wait);
|
bool interruptible, bool no_wait);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ttm_bo_mem_compat - Check if proposed placement is compatible with a bo
|
||||||
|
*
|
||||||
|
* @placement: Return immediately if buffer is busy.
|
||||||
|
* @mem: The struct ttm_mem_reg indicating the region where the bo resides
|
||||||
|
* @new_flags: Describes compatible placement found
|
||||||
|
*
|
||||||
|
* Returns true if the placement is compatible
|
||||||
|
*/
|
||||||
|
extern bool ttm_bo_mem_compat(struct ttm_placement *placement,
|
||||||
|
struct ttm_mem_reg *mem,
|
||||||
|
uint32_t *new_flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ttm_bo_validate
|
* ttm_bo_validate
|
||||||
*
|
*
|
||||||
|
@ -34,20 +34,29 @@
|
|||||||
* The idea here is to build acquire/release variants by adding explicit
|
* The idea here is to build acquire/release variants by adding explicit
|
||||||
* barriers on top of the relaxed variant. In the case where the relaxed
|
* barriers on top of the relaxed variant. In the case where the relaxed
|
||||||
* variant is already fully ordered, no additional barriers are needed.
|
* variant is already fully ordered, no additional barriers are needed.
|
||||||
|
*
|
||||||
|
* Besides, if an arch has a special barrier for acquire/release, it could
|
||||||
|
* implement its own __atomic_op_* and use the same framework for building
|
||||||
|
* variants
|
||||||
*/
|
*/
|
||||||
|
#ifndef __atomic_op_acquire
|
||||||
#define __atomic_op_acquire(op, args...) \
|
#define __atomic_op_acquire(op, args...) \
|
||||||
({ \
|
({ \
|
||||||
typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
|
typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
|
||||||
smp_mb__after_atomic(); \
|
smp_mb__after_atomic(); \
|
||||||
__ret; \
|
__ret; \
|
||||||
})
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __atomic_op_release
|
||||||
#define __atomic_op_release(op, args...) \
|
#define __atomic_op_release(op, args...) \
|
||||||
({ \
|
({ \
|
||||||
smp_mb__before_atomic(); \
|
smp_mb__before_atomic(); \
|
||||||
op##_relaxed(args); \
|
op##_relaxed(args); \
|
||||||
})
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __atomic_op_fence
|
||||||
#define __atomic_op_fence(op, args...) \
|
#define __atomic_op_fence(op, args...) \
|
||||||
({ \
|
({ \
|
||||||
typeof(op##_relaxed(args)) __ret; \
|
typeof(op##_relaxed(args)) __ret; \
|
||||||
@ -56,6 +65,7 @@
|
|||||||
smp_mb__after_atomic(); \
|
smp_mb__after_atomic(); \
|
||||||
__ret; \
|
__ret; \
|
||||||
})
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
/* atomic_add_return_relaxed */
|
/* atomic_add_return_relaxed */
|
||||||
#ifndef atomic_add_return_relaxed
|
#ifndef atomic_add_return_relaxed
|
||||||
@ -548,6 +558,27 @@ static inline int atomic_dec_if_positive(atomic_t *v)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* atomic_fetch_or - perform *p |= mask and return old value of *p
|
||||||
|
* @p: pointer to atomic_t
|
||||||
|
* @mask: mask to OR on the atomic_t
|
||||||
|
*/
|
||||||
|
#ifndef atomic_fetch_or
|
||||||
|
static inline int atomic_fetch_or(atomic_t *p, int mask)
|
||||||
|
{
|
||||||
|
int old, val = atomic_read(p);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
old = atomic_cmpxchg(p, val, val | mask);
|
||||||
|
if (old == val)
|
||||||
|
break;
|
||||||
|
val = old;
|
||||||
|
}
|
||||||
|
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_ATOMIC64
|
#ifdef CONFIG_GENERIC_ATOMIC64
|
||||||
#include <asm-generic/atomic64.h>
|
#include <asm-generic/atomic64.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -59,6 +59,8 @@
|
|||||||
* bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region
|
* bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region
|
||||||
* bitmap_release_region(bitmap, pos, order) Free specified bit region
|
* bitmap_release_region(bitmap, pos, order) Free specified bit region
|
||||||
* bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region
|
* bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region
|
||||||
|
* bitmap_from_u32array(dst, nbits, buf, nwords) *dst = *buf (nwords 32b words)
|
||||||
|
* bitmap_to_u32array(buf, nwords, src, nbits) *buf = *dst (nwords 32b words)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -163,6 +165,14 @@ extern void bitmap_fold(unsigned long *dst, const unsigned long *orig,
|
|||||||
extern int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order);
|
extern int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order);
|
||||||
extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order);
|
extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order);
|
||||||
extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order);
|
extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order);
|
||||||
|
extern unsigned int bitmap_from_u32array(unsigned long *bitmap,
|
||||||
|
unsigned int nbits,
|
||||||
|
const u32 *buf,
|
||||||
|
unsigned int nwords);
|
||||||
|
extern unsigned int bitmap_to_u32array(u32 *buf,
|
||||||
|
unsigned int nwords,
|
||||||
|
const unsigned long *bitmap,
|
||||||
|
unsigned int nbits);
|
||||||
#ifdef __BIG_ENDIAN
|
#ifdef __BIG_ENDIAN
|
||||||
extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits);
|
extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits);
|
||||||
#else
|
#else
|
||||||
|
@ -20,6 +20,7 @@ struct pt_regs;
|
|||||||
#define BUILD_BUG_ON_MSG(cond, msg) (0)
|
#define BUILD_BUG_ON_MSG(cond, msg) (0)
|
||||||
#define BUILD_BUG_ON(condition) (0)
|
#define BUILD_BUG_ON(condition) (0)
|
||||||
#define BUILD_BUG() (0)
|
#define BUILD_BUG() (0)
|
||||||
|
#define MAYBE_BUILD_BUG_ON(cond) (0)
|
||||||
#else /* __CHECKER__ */
|
#else /* __CHECKER__ */
|
||||||
|
|
||||||
/* Force a compilation error if a constant expression is not a power of 2 */
|
/* Force a compilation error if a constant expression is not a power of 2 */
|
||||||
@ -83,6 +84,14 @@ struct pt_regs;
|
|||||||
*/
|
*/
|
||||||
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
|
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
|
||||||
|
|
||||||
|
#define MAYBE_BUILD_BUG_ON(cond) \
|
||||||
|
do { \
|
||||||
|
if (__builtin_constant_p((cond))) \
|
||||||
|
BUILD_BUG_ON(cond); \
|
||||||
|
else \
|
||||||
|
BUG_ON(cond); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif /* __CHECKER__ */
|
#endif /* __CHECKER__ */
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_BUG
|
#ifdef CONFIG_GENERIC_BUG
|
||||||
|
@ -12,10 +12,24 @@
|
|||||||
#define SMP_CACHE_BYTES L1_CACHE_BYTES
|
#define SMP_CACHE_BYTES L1_CACHE_BYTES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __read_mostly is used to keep rarely changing variables out of frequently
|
||||||
|
* updated cachelines. If an architecture doesn't support it, ignore the
|
||||||
|
* hint.
|
||||||
|
*/
|
||||||
#ifndef __read_mostly
|
#ifndef __read_mostly
|
||||||
#define __read_mostly
|
#define __read_mostly
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __ro_after_init is used to mark things that are read-only after init (i.e.
|
||||||
|
* after mark_rodata_ro() has been called). These are effectively read-only,
|
||||||
|
* but may get written to during init, so can't live in .rodata (via "const").
|
||||||
|
*/
|
||||||
|
#ifndef __ro_after_init
|
||||||
|
#define __ro_after_init __attribute__((__section__(".data..ro_after_init")))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ____cacheline_aligned
|
#ifndef ____cacheline_aligned
|
||||||
#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
|
#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
|
||||||
#endif
|
#endif
|
||||||
|
@ -118,6 +118,23 @@ struct clocksource {
|
|||||||
/* simplify initialization of mask field */
|
/* simplify initialization of mask field */
|
||||||
#define CLOCKSOURCE_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
|
#define CLOCKSOURCE_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
|
||||||
|
|
||||||
|
static inline u32 clocksource_freq2mult(u32 freq, u32 shift_constant, u64 from)
|
||||||
|
{
|
||||||
|
/* freq = cyc/from
|
||||||
|
* mult/2^shift = ns/cyc
|
||||||
|
* mult = ns/cyc * 2^shift
|
||||||
|
* mult = from/freq * 2^shift
|
||||||
|
* mult = from * 2^shift / freq
|
||||||
|
* mult = (from<<shift) / freq
|
||||||
|
*/
|
||||||
|
u64 tmp = ((u64)from) << shift_constant;
|
||||||
|
|
||||||
|
tmp += freq/2; /* round for do_div */
|
||||||
|
do_div(tmp, freq);
|
||||||
|
|
||||||
|
return (u32)tmp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clocksource_khz2mult - calculates mult from khz and shift
|
* clocksource_khz2mult - calculates mult from khz and shift
|
||||||
* @khz: Clocksource frequency in KHz
|
* @khz: Clocksource frequency in KHz
|
||||||
@ -128,19 +145,7 @@ struct clocksource {
|
|||||||
*/
|
*/
|
||||||
static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant)
|
static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant)
|
||||||
{
|
{
|
||||||
/* khz = cyc/(Million ns)
|
return clocksource_freq2mult(khz, shift_constant, NSEC_PER_MSEC);
|
||||||
* mult/2^shift = ns/cyc
|
|
||||||
* mult = ns/cyc * 2^shift
|
|
||||||
* mult = 1Million/khz * 2^shift
|
|
||||||
* mult = 1000000 * 2^shift / khz
|
|
||||||
* mult = (1000000<<shift) / khz
|
|
||||||
*/
|
|
||||||
u64 tmp = ((u64)1000000) << shift_constant;
|
|
||||||
|
|
||||||
tmp += khz/2; /* round for do_div */
|
|
||||||
do_div(tmp, khz);
|
|
||||||
|
|
||||||
return (u32)tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,19 +159,7 @@ static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant)
|
|||||||
*/
|
*/
|
||||||
static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
|
static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
|
||||||
{
|
{
|
||||||
/* hz = cyc/(Billion ns)
|
return clocksource_freq2mult(hz, shift_constant, NSEC_PER_SEC);
|
||||||
* mult/2^shift = ns/cyc
|
|
||||||
* mult = ns/cyc * 2^shift
|
|
||||||
* mult = 1Billion/hz * 2^shift
|
|
||||||
* mult = 1000000000 * 2^shift / hz
|
|
||||||
* mult = (1000000000<<shift) / hz
|
|
||||||
*/
|
|
||||||
u64 tmp = ((u64)1000000000) << shift_constant;
|
|
||||||
|
|
||||||
tmp += hz/2; /* round for do_div */
|
|
||||||
do_div(tmp, hz);
|
|
||||||
|
|
||||||
return (u32)tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -246,7 +246,7 @@
|
|||||||
#define __HAVE_BUILTIN_BSWAP32__
|
#define __HAVE_BUILTIN_BSWAP32__
|
||||||
#define __HAVE_BUILTIN_BSWAP64__
|
#define __HAVE_BUILTIN_BSWAP64__
|
||||||
#endif
|
#endif
|
||||||
#if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600)
|
#if GCC_VERSION >= 40800
|
||||||
#define __HAVE_BUILTIN_BSWAP16__
|
#define __HAVE_BUILTIN_BSWAP16__
|
||||||
#endif
|
#endif
|
||||||
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
||||||
|
@ -20,12 +20,14 @@
|
|||||||
# define __pmem __attribute__((noderef, address_space(5)))
|
# define __pmem __attribute__((noderef, address_space(5)))
|
||||||
#ifdef CONFIG_SPARSE_RCU_POINTER
|
#ifdef CONFIG_SPARSE_RCU_POINTER
|
||||||
# define __rcu __attribute__((noderef, address_space(4)))
|
# define __rcu __attribute__((noderef, address_space(4)))
|
||||||
#else
|
#else /* CONFIG_SPARSE_RCU_POINTER */
|
||||||
# define __rcu
|
# define __rcu
|
||||||
#endif
|
#endif /* CONFIG_SPARSE_RCU_POINTER */
|
||||||
|
# define __private __attribute__((noderef))
|
||||||
extern void __chk_user_ptr(const volatile void __user *);
|
extern void __chk_user_ptr(const volatile void __user *);
|
||||||
extern void __chk_io_ptr(const volatile void __iomem *);
|
extern void __chk_io_ptr(const volatile void __iomem *);
|
||||||
#else
|
# define ACCESS_PRIVATE(p, member) (*((typeof((p)->member) __force *) &(p)->member))
|
||||||
|
#else /* __CHECKER__ */
|
||||||
# define __user
|
# define __user
|
||||||
# define __kernel
|
# define __kernel
|
||||||
# define __safe
|
# define __safe
|
||||||
@ -44,7 +46,9 @@ extern void __chk_io_ptr(const volatile void __iomem *);
|
|||||||
# define __percpu
|
# define __percpu
|
||||||
# define __rcu
|
# define __rcu
|
||||||
# define __pmem
|
# define __pmem
|
||||||
#endif
|
# define __private
|
||||||
|
# define ACCESS_PRIVATE(p, member) ((p)->member)
|
||||||
|
#endif /* __CHECKER__ */
|
||||||
|
|
||||||
/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
|
/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
|
||||||
#define ___PASTE(a,b) a##b
|
#define ___PASTE(a,b) a##b
|
||||||
@ -263,8 +267,9 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
|
|||||||
* In contrast to ACCESS_ONCE these two macros will also work on aggregate
|
* In contrast to ACCESS_ONCE these two macros will also work on aggregate
|
||||||
* data types like structs or unions. If the size of the accessed data
|
* data types like structs or unions. If the size of the accessed data
|
||||||
* type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
|
* type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
|
||||||
* READ_ONCE() and WRITE_ONCE() will fall back to memcpy and print a
|
* READ_ONCE() and WRITE_ONCE() will fall back to memcpy(). There's at
|
||||||
* compile-time warning.
|
* least two memcpy()s: one for the __builtin_memcpy() and then one for
|
||||||
|
* the macro doing the copy of variable - '__u' allocated on the stack.
|
||||||
*
|
*
|
||||||
* Their two major use cases are: (1) Mediating communication between
|
* Their two major use cases are: (1) Mediating communication between
|
||||||
* process-level code and irq/NMI handlers, all running on the same CPU,
|
* process-level code and irq/NMI handlers, all running on the same CPU,
|
||||||
|
@ -607,8 +607,6 @@ static inline int cpulist_parse(const char *buf, struct cpumask *dstp)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* cpumask_size - size to allocate for a 'struct cpumask' in bytes
|
* cpumask_size - size to allocate for a 'struct cpumask' in bytes
|
||||||
*
|
|
||||||
* This will eventually be a runtime variable, depending on nr_cpu_ids.
|
|
||||||
*/
|
*/
|
||||||
static inline size_t cpumask_size(void)
|
static inline size_t cpumask_size(void)
|
||||||
{
|
{
|
||||||
|
@ -122,6 +122,9 @@ static inline void dev_set_drvdata(struct device *dev, void *data)
|
|||||||
dev->driver_data = data;
|
dev->driver_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline __printf(2, 3)
|
||||||
|
void dev_notice(const struct device *dev, const char *fmt, ...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
#endif /* _DEVICE_H_ */
|
#endif /* _DEVICE_H_ */
|
||||||
|
@ -18,6 +18,7 @@ enum dma_attr {
|
|||||||
DMA_ATTR_NO_KERNEL_MAPPING,
|
DMA_ATTR_NO_KERNEL_MAPPING,
|
||||||
DMA_ATTR_SKIP_CPU_SYNC,
|
DMA_ATTR_SKIP_CPU_SYNC,
|
||||||
DMA_ATTR_FORCE_CONTIGUOUS,
|
DMA_ATTR_FORCE_CONTIGUOUS,
|
||||||
|
DMA_ATTR_ALLOC_SINGLE_PAGES,
|
||||||
DMA_ATTR_MAX,
|
DMA_ATTR_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ struct dma_buf_attachment;
|
|||||||
* @release: release this buffer; to be called after the last dma_buf_put.
|
* @release: release this buffer; to be called after the last dma_buf_put.
|
||||||
* @begin_cpu_access: [optional] called before cpu access to invalidate cpu
|
* @begin_cpu_access: [optional] called before cpu access to invalidate cpu
|
||||||
* caches and allocate backing storage (if not yet done)
|
* caches and allocate backing storage (if not yet done)
|
||||||
* respectively pin the objet into memory.
|
* respectively pin the object into memory.
|
||||||
* @end_cpu_access: [optional] called after cpu access to flush caches.
|
* @end_cpu_access: [optional] called after cpu access to flush caches.
|
||||||
* @kmap_atomic: maps a page from the buffer into kernel address
|
* @kmap_atomic: maps a page from the buffer into kernel address
|
||||||
* space, users may not block until the subsequent unmap call.
|
* space, users may not block until the subsequent unmap call.
|
||||||
@ -93,10 +93,8 @@ struct dma_buf_ops {
|
|||||||
/* after final dma_buf_put() */
|
/* after final dma_buf_put() */
|
||||||
void (*release)(struct dma_buf *);
|
void (*release)(struct dma_buf *);
|
||||||
|
|
||||||
int (*begin_cpu_access)(struct dma_buf *, size_t, size_t,
|
int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction);
|
||||||
enum dma_data_direction);
|
int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction);
|
||||||
void (*end_cpu_access)(struct dma_buf *, size_t, size_t,
|
|
||||||
enum dma_data_direction);
|
|
||||||
void *(*kmap_atomic)(struct dma_buf *, unsigned long);
|
void *(*kmap_atomic)(struct dma_buf *, unsigned long);
|
||||||
void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *);
|
void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *);
|
||||||
void *(*kmap)(struct dma_buf *, unsigned long);
|
void *(*kmap)(struct dma_buf *, unsigned long);
|
||||||
@ -192,10 +190,6 @@ struct dma_buf_export_info {
|
|||||||
* kernel side. For example, an exporter that needs to keep a dmabuf ptr
|
* kernel side. For example, an exporter that needs to keep a dmabuf ptr
|
||||||
* so that subsequent exports don't create a new dmabuf.
|
* so that subsequent exports don't create a new dmabuf.
|
||||||
*/
|
*/
|
||||||
static inline void get_dma_buf(struct dma_buf *dmabuf)
|
|
||||||
{
|
|
||||||
get_file(dmabuf->file);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
|
struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
|
||||||
struct device *dev);
|
struct device *dev);
|
||||||
@ -212,10 +206,10 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *,
|
|||||||
enum dma_data_direction);
|
enum dma_data_direction);
|
||||||
void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,
|
void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,
|
||||||
enum dma_data_direction);
|
enum dma_data_direction);
|
||||||
int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len,
|
int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
|
||||||
enum dma_data_direction dir);
|
enum dma_data_direction dir);
|
||||||
void dma_buf_end_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len,
|
int dma_buf_end_cpu_access(struct dma_buf *dma_buf,
|
||||||
enum dma_data_direction dir);
|
enum dma_data_direction dir);
|
||||||
void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long);
|
void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long);
|
||||||
void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *);
|
void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *);
|
||||||
void *dma_buf_kmap(struct dma_buf *, unsigned long);
|
void *dma_buf_kmap(struct dma_buf *, unsigned long);
|
||||||
|
@ -296,9 +296,6 @@ struct fb_ops {
|
|||||||
/* Draws cursor */
|
/* Draws cursor */
|
||||||
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
|
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
|
||||||
|
|
||||||
/* Rotates the display */
|
|
||||||
void (*fb_rotate)(struct fb_info *info, int angle);
|
|
||||||
|
|
||||||
/* wait for blit idle, optional */
|
/* wait for blit idle, optional */
|
||||||
int (*fb_sync)(struct fb_info *info);
|
int (*fb_sync)(struct fb_info *info);
|
||||||
|
|
||||||
|
@ -79,6 +79,8 @@ struct fence {
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
ktime_t timestamp;
|
ktime_t timestamp;
|
||||||
int status;
|
int status;
|
||||||
|
struct list_head child_list;
|
||||||
|
struct list_head active_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum fence_flag_bits {
|
enum fence_flag_bits {
|
||||||
@ -292,7 +294,7 @@ static inline bool fence_is_later(struct fence *f1, struct fence *f2)
|
|||||||
if (WARN_ON(f1->context != f2->context))
|
if (WARN_ON(f1->context != f2->context))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return f1->seqno - f2->seqno < INT_MAX;
|
return (int)(f1->seqno - f2->seqno) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,11 @@
|
|||||||
struct file;
|
struct file;
|
||||||
|
|
||||||
extern void fput(struct file *);
|
extern void fput(struct file *);
|
||||||
|
|
||||||
|
struct file_operations;
|
||||||
|
struct vfsmount;
|
||||||
|
struct dentry;
|
||||||
|
struct path;
|
||||||
struct fd {
|
struct fd {
|
||||||
struct file *file;
|
struct file *file;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user