forked from rubenslte/android_kernel_samsung_msm8226
Merge tag 'v3.4.113' into lineage-16.0
This is the 3.4.113 stable release Change-Id: I80791430656359c5447a675cbff4431362d18df0 Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
This commit is contained in:
committed by
Francescodario Cuzzocrea
parent
36738e5d0d
commit
238a0fb5ad
@@ -41,6 +41,7 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
|
||||
lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
|
||||
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
|
||||
|
||||
GCOV_PROFILE_hweight.o := n
|
||||
CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS))
|
||||
obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
|
||||
|
||||
|
||||
+5
-12
@@ -31,7 +31,11 @@
|
||||
static union {
|
||||
raw_spinlock_t lock;
|
||||
char pad[L1_CACHE_BYTES];
|
||||
} atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp;
|
||||
} atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp = {
|
||||
[0 ... (NR_LOCKS - 1)] = {
|
||||
.lock = __RAW_SPIN_LOCK_UNLOCKED(atomic64_lock.lock),
|
||||
},
|
||||
};
|
||||
|
||||
static inline raw_spinlock_t *lock_addr(const atomic64_t *v)
|
||||
{
|
||||
@@ -173,14 +177,3 @@ int atomic64_add_unless(atomic64_t *v, long long a, long long u)
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(atomic64_add_unless);
|
||||
|
||||
static int init_atomic64_lock(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NR_LOCKS; ++i)
|
||||
raw_spin_lock_init(&atomic64_lock[i].lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pure_initcall(init_atomic64_lock);
|
||||
|
||||
+15
-10
@@ -131,7 +131,9 @@ void __bitmap_shift_right(unsigned long *dst,
|
||||
lower = src[off + k];
|
||||
if (left && off + k == lim - 1)
|
||||
lower &= mask;
|
||||
dst[k] = upper << (BITS_PER_LONG - rem) | lower >> rem;
|
||||
dst[k] = lower >> rem;
|
||||
if (rem)
|
||||
dst[k] |= upper << (BITS_PER_LONG - rem);
|
||||
if (left && k == lim - 1)
|
||||
dst[k] &= mask;
|
||||
}
|
||||
@@ -172,7 +174,9 @@ void __bitmap_shift_left(unsigned long *dst,
|
||||
upper = src[k];
|
||||
if (left && k == lim - 1)
|
||||
upper &= (1UL << left) - 1;
|
||||
dst[k + off] = lower >> (BITS_PER_LONG - rem) | upper << rem;
|
||||
dst[k + off] = upper << rem;
|
||||
if (rem)
|
||||
dst[k + off] |= lower >> (BITS_PER_LONG - rem);
|
||||
if (left && k + off == lim - 1)
|
||||
dst[k + off] &= (1UL << left) - 1;
|
||||
}
|
||||
@@ -601,12 +605,12 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||
unsigned a, b;
|
||||
int c, old_c, totaldigits;
|
||||
const char __user __force *ubuf = (const char __user __force *)buf;
|
||||
int exp_digit, in_range;
|
||||
int at_start, in_range;
|
||||
|
||||
totaldigits = c = 0;
|
||||
bitmap_zero(maskp, nmaskbits);
|
||||
do {
|
||||
exp_digit = 1;
|
||||
at_start = 1;
|
||||
in_range = 0;
|
||||
a = b = 0;
|
||||
|
||||
@@ -635,11 +639,10 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||
break;
|
||||
|
||||
if (c == '-') {
|
||||
if (exp_digit || in_range)
|
||||
if (at_start || in_range)
|
||||
return -EINVAL;
|
||||
b = 0;
|
||||
in_range = 1;
|
||||
exp_digit = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -649,16 +652,18 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen,
|
||||
b = b * 10 + (c - '0');
|
||||
if (!in_range)
|
||||
a = b;
|
||||
exp_digit = 0;
|
||||
at_start = 0;
|
||||
totaldigits++;
|
||||
}
|
||||
if (!(a <= b))
|
||||
return -EINVAL;
|
||||
if (b >= nmaskbits)
|
||||
return -ERANGE;
|
||||
while (a <= b) {
|
||||
set_bit(a, maskp);
|
||||
a++;
|
||||
if (!at_start) {
|
||||
while (a <= b) {
|
||||
set_bit(a, maskp);
|
||||
a++;
|
||||
}
|
||||
}
|
||||
} while (buflen && c == ',');
|
||||
return 0;
|
||||
|
||||
+3
-2
@@ -198,6 +198,7 @@ EXPORT_SYMBOL_GPL(btree_init);
|
||||
|
||||
void btree_destroy(struct btree_head *head)
|
||||
{
|
||||
mempool_free(head->node, head->mempool);
|
||||
mempool_destroy(head->mempool);
|
||||
head->mempool = NULL;
|
||||
}
|
||||
@@ -319,8 +320,8 @@ void *btree_get_prev(struct btree_head *head, struct btree_geo *geo,
|
||||
|
||||
if (head->height == 0)
|
||||
return NULL;
|
||||
retry:
|
||||
longcpy(key, __key, geo->keylen);
|
||||
retry:
|
||||
dec_key(geo, key);
|
||||
|
||||
node = head->node;
|
||||
@@ -351,7 +352,7 @@ retry:
|
||||
}
|
||||
miss:
|
||||
if (retry_key) {
|
||||
__key = retry_key;
|
||||
longcpy(key, retry_key, geo->keylen);
|
||||
retry_key = NULL;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
+10
-2
@@ -179,6 +179,15 @@ csum_partial_copy(const void *src, void *dst, int len, __wsum sum)
|
||||
EXPORT_SYMBOL(csum_partial_copy);
|
||||
|
||||
#ifndef csum_tcpudp_nofold
|
||||
static inline u32 from64to32(u64 x)
|
||||
{
|
||||
/* add up 32-bit and 32-bit for 32+c bit */
|
||||
x = (x & 0xffffffff) + (x >> 32);
|
||||
/* add up carry.. */
|
||||
x = (x & 0xffffffff) + (x >> 32);
|
||||
return (u32)x;
|
||||
}
|
||||
|
||||
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
@@ -193,8 +202,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
#else
|
||||
s += (proto + len) << 8;
|
||||
#endif
|
||||
s += (s >> 32);
|
||||
return (__force __wsum)s;
|
||||
return (__force __wsum)from64to32(s);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_tcpudp_nofold);
|
||||
#endif
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#ifdef STATIC
|
||||
#include "lzo/lzo1x_decompress.c"
|
||||
#include "lzo/lzo1x_decompress_safe.c"
|
||||
#else
|
||||
#include <linux/decompress/unlzo.h>
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -421,7 +421,7 @@ void pcim_iounmap_regions(struct pci_dev *pdev, int mask)
|
||||
if (!iomap)
|
||||
return;
|
||||
|
||||
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
for (i = 0; i < PCIM_IOMAP_MAX; i++) {
|
||||
if (!(mask & (1 << i)))
|
||||
continue;
|
||||
|
||||
|
||||
+7
-3
@@ -162,10 +162,14 @@ static int digsig_verify_rsa(struct key *key,
|
||||
memset(out1, 0, head);
|
||||
memcpy(out1 + head, p, l);
|
||||
|
||||
err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len);
|
||||
kfree(p);
|
||||
|
||||
if (!err && len == hlen)
|
||||
err = memcmp(out2, h, hlen);
|
||||
err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
if (len != hlen || memcmp(out2, h, hlen))
|
||||
err = -EINVAL;
|
||||
|
||||
err:
|
||||
mpi_free(in);
|
||||
|
||||
@@ -10,23 +10,27 @@
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/dynamic_queue_limits.h>
|
||||
|
||||
#define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)
|
||||
#define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0)
|
||||
#define AFTER_EQ(A, B) ((int)((A) - (B)) >= 0)
|
||||
|
||||
/* Records completed count and recalculates the queue limit */
|
||||
void dql_completed(struct dql *dql, unsigned int count)
|
||||
{
|
||||
unsigned int inprogress, prev_inprogress, limit;
|
||||
unsigned int ovlimit, all_prev_completed, completed;
|
||||
unsigned int ovlimit, completed, num_queued;
|
||||
bool all_prev_completed;
|
||||
|
||||
num_queued = ACCESS_ONCE(dql->num_queued);
|
||||
|
||||
/* Can't complete more than what's in queue */
|
||||
BUG_ON(count > dql->num_queued - dql->num_completed);
|
||||
BUG_ON(count > num_queued - dql->num_completed);
|
||||
|
||||
completed = dql->num_completed + count;
|
||||
limit = dql->limit;
|
||||
ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit);
|
||||
inprogress = dql->num_queued - completed;
|
||||
ovlimit = POSDIFF(num_queued - dql->num_completed, limit);
|
||||
inprogress = num_queued - completed;
|
||||
prev_inprogress = dql->prev_num_queued - dql->num_completed;
|
||||
all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
|
||||
all_prev_completed = AFTER_EQ(completed, dql->prev_num_queued);
|
||||
|
||||
if ((ovlimit && !inprogress) ||
|
||||
(dql->prev_ovlimit && all_prev_completed)) {
|
||||
@@ -104,7 +108,7 @@ void dql_completed(struct dql *dql, unsigned int count)
|
||||
dql->prev_ovlimit = ovlimit;
|
||||
dql->prev_last_obj_cnt = dql->last_obj_cnt;
|
||||
dql->num_completed = completed;
|
||||
dql->prev_num_queued = dql->num_queued;
|
||||
dql->prev_num_queued = num_queued;
|
||||
}
|
||||
EXPORT_SYMBOL(dql_completed);
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@ unsigned long gcd(unsigned long a, unsigned long b)
|
||||
|
||||
if (a < b)
|
||||
swap(a, b);
|
||||
|
||||
if (!b)
|
||||
return a;
|
||||
while ((r = a % b) != 0) {
|
||||
a = b;
|
||||
b = r;
|
||||
|
||||
@@ -39,6 +39,14 @@
|
||||
static struct kmem_cache *idr_layer_cache;
|
||||
static DEFINE_SPINLOCK(simple_ida_lock);
|
||||
|
||||
/* the maximum ID which can be allocated given idr->layers */
|
||||
static int idr_max(int layers)
|
||||
{
|
||||
int bits = min_t(int, layers * IDR_BITS, MAX_ID_SHIFT);
|
||||
|
||||
return (1 << bits) - 1;
|
||||
}
|
||||
|
||||
static struct idr_layer *get_from_free_list(struct idr *idp)
|
||||
{
|
||||
struct idr_layer *p;
|
||||
@@ -223,7 +231,7 @@ build_up:
|
||||
* Add a new layer to the top of the tree if the requested
|
||||
* id is larger than the currently allocated space.
|
||||
*/
|
||||
while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
|
||||
while (id > idr_max(layers)) {
|
||||
layers++;
|
||||
if (!p->count) {
|
||||
/* special case: if the tree is currently empty,
|
||||
@@ -265,7 +273,7 @@ build_up:
|
||||
|
||||
static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
|
||||
{
|
||||
struct idr_layer *pa[MAX_LEVEL];
|
||||
struct idr_layer *pa[MAX_LEVEL + 1];
|
||||
int id;
|
||||
|
||||
id = idr_get_empty_slot(idp, starting_id, pa);
|
||||
@@ -357,7 +365,7 @@ static void idr_remove_warning(int id)
|
||||
static void sub_remove(struct idr *idp, int shift, int id)
|
||||
{
|
||||
struct idr_layer *p = idp->top;
|
||||
struct idr_layer **pa[MAX_LEVEL];
|
||||
struct idr_layer **pa[MAX_LEVEL + 1];
|
||||
struct idr_layer ***paa = &pa[0];
|
||||
struct idr_layer *to_free;
|
||||
int n;
|
||||
@@ -451,16 +459,16 @@ void idr_remove_all(struct idr *idp)
|
||||
int n, id, max;
|
||||
int bt_mask;
|
||||
struct idr_layer *p;
|
||||
struct idr_layer *pa[MAX_LEVEL];
|
||||
struct idr_layer *pa[MAX_LEVEL + 1];
|
||||
struct idr_layer **paa = &pa[0];
|
||||
|
||||
n = idp->layers * IDR_BITS;
|
||||
p = idp->top;
|
||||
rcu_assign_pointer(idp->top, NULL);
|
||||
max = 1 << n;
|
||||
max = idr_max(idp->layers);
|
||||
|
||||
id = 0;
|
||||
while (id < max) {
|
||||
while (id >= 0 && id <= max) {
|
||||
while (n > IDR_BITS && p) {
|
||||
n -= IDR_BITS;
|
||||
*paa++ = p;
|
||||
@@ -519,7 +527,7 @@ void *idr_find(struct idr *idp, int id)
|
||||
/* Mask off upper bits we don't use for the search. */
|
||||
id &= MAX_ID_MASK;
|
||||
|
||||
if (id >= (1 << n))
|
||||
if (id > idr_max(p->layer + 1))
|
||||
return NULL;
|
||||
BUG_ON(n == 0);
|
||||
|
||||
@@ -555,15 +563,15 @@ int idr_for_each(struct idr *idp,
|
||||
{
|
||||
int n, id, max, error = 0;
|
||||
struct idr_layer *p;
|
||||
struct idr_layer *pa[MAX_LEVEL];
|
||||
struct idr_layer *pa[MAX_LEVEL + 1];
|
||||
struct idr_layer **paa = &pa[0];
|
||||
|
||||
n = idp->layers * IDR_BITS;
|
||||
p = rcu_dereference_raw(idp->top);
|
||||
max = 1 << n;
|
||||
max = idr_max(idp->layers);
|
||||
|
||||
id = 0;
|
||||
while (id < max) {
|
||||
while (id >= 0 && id <= max) {
|
||||
while (n > 0 && p) {
|
||||
n -= IDR_BITS;
|
||||
*paa++ = p;
|
||||
@@ -601,7 +609,7 @@ EXPORT_SYMBOL(idr_for_each);
|
||||
*/
|
||||
void *idr_get_next(struct idr *idp, int *nextidp)
|
||||
{
|
||||
struct idr_layer *p, *pa[MAX_LEVEL];
|
||||
struct idr_layer *p, *pa[MAX_LEVEL + 1];
|
||||
struct idr_layer **paa = &pa[0];
|
||||
int id = *nextidp;
|
||||
int n, max;
|
||||
@@ -611,9 +619,9 @@ void *idr_get_next(struct idr *idp, int *nextidp)
|
||||
if (!p)
|
||||
return NULL;
|
||||
n = (p->layer + 1) * IDR_BITS;
|
||||
max = 1 << n;
|
||||
max = idr_max(p->layer + 1);
|
||||
|
||||
while (id < max) {
|
||||
while (id >= 0 && id <= max) {
|
||||
while (n > 0 && p) {
|
||||
n -= IDR_BITS;
|
||||
*paa++ = p;
|
||||
@@ -787,7 +795,7 @@ EXPORT_SYMBOL(ida_pre_get);
|
||||
*/
|
||||
int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
|
||||
{
|
||||
struct idr_layer *pa[MAX_LEVEL];
|
||||
struct idr_layer *pa[MAX_LEVEL + 1];
|
||||
struct ida_bitmap *bitmap;
|
||||
unsigned long flags;
|
||||
int idr_id = starting_id / IDA_BITMAP_BITS;
|
||||
|
||||
+8
-1
@@ -531,6 +531,13 @@ struct kobject *kobject_get(struct kobject *kobj)
|
||||
return kobj;
|
||||
}
|
||||
|
||||
static struct kobject *kobject_get_unless_zero(struct kobject *kobj)
|
||||
{
|
||||
if (!kref_get_unless_zero(&kobj->kref))
|
||||
kobj = NULL;
|
||||
return kobj;
|
||||
}
|
||||
|
||||
/*
|
||||
* kobject_cleanup - free kobject resources.
|
||||
* @kobj: object to cleanup
|
||||
@@ -753,7 +760,7 @@ struct kobject *kset_find_obj(struct kset *kset, const char *name)
|
||||
|
||||
list_for_each_entry(k, &kset->list, entry) {
|
||||
if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
|
||||
ret = kobject_get(k);
|
||||
ret = kobject_get_unless_zero(k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
lzo_compress-objs := lzo1x_compress.o
|
||||
lzo_decompress-objs := lzo1x_decompress.o
|
||||
lzo_decompress-objs := lzo1x_decompress_safe.o
|
||||
|
||||
obj-$(CONFIG_LZO_COMPRESS) += lzo_compress.o
|
||||
obj-$(CONFIG_LZO_DECOMPRESS) += lzo_decompress.o
|
||||
|
||||
+201
-148
@@ -1,194 +1,243 @@
|
||||
/*
|
||||
* LZO1X Compressor from MiniLZO
|
||||
* LZO1X Compressor from LZO
|
||||
*
|
||||
* Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
* Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
*
|
||||
* The full LZO package can be found at:
|
||||
* http://www.oberhumer.com/opensource/lzo/
|
||||
*
|
||||
* Changed for kernel use by:
|
||||
* Changed for Linux kernel use by:
|
||||
* Nitin Gupta <nitingupta910@gmail.com>
|
||||
* Richard Purdie <rpurdie@openedhand.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/lzo.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/lzo.h>
|
||||
#include "lzodefs.h"
|
||||
|
||||
static noinline size_t
|
||||
_lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
|
||||
unsigned char *out, size_t *out_len, void *wrkmem)
|
||||
lzo1x_1_do_compress(const unsigned char *in, size_t in_len,
|
||||
unsigned char *out, size_t *out_len,
|
||||
size_t ti, void *wrkmem)
|
||||
{
|
||||
const unsigned char *ip;
|
||||
unsigned char *op;
|
||||
const unsigned char * const in_end = in + in_len;
|
||||
const unsigned char * const ip_end = in + in_len - M2_MAX_LEN - 5;
|
||||
const unsigned char ** const dict = wrkmem;
|
||||
const unsigned char *ip = in, *ii = ip;
|
||||
const unsigned char *end, *m, *m_pos;
|
||||
size_t m_off, m_len, dindex;
|
||||
unsigned char *op = out;
|
||||
const unsigned char * const ip_end = in + in_len - 20;
|
||||
const unsigned char *ii;
|
||||
lzo_dict_t * const dict = (lzo_dict_t *) wrkmem;
|
||||
|
||||
ip += 4;
|
||||
op = out;
|
||||
ip = in;
|
||||
ii = ip;
|
||||
ip += ti < 4 ? 4 - ti : 0;
|
||||
|
||||
for (;;) {
|
||||
dindex = ((size_t)(0x21 * DX3(ip, 5, 5, 6)) >> 5) & D_MASK;
|
||||
m_pos = dict[dindex];
|
||||
|
||||
if (m_pos < in)
|
||||
goto literal;
|
||||
|
||||
if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET))
|
||||
goto literal;
|
||||
|
||||
m_off = ip - m_pos;
|
||||
if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
|
||||
goto try_match;
|
||||
|
||||
dindex = (dindex & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f);
|
||||
m_pos = dict[dindex];
|
||||
|
||||
if (m_pos < in)
|
||||
goto literal;
|
||||
|
||||
if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET))
|
||||
goto literal;
|
||||
|
||||
m_off = ip - m_pos;
|
||||
if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
|
||||
goto try_match;
|
||||
|
||||
goto literal;
|
||||
|
||||
try_match:
|
||||
if (get_unaligned((const unsigned short *)m_pos)
|
||||
== get_unaligned((const unsigned short *)ip)) {
|
||||
if (likely(m_pos[2] == ip[2]))
|
||||
goto match;
|
||||
}
|
||||
|
||||
const unsigned char *m_pos;
|
||||
size_t t, m_len, m_off;
|
||||
u32 dv;
|
||||
literal:
|
||||
dict[dindex] = ip;
|
||||
++ip;
|
||||
ip += 1 + ((ip - ii) >> 5);
|
||||
next:
|
||||
if (unlikely(ip >= ip_end))
|
||||
break;
|
||||
continue;
|
||||
|
||||
match:
|
||||
dict[dindex] = ip;
|
||||
if (ip != ii) {
|
||||
size_t t = ip - ii;
|
||||
dv = get_unaligned_le32(ip);
|
||||
t = ((dv * 0x1824429d) >> (32 - D_BITS)) & D_MASK;
|
||||
m_pos = in + dict[t];
|
||||
dict[t] = (lzo_dict_t) (ip - in);
|
||||
if (unlikely(dv != get_unaligned_le32(m_pos)))
|
||||
goto literal;
|
||||
|
||||
ii -= ti;
|
||||
ti = 0;
|
||||
t = ip - ii;
|
||||
if (t != 0) {
|
||||
if (t <= 3) {
|
||||
op[-2] |= t;
|
||||
} else if (t <= 18) {
|
||||
COPY4(op, ii);
|
||||
op += t;
|
||||
} else if (t <= 16) {
|
||||
*op++ = (t - 3);
|
||||
COPY8(op, ii);
|
||||
COPY8(op + 8, ii + 8);
|
||||
op += t;
|
||||
} else {
|
||||
size_t tt = t - 18;
|
||||
|
||||
*op++ = 0;
|
||||
while (tt > 255) {
|
||||
tt -= 255;
|
||||
if (t <= 18) {
|
||||
*op++ = (t - 3);
|
||||
} else {
|
||||
size_t tt = t - 18;
|
||||
*op++ = 0;
|
||||
}
|
||||
*op++ = tt;
|
||||
}
|
||||
do {
|
||||
*op++ = *ii++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
|
||||
ip += 3;
|
||||
if (m_pos[3] != *ip++ || m_pos[4] != *ip++
|
||||
|| m_pos[5] != *ip++ || m_pos[6] != *ip++
|
||||
|| m_pos[7] != *ip++ || m_pos[8] != *ip++) {
|
||||
--ip;
|
||||
m_len = ip - ii;
|
||||
|
||||
if (m_off <= M2_MAX_OFFSET) {
|
||||
m_off -= 1;
|
||||
*op++ = (((m_len - 1) << 5)
|
||||
| ((m_off & 7) << 2));
|
||||
*op++ = (m_off >> 3);
|
||||
} else if (m_off <= M3_MAX_OFFSET) {
|
||||
m_off -= 1;
|
||||
*op++ = (M3_MARKER | (m_len - 2));
|
||||
goto m3_m4_offset;
|
||||
} else {
|
||||
m_off -= 0x4000;
|
||||
|
||||
*op++ = (M4_MARKER | ((m_off & 0x4000) >> 11)
|
||||
| (m_len - 2));
|
||||
goto m3_m4_offset;
|
||||
}
|
||||
} else {
|
||||
end = in_end;
|
||||
m = m_pos + M2_MAX_LEN + 1;
|
||||
|
||||
while (ip < end && *m == *ip) {
|
||||
m++;
|
||||
ip++;
|
||||
}
|
||||
m_len = ip - ii;
|
||||
|
||||
if (m_off <= M3_MAX_OFFSET) {
|
||||
m_off -= 1;
|
||||
if (m_len <= 33) {
|
||||
*op++ = (M3_MARKER | (m_len - 2));
|
||||
} else {
|
||||
m_len -= 33;
|
||||
*op++ = M3_MARKER | 0;
|
||||
goto m3_m4_len;
|
||||
}
|
||||
} else {
|
||||
m_off -= 0x4000;
|
||||
if (m_len <= M4_MAX_LEN) {
|
||||
*op++ = (M4_MARKER
|
||||
| ((m_off & 0x4000) >> 11)
|
||||
| (m_len - 2));
|
||||
} else {
|
||||
m_len -= M4_MAX_LEN;
|
||||
*op++ = (M4_MARKER
|
||||
| ((m_off & 0x4000) >> 11));
|
||||
m3_m4_len:
|
||||
while (m_len > 255) {
|
||||
m_len -= 255;
|
||||
while (unlikely(tt > 255)) {
|
||||
tt -= 255;
|
||||
*op++ = 0;
|
||||
}
|
||||
|
||||
*op++ = (m_len);
|
||||
*op++ = tt;
|
||||
}
|
||||
do {
|
||||
COPY8(op, ii);
|
||||
COPY8(op + 8, ii + 8);
|
||||
op += 16;
|
||||
ii += 16;
|
||||
t -= 16;
|
||||
} while (t >= 16);
|
||||
if (t > 0) do {
|
||||
*op++ = *ii++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
m3_m4_offset:
|
||||
*op++ = ((m_off & 63) << 2);
|
||||
*op++ = (m_off >> 6);
|
||||
}
|
||||
|
||||
ii = ip;
|
||||
if (unlikely(ip >= ip_end))
|
||||
break;
|
||||
}
|
||||
m_len = 4;
|
||||
{
|
||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && defined(LZO_USE_CTZ64)
|
||||
u64 v;
|
||||
v = get_unaligned((const u64 *) (ip + m_len)) ^
|
||||
get_unaligned((const u64 *) (m_pos + m_len));
|
||||
if (unlikely(v == 0)) {
|
||||
do {
|
||||
m_len += 8;
|
||||
v = get_unaligned((const u64 *) (ip + m_len)) ^
|
||||
get_unaligned((const u64 *) (m_pos + m_len));
|
||||
if (unlikely(ip + m_len >= ip_end))
|
||||
goto m_len_done;
|
||||
} while (v == 0);
|
||||
}
|
||||
# if defined(__LITTLE_ENDIAN)
|
||||
m_len += (unsigned) __builtin_ctzll(v) / 8;
|
||||
# elif defined(__BIG_ENDIAN)
|
||||
m_len += (unsigned) __builtin_clzll(v) / 8;
|
||||
# else
|
||||
# error "missing endian definition"
|
||||
# endif
|
||||
#elif defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && defined(LZO_USE_CTZ32)
|
||||
u32 v;
|
||||
v = get_unaligned((const u32 *) (ip + m_len)) ^
|
||||
get_unaligned((const u32 *) (m_pos + m_len));
|
||||
if (unlikely(v == 0)) {
|
||||
do {
|
||||
m_len += 4;
|
||||
v = get_unaligned((const u32 *) (ip + m_len)) ^
|
||||
get_unaligned((const u32 *) (m_pos + m_len));
|
||||
if (v != 0)
|
||||
break;
|
||||
m_len += 4;
|
||||
v = get_unaligned((const u32 *) (ip + m_len)) ^
|
||||
get_unaligned((const u32 *) (m_pos + m_len));
|
||||
if (unlikely(ip + m_len >= ip_end))
|
||||
goto m_len_done;
|
||||
} while (v == 0);
|
||||
}
|
||||
# if defined(__LITTLE_ENDIAN)
|
||||
m_len += (unsigned) __builtin_ctz(v) / 8;
|
||||
# elif defined(__BIG_ENDIAN)
|
||||
m_len += (unsigned) __builtin_clz(v) / 8;
|
||||
# else
|
||||
# error "missing endian definition"
|
||||
# endif
|
||||
#else
|
||||
if (unlikely(ip[m_len] == m_pos[m_len])) {
|
||||
do {
|
||||
m_len += 1;
|
||||
if (ip[m_len] != m_pos[m_len])
|
||||
break;
|
||||
m_len += 1;
|
||||
if (ip[m_len] != m_pos[m_len])
|
||||
break;
|
||||
m_len += 1;
|
||||
if (ip[m_len] != m_pos[m_len])
|
||||
break;
|
||||
m_len += 1;
|
||||
if (ip[m_len] != m_pos[m_len])
|
||||
break;
|
||||
m_len += 1;
|
||||
if (ip[m_len] != m_pos[m_len])
|
||||
break;
|
||||
m_len += 1;
|
||||
if (ip[m_len] != m_pos[m_len])
|
||||
break;
|
||||
m_len += 1;
|
||||
if (ip[m_len] != m_pos[m_len])
|
||||
break;
|
||||
m_len += 1;
|
||||
if (unlikely(ip + m_len >= ip_end))
|
||||
goto m_len_done;
|
||||
} while (ip[m_len] == m_pos[m_len]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
m_len_done:
|
||||
|
||||
m_off = ip - m_pos;
|
||||
ip += m_len;
|
||||
ii = ip;
|
||||
if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) {
|
||||
m_off -= 1;
|
||||
*op++ = (((m_len - 1) << 5) | ((m_off & 7) << 2));
|
||||
*op++ = (m_off >> 3);
|
||||
} else if (m_off <= M3_MAX_OFFSET) {
|
||||
m_off -= 1;
|
||||
if (m_len <= M3_MAX_LEN)
|
||||
*op++ = (M3_MARKER | (m_len - 2));
|
||||
else {
|
||||
m_len -= M3_MAX_LEN;
|
||||
*op++ = M3_MARKER | 0;
|
||||
while (unlikely(m_len > 255)) {
|
||||
m_len -= 255;
|
||||
*op++ = 0;
|
||||
}
|
||||
*op++ = (m_len);
|
||||
}
|
||||
*op++ = (m_off << 2);
|
||||
*op++ = (m_off >> 6);
|
||||
} else {
|
||||
m_off -= 0x4000;
|
||||
if (m_len <= M4_MAX_LEN)
|
||||
*op++ = (M4_MARKER | ((m_off >> 11) & 8)
|
||||
| (m_len - 2));
|
||||
else {
|
||||
m_len -= M4_MAX_LEN;
|
||||
*op++ = (M4_MARKER | ((m_off >> 11) & 8));
|
||||
while (unlikely(m_len > 255)) {
|
||||
m_len -= 255;
|
||||
*op++ = 0;
|
||||
}
|
||||
*op++ = (m_len);
|
||||
}
|
||||
*op++ = (m_off << 2);
|
||||
*op++ = (m_off >> 6);
|
||||
}
|
||||
goto next;
|
||||
}
|
||||
*out_len = op - out;
|
||||
return in_end - ii;
|
||||
return in_end - (ii - ti);
|
||||
}
|
||||
|
||||
int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out,
|
||||
size_t *out_len, void *wrkmem)
|
||||
int lzo1x_1_compress(const unsigned char *in, size_t in_len,
|
||||
unsigned char *out, size_t *out_len,
|
||||
void *wrkmem)
|
||||
{
|
||||
const unsigned char *ii;
|
||||
const unsigned char *ip = in;
|
||||
unsigned char *op = out;
|
||||
size_t t;
|
||||
size_t l = in_len;
|
||||
size_t t = 0;
|
||||
|
||||
if (unlikely(in_len <= M2_MAX_LEN + 5)) {
|
||||
t = in_len;
|
||||
} else {
|
||||
t = _lzo1x_1_do_compress(in, in_len, op, out_len, wrkmem);
|
||||
while (l > 20) {
|
||||
size_t ll = l <= (M4_MAX_OFFSET + 1) ? l : (M4_MAX_OFFSET + 1);
|
||||
uintptr_t ll_end = (uintptr_t) ip + ll;
|
||||
if ((ll_end + ((t + ll) >> 5)) <= ll_end)
|
||||
break;
|
||||
BUILD_BUG_ON(D_SIZE * sizeof(lzo_dict_t) > LZO1X_1_MEM_COMPRESS);
|
||||
memset(wrkmem, 0, D_SIZE * sizeof(lzo_dict_t));
|
||||
t = lzo1x_1_do_compress(ip, ll, op, out_len, t, wrkmem);
|
||||
ip += ll;
|
||||
op += *out_len;
|
||||
l -= ll;
|
||||
}
|
||||
t += l;
|
||||
|
||||
if (t > 0) {
|
||||
ii = in + in_len - t;
|
||||
const unsigned char *ii = in + in_len - t;
|
||||
|
||||
if (op == out && t <= 238) {
|
||||
*op++ = (17 + t);
|
||||
@@ -198,16 +247,21 @@ int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out,
|
||||
*op++ = (t - 3);
|
||||
} else {
|
||||
size_t tt = t - 18;
|
||||
|
||||
*op++ = 0;
|
||||
while (tt > 255) {
|
||||
tt -= 255;
|
||||
*op++ = 0;
|
||||
}
|
||||
|
||||
*op++ = tt;
|
||||
}
|
||||
do {
|
||||
if (t >= 16) do {
|
||||
COPY8(op, ii);
|
||||
COPY8(op + 8, ii + 8);
|
||||
op += 16;
|
||||
ii += 16;
|
||||
t -= 16;
|
||||
} while (t >= 16);
|
||||
if (t > 0) do {
|
||||
*op++ = *ii++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
@@ -223,4 +277,3 @@ EXPORT_SYMBOL_GPL(lzo1x_1_compress);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("LZO1X-1 Compressor");
|
||||
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* LZO1X Decompressor from MiniLZO
|
||||
*
|
||||
* Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
*
|
||||
* The full LZO package can be found at:
|
||||
* http://www.oberhumer.com/opensource/lzo/
|
||||
*
|
||||
* Changed for kernel use by:
|
||||
* Nitin Gupta <nitingupta910@gmail.com>
|
||||
* Richard Purdie <rpurdie@openedhand.com>
|
||||
*/
|
||||
|
||||
#ifndef STATIC
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/lzo.h>
|
||||
#include "lzodefs.h"
|
||||
|
||||
#define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x))
|
||||
#define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x))
|
||||
#define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op)
|
||||
|
||||
#define COPY4(dst, src) \
|
||||
put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
|
||||
|
||||
int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
|
||||
unsigned char *out, size_t *out_len)
|
||||
{
|
||||
const unsigned char * const ip_end = in + in_len;
|
||||
unsigned char * const op_end = out + *out_len;
|
||||
const unsigned char *ip = in, *m_pos;
|
||||
unsigned char *op = out;
|
||||
size_t t;
|
||||
|
||||
*out_len = 0;
|
||||
|
||||
if (*ip > 17) {
|
||||
t = *ip++ - 17;
|
||||
if (t < 4)
|
||||
goto match_next;
|
||||
if (HAVE_OP(t, op_end, op))
|
||||
goto output_overrun;
|
||||
if (HAVE_IP(t + 1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
do {
|
||||
*op++ = *ip++;
|
||||
} while (--t > 0);
|
||||
goto first_literal_run;
|
||||
}
|
||||
|
||||
while ((ip < ip_end)) {
|
||||
t = *ip++;
|
||||
if (t >= 16)
|
||||
goto match;
|
||||
if (t == 0) {
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
while (*ip == 0) {
|
||||
t += 255;
|
||||
ip++;
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
}
|
||||
t += 15 + *ip++;
|
||||
}
|
||||
if (HAVE_OP(t + 3, op_end, op))
|
||||
goto output_overrun;
|
||||
if (HAVE_IP(t + 4, ip_end, ip))
|
||||
goto input_overrun;
|
||||
|
||||
COPY4(op, ip);
|
||||
op += 4;
|
||||
ip += 4;
|
||||
if (--t > 0) {
|
||||
if (t >= 4) {
|
||||
do {
|
||||
COPY4(op, ip);
|
||||
op += 4;
|
||||
ip += 4;
|
||||
t -= 4;
|
||||
} while (t >= 4);
|
||||
if (t > 0) {
|
||||
do {
|
||||
*op++ = *ip++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
*op++ = *ip++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
}
|
||||
|
||||
first_literal_run:
|
||||
t = *ip++;
|
||||
if (t >= 16)
|
||||
goto match;
|
||||
m_pos = op - (1 + M2_MAX_OFFSET);
|
||||
m_pos -= t >> 2;
|
||||
m_pos -= *ip++ << 2;
|
||||
|
||||
if (HAVE_LB(m_pos, out, op))
|
||||
goto lookbehind_overrun;
|
||||
|
||||
if (HAVE_OP(3, op_end, op))
|
||||
goto output_overrun;
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos;
|
||||
|
||||
goto match_done;
|
||||
|
||||
do {
|
||||
match:
|
||||
if (t >= 64) {
|
||||
m_pos = op - 1;
|
||||
m_pos -= (t >> 2) & 7;
|
||||
m_pos -= *ip++ << 3;
|
||||
t = (t >> 5) - 1;
|
||||
if (HAVE_LB(m_pos, out, op))
|
||||
goto lookbehind_overrun;
|
||||
if (HAVE_OP(t + 3 - 1, op_end, op))
|
||||
goto output_overrun;
|
||||
goto copy_match;
|
||||
} else if (t >= 32) {
|
||||
t &= 31;
|
||||
if (t == 0) {
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
while (*ip == 0) {
|
||||
t += 255;
|
||||
ip++;
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
}
|
||||
t += 31 + *ip++;
|
||||
}
|
||||
m_pos = op - 1;
|
||||
m_pos -= get_unaligned_le16(ip) >> 2;
|
||||
ip += 2;
|
||||
} else if (t >= 16) {
|
||||
m_pos = op;
|
||||
m_pos -= (t & 8) << 11;
|
||||
|
||||
t &= 7;
|
||||
if (t == 0) {
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
while (*ip == 0) {
|
||||
t += 255;
|
||||
ip++;
|
||||
if (HAVE_IP(1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
}
|
||||
t += 7 + *ip++;
|
||||
}
|
||||
m_pos -= get_unaligned_le16(ip) >> 2;
|
||||
ip += 2;
|
||||
if (m_pos == op)
|
||||
goto eof_found;
|
||||
m_pos -= 0x4000;
|
||||
} else {
|
||||
m_pos = op - 1;
|
||||
m_pos -= t >> 2;
|
||||
m_pos -= *ip++ << 2;
|
||||
|
||||
if (HAVE_LB(m_pos, out, op))
|
||||
goto lookbehind_overrun;
|
||||
if (HAVE_OP(2, op_end, op))
|
||||
goto output_overrun;
|
||||
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos;
|
||||
goto match_done;
|
||||
}
|
||||
|
||||
if (HAVE_LB(m_pos, out, op))
|
||||
goto lookbehind_overrun;
|
||||
if (HAVE_OP(t + 3 - 1, op_end, op))
|
||||
goto output_overrun;
|
||||
|
||||
if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) {
|
||||
COPY4(op, m_pos);
|
||||
op += 4;
|
||||
m_pos += 4;
|
||||
t -= 4 - (3 - 1);
|
||||
do {
|
||||
COPY4(op, m_pos);
|
||||
op += 4;
|
||||
m_pos += 4;
|
||||
t -= 4;
|
||||
} while (t >= 4);
|
||||
if (t > 0)
|
||||
do {
|
||||
*op++ = *m_pos++;
|
||||
} while (--t > 0);
|
||||
} else {
|
||||
copy_match:
|
||||
*op++ = *m_pos++;
|
||||
*op++ = *m_pos++;
|
||||
do {
|
||||
*op++ = *m_pos++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
match_done:
|
||||
t = ip[-2] & 3;
|
||||
if (t == 0)
|
||||
break;
|
||||
match_next:
|
||||
if (HAVE_OP(t, op_end, op))
|
||||
goto output_overrun;
|
||||
if (HAVE_IP(t + 1, ip_end, ip))
|
||||
goto input_overrun;
|
||||
|
||||
*op++ = *ip++;
|
||||
if (t > 1) {
|
||||
*op++ = *ip++;
|
||||
if (t > 2)
|
||||
*op++ = *ip++;
|
||||
}
|
||||
|
||||
t = *ip++;
|
||||
} while (ip < ip_end);
|
||||
}
|
||||
|
||||
*out_len = op - out;
|
||||
return LZO_E_EOF_NOT_FOUND;
|
||||
|
||||
eof_found:
|
||||
*out_len = op - out;
|
||||
return (ip == ip_end ? LZO_E_OK :
|
||||
(ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
|
||||
input_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_INPUT_OVERRUN;
|
||||
|
||||
output_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_OUTPUT_OVERRUN;
|
||||
|
||||
lookbehind_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_LOOKBEHIND_OVERRUN;
|
||||
}
|
||||
#ifndef STATIC
|
||||
EXPORT_SYMBOL_GPL(lzo1x_decompress_safe);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("LZO1X Decompressor");
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* LZO1X Decompressor from LZO
|
||||
*
|
||||
* Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
*
|
||||
* The full LZO package can be found at:
|
||||
* http://www.oberhumer.com/opensource/lzo/
|
||||
*
|
||||
* Changed for Linux kernel use by:
|
||||
* Nitin Gupta <nitingupta910@gmail.com>
|
||||
* Richard Purdie <rpurdie@openedhand.com>
|
||||
*/
|
||||
|
||||
#ifndef STATIC
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/lzo.h>
|
||||
#include "lzodefs.h"
|
||||
|
||||
#define HAVE_IP(x) ((size_t)(ip_end - ip) >= (size_t)(x))
|
||||
#define HAVE_OP(x) ((size_t)(op_end - op) >= (size_t)(x))
|
||||
#define NEED_IP(x) if (!HAVE_IP(x)) goto input_overrun
|
||||
#define NEED_OP(x) if (!HAVE_OP(x)) goto output_overrun
|
||||
#define TEST_LB(m_pos) if ((m_pos) < out) goto lookbehind_overrun
|
||||
|
||||
/* This MAX_255_COUNT is the maximum number of times we can add 255 to a base
|
||||
* count without overflowing an integer. The multiply will overflow when
|
||||
* multiplying 255 by more than MAXINT/255. The sum will overflow earlier
|
||||
* depending on the base count. Since the base count is taken from a u8
|
||||
* and a few bits, it is safe to assume that it will always be lower than
|
||||
* or equal to 2*255, thus we can always prevent any overflow by accepting
|
||||
* two less 255 steps. See Documentation/lzo.txt for more information.
|
||||
*/
|
||||
#define MAX_255_COUNT ((((size_t)~0) / 255) - 2)
|
||||
|
||||
int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
|
||||
unsigned char *out, size_t *out_len)
|
||||
{
|
||||
unsigned char *op;
|
||||
const unsigned char *ip;
|
||||
size_t t, next;
|
||||
size_t state = 0;
|
||||
const unsigned char *m_pos;
|
||||
const unsigned char * const ip_end = in + in_len;
|
||||
unsigned char * const op_end = out + *out_len;
|
||||
|
||||
op = out;
|
||||
ip = in;
|
||||
|
||||
if (unlikely(in_len < 3))
|
||||
goto input_overrun;
|
||||
if (*ip > 17) {
|
||||
t = *ip++ - 17;
|
||||
if (t < 4) {
|
||||
next = t;
|
||||
goto match_next;
|
||||
}
|
||||
goto copy_literal_run;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
t = *ip++;
|
||||
if (t < 16) {
|
||||
if (likely(state == 0)) {
|
||||
if (unlikely(t == 0)) {
|
||||
size_t offset;
|
||||
const unsigned char *ip_last = ip;
|
||||
|
||||
while (unlikely(*ip == 0)) {
|
||||
ip++;
|
||||
NEED_IP(1);
|
||||
}
|
||||
offset = ip - ip_last;
|
||||
if (unlikely(offset > MAX_255_COUNT))
|
||||
return LZO_E_ERROR;
|
||||
|
||||
offset = (offset << 8) - offset;
|
||||
t += offset + 15 + *ip++;
|
||||
}
|
||||
t += 3;
|
||||
copy_literal_run:
|
||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
|
||||
const unsigned char *ie = ip + t;
|
||||
unsigned char *oe = op + t;
|
||||
do {
|
||||
COPY8(op, ip);
|
||||
op += 8;
|
||||
ip += 8;
|
||||
COPY8(op, ip);
|
||||
op += 8;
|
||||
ip += 8;
|
||||
} while (ip < ie);
|
||||
ip = ie;
|
||||
op = oe;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
NEED_OP(t);
|
||||
NEED_IP(t + 3);
|
||||
do {
|
||||
*op++ = *ip++;
|
||||
} while (--t > 0);
|
||||
}
|
||||
state = 4;
|
||||
continue;
|
||||
} else if (state != 4) {
|
||||
next = t & 3;
|
||||
m_pos = op - 1;
|
||||
m_pos -= t >> 2;
|
||||
m_pos -= *ip++ << 2;
|
||||
TEST_LB(m_pos);
|
||||
NEED_OP(2);
|
||||
op[0] = m_pos[0];
|
||||
op[1] = m_pos[1];
|
||||
op += 2;
|
||||
goto match_next;
|
||||
} else {
|
||||
next = t & 3;
|
||||
m_pos = op - (1 + M2_MAX_OFFSET);
|
||||
m_pos -= t >> 2;
|
||||
m_pos -= *ip++ << 2;
|
||||
t = 3;
|
||||
}
|
||||
} else if (t >= 64) {
|
||||
next = t & 3;
|
||||
m_pos = op - 1;
|
||||
m_pos -= (t >> 2) & 7;
|
||||
m_pos -= *ip++ << 3;
|
||||
t = (t >> 5) - 1 + (3 - 1);
|
||||
} else if (t >= 32) {
|
||||
t = (t & 31) + (3 - 1);
|
||||
if (unlikely(t == 2)) {
|
||||
size_t offset;
|
||||
const unsigned char *ip_last = ip;
|
||||
|
||||
while (unlikely(*ip == 0)) {
|
||||
ip++;
|
||||
NEED_IP(1);
|
||||
}
|
||||
offset = ip - ip_last;
|
||||
if (unlikely(offset > MAX_255_COUNT))
|
||||
return LZO_E_ERROR;
|
||||
|
||||
offset = (offset << 8) - offset;
|
||||
t += offset + 31 + *ip++;
|
||||
NEED_IP(2);
|
||||
}
|
||||
m_pos = op - 1;
|
||||
next = get_unaligned_le16(ip);
|
||||
ip += 2;
|
||||
m_pos -= next >> 2;
|
||||
next &= 3;
|
||||
} else {
|
||||
m_pos = op;
|
||||
m_pos -= (t & 8) << 11;
|
||||
t = (t & 7) + (3 - 1);
|
||||
if (unlikely(t == 2)) {
|
||||
size_t offset;
|
||||
const unsigned char *ip_last = ip;
|
||||
|
||||
while (unlikely(*ip == 0)) {
|
||||
ip++;
|
||||
NEED_IP(1);
|
||||
}
|
||||
offset = ip - ip_last;
|
||||
if (unlikely(offset > MAX_255_COUNT))
|
||||
return LZO_E_ERROR;
|
||||
|
||||
offset = (offset << 8) - offset;
|
||||
t += offset + 7 + *ip++;
|
||||
NEED_IP(2);
|
||||
}
|
||||
next = get_unaligned_le16(ip);
|
||||
ip += 2;
|
||||
m_pos -= next >> 2;
|
||||
next &= 3;
|
||||
if (m_pos == op)
|
||||
goto eof_found;
|
||||
m_pos -= 0x4000;
|
||||
}
|
||||
TEST_LB(m_pos);
|
||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
if (op - m_pos >= 8) {
|
||||
unsigned char *oe = op + t;
|
||||
if (likely(HAVE_OP(t + 15))) {
|
||||
do {
|
||||
COPY8(op, m_pos);
|
||||
op += 8;
|
||||
m_pos += 8;
|
||||
COPY8(op, m_pos);
|
||||
op += 8;
|
||||
m_pos += 8;
|
||||
} while (op < oe);
|
||||
op = oe;
|
||||
if (HAVE_IP(6)) {
|
||||
state = next;
|
||||
COPY4(op, ip);
|
||||
op += next;
|
||||
ip += next;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
NEED_OP(t);
|
||||
do {
|
||||
*op++ = *m_pos++;
|
||||
} while (op < oe);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
unsigned char *oe = op + t;
|
||||
NEED_OP(t);
|
||||
op[0] = m_pos[0];
|
||||
op[1] = m_pos[1];
|
||||
op += 2;
|
||||
m_pos += 2;
|
||||
do {
|
||||
*op++ = *m_pos++;
|
||||
} while (op < oe);
|
||||
}
|
||||
match_next:
|
||||
state = next;
|
||||
t = next;
|
||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
if (likely(HAVE_IP(6) && HAVE_OP(4))) {
|
||||
COPY4(op, ip);
|
||||
op += t;
|
||||
ip += t;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
NEED_IP(t + 3);
|
||||
NEED_OP(t);
|
||||
while (t > 0) {
|
||||
*op++ = *ip++;
|
||||
t--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eof_found:
|
||||
*out_len = op - out;
|
||||
return (t != 3 ? LZO_E_ERROR :
|
||||
ip == ip_end ? LZO_E_OK :
|
||||
ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN);
|
||||
|
||||
input_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_INPUT_OVERRUN;
|
||||
|
||||
output_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_OUTPUT_OVERRUN;
|
||||
|
||||
lookbehind_overrun:
|
||||
*out_len = op - out;
|
||||
return LZO_E_LOOKBEHIND_OVERRUN;
|
||||
}
|
||||
#ifndef STATIC
|
||||
EXPORT_SYMBOL_GPL(lzo1x_decompress_safe);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("LZO1X Decompressor");
|
||||
|
||||
#endif
|
||||
+27
-11
@@ -1,19 +1,37 @@
|
||||
/*
|
||||
* lzodefs.h -- architecture, OS and compiler specific defines
|
||||
*
|
||||
* Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
* Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
||||
*
|
||||
* The full LZO package can be found at:
|
||||
* http://www.oberhumer.com/opensource/lzo/
|
||||
*
|
||||
* Changed for kernel use by:
|
||||
* Changed for Linux kernel use by:
|
||||
* Nitin Gupta <nitingupta910@gmail.com>
|
||||
* Richard Purdie <rpurdie@openedhand.com>
|
||||
*/
|
||||
|
||||
#define LZO_VERSION 0x2020
|
||||
#define LZO_VERSION_STRING "2.02"
|
||||
#define LZO_VERSION_DATE "Oct 17 2005"
|
||||
|
||||
#define COPY4(dst, src) \
|
||||
put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst))
|
||||
#if defined(__x86_64__)
|
||||
#define COPY8(dst, src) \
|
||||
put_unaligned(get_unaligned((const u64 *)(src)), (u64 *)(dst))
|
||||
#else
|
||||
#define COPY8(dst, src) \
|
||||
COPY4(dst, src); COPY4((dst) + 4, (src) + 4)
|
||||
#endif
|
||||
|
||||
#if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
|
||||
#error "conflicting endian definitions"
|
||||
#elif defined(__x86_64__)
|
||||
#define LZO_USE_CTZ64 1
|
||||
#define LZO_USE_CTZ32 1
|
||||
#elif defined(__i386__) || defined(__powerpc__)
|
||||
#define LZO_USE_CTZ32 1
|
||||
#elif defined(__arm__) && (__LINUX_ARM_ARCH__ >= 5)
|
||||
#define LZO_USE_CTZ32 1
|
||||
#endif
|
||||
|
||||
#define M1_MAX_OFFSET 0x0400
|
||||
#define M2_MAX_OFFSET 0x0800
|
||||
@@ -34,10 +52,8 @@
|
||||
#define M3_MARKER 32
|
||||
#define M4_MARKER 16
|
||||
|
||||
#define D_BITS 14
|
||||
#define D_MASK ((1u << D_BITS) - 1)
|
||||
#define lzo_dict_t unsigned short
|
||||
#define D_BITS 13
|
||||
#define D_SIZE (1u << D_BITS)
|
||||
#define D_MASK (D_SIZE - 1)
|
||||
#define D_HIGH ((D_MASK >> 1) + 1)
|
||||
|
||||
#define DX2(p, s1, s2) (((((size_t)((p)[2]) << (s2)) ^ (p)[1]) \
|
||||
<< (s1)) ^ (p)[0])
|
||||
#define DX3(p, s1, s2, s3) ((DX2((p)+1, s2, s3) << (s1)) ^ (p)[0])
|
||||
|
||||
+17
-2
@@ -703,7 +703,14 @@ do { \
|
||||
************** MIPS *****************
|
||||
***************************************/
|
||||
#if defined(__mips__) && W_TYPE_SIZE == 32
|
||||
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
|
||||
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
do { \
|
||||
UDItype __ll = (UDItype)(u) * (v); \
|
||||
w1 = __ll >> 32; \
|
||||
w0 = __ll; \
|
||||
} while (0)
|
||||
#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
__asm__ ("multu %2,%3" \
|
||||
: "=l" ((USItype)(w0)), \
|
||||
@@ -728,7 +735,15 @@ do { \
|
||||
************** MIPS/64 **************
|
||||
***************************************/
|
||||
#if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
|
||||
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
|
||||
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
do { \
|
||||
typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
|
||||
__ll_UTItype __ll = (__ll_UTItype)(u) * (v); \
|
||||
w1 = __ll >> 64; \
|
||||
w0 = __ll; \
|
||||
} while (0)
|
||||
#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
__asm__ ("dmultu %2,%3" \
|
||||
: "=l" ((UDItype)(w0)), \
|
||||
|
||||
+11
-4
@@ -13,6 +13,7 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = {
|
||||
@@ -197,8 +198,8 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
|
||||
}
|
||||
|
||||
if (unlikely(rem > 0))
|
||||
printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
|
||||
"attributes.\n", rem);
|
||||
pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n",
|
||||
rem, current->comm);
|
||||
|
||||
err = 0;
|
||||
errout:
|
||||
@@ -299,9 +300,15 @@ int nla_memcmp(const struct nlattr *nla, const void *data,
|
||||
*/
|
||||
int nla_strcmp(const struct nlattr *nla, const char *str)
|
||||
{
|
||||
int len = strlen(str) + 1;
|
||||
int d = nla_len(nla) - len;
|
||||
int len = strlen(str);
|
||||
char *buf = nla_data(nla);
|
||||
int attrlen = nla_len(nla);
|
||||
int d;
|
||||
|
||||
if (attrlen > 0 && buf[attrlen - 1] == '\0')
|
||||
attrlen--;
|
||||
|
||||
d = attrlen - len;
|
||||
if (d == 0)
|
||||
d = memcmp(nla_data(nla), str, len);
|
||||
|
||||
|
||||
@@ -673,6 +673,9 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
|
||||
* during iterating; it can be zero only at the beginning.
|
||||
* And we cannot overflow iter->next_index in a single step,
|
||||
* because RADIX_TREE_MAP_SHIFT < BITS_PER_LONG.
|
||||
*
|
||||
* This condition also used by radix_tree_next_slot() to stop
|
||||
* contiguous iterating, and forbid swithing to the next chunk.
|
||||
*/
|
||||
index = iter->next_index;
|
||||
if (!index && iter->index)
|
||||
|
||||
+7
-7
@@ -92,7 +92,7 @@ void srandom32(u32 entropy)
|
||||
*/
|
||||
for_each_possible_cpu (i) {
|
||||
struct rnd_state *state = &per_cpu(net_rand_state, i);
|
||||
state->s1 = __seed(state->s1 ^ entropy, 1);
|
||||
state->s1 = __seed(state->s1 ^ entropy, 2);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(srandom32);
|
||||
@@ -109,9 +109,9 @@ static int __init random32_init(void)
|
||||
struct rnd_state *state = &per_cpu(net_rand_state,i);
|
||||
|
||||
#define LCG(x) ((x) * 69069) /* super-duper LCG */
|
||||
state->s1 = __seed(LCG(i + jiffies), 1);
|
||||
state->s2 = __seed(LCG(state->s1), 7);
|
||||
state->s3 = __seed(LCG(state->s2), 15);
|
||||
state->s1 = __seed(LCG(i + jiffies), 2);
|
||||
state->s2 = __seed(LCG(state->s1), 8);
|
||||
state->s3 = __seed(LCG(state->s2), 16);
|
||||
|
||||
/* "warm it up" */
|
||||
prandom32(state);
|
||||
@@ -138,9 +138,9 @@ static int __init random32_reseed(void)
|
||||
u32 seeds[3];
|
||||
|
||||
get_random_bytes(&seeds, sizeof(seeds));
|
||||
state->s1 = __seed(seeds[0], 1);
|
||||
state->s2 = __seed(seeds[1], 7);
|
||||
state->s3 = __seed(seeds[2], 15);
|
||||
state->s1 = __seed(seeds[0], 2);
|
||||
state->s2 = __seed(seeds[1], 8);
|
||||
state->s3 = __seed(seeds[2], 16);
|
||||
|
||||
/* mix it in */
|
||||
prandom32(state);
|
||||
|
||||
+2
-1
@@ -421,7 +421,8 @@ void sg_miter_stop(struct sg_mapping_iter *miter)
|
||||
if (miter->addr) {
|
||||
miter->__offset += miter->consumed;
|
||||
|
||||
if (miter->__flags & SG_MITER_TO_SG)
|
||||
if ((miter->__flags & SG_MITER_TO_SG) &&
|
||||
!PageSlab(miter->page))
|
||||
flush_kernel_dcache_page(miter->page);
|
||||
|
||||
if (miter->__flags & SG_MITER_ATOMIC) {
|
||||
|
||||
@@ -18,6 +18,9 @@ void show_mem(unsigned int filter)
|
||||
printk("Mem-Info:\n");
|
||||
show_free_areas(filter);
|
||||
|
||||
if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
|
||||
return;
|
||||
|
||||
for_each_online_pgdat(pgdat) {
|
||||
unsigned long i, flags;
|
||||
|
||||
|
||||
@@ -586,6 +586,22 @@ void *memset(void *s, int c, size_t count)
|
||||
EXPORT_SYMBOL(memset);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* memzero_explicit - Fill a region of memory (e.g. sensitive
|
||||
* keying data) with 0s.
|
||||
* @s: Pointer to the start of the area.
|
||||
* @count: The size of the area.
|
||||
*
|
||||
* memzero_explicit() doesn't need an arch-specific version as
|
||||
* it just invokes the one of memset() implicitly.
|
||||
*/
|
||||
void memzero_explicit(void *s, size_t count)
|
||||
{
|
||||
memset(s, 0, count);
|
||||
OPTIMIZER_HIDE_VAR(s);
|
||||
}
|
||||
EXPORT_SYMBOL(memzero_explicit);
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMCPY
|
||||
/**
|
||||
* memcpy - Copy one area of memory to another
|
||||
|
||||
+32
-4
@@ -25,6 +25,7 @@
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/cred.h>
|
||||
#include <net/addrconf.h>
|
||||
|
||||
#include <asm/page.h> /* for PAGE_SIZE */
|
||||
@@ -926,16 +927,43 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
||||
* %pK cannot be used in IRQ context because its test
|
||||
* for CAP_SYSLOG would be meaningless.
|
||||
*/
|
||||
if (in_irq() || in_serving_softirq() || in_nmi()) {
|
||||
if (kptr_restrict && (in_irq() || in_serving_softirq() ||
|
||||
in_nmi())) {
|
||||
if (spec.field_width == -1)
|
||||
spec.field_width = 2 * sizeof(void *);
|
||||
return string(buf, end, "pK-error", spec);
|
||||
}
|
||||
if (!((kptr_restrict == 0) ||
|
||||
(kptr_restrict == 1 &&
|
||||
has_capability_noaudit(current, CAP_SYSLOG))))
|
||||
|
||||
switch (kptr_restrict) {
|
||||
case 0:
|
||||
/* Always print %pK values */
|
||||
break;
|
||||
case 1: {
|
||||
/*
|
||||
* Only print the real pointer value if the current
|
||||
* process has CAP_SYSLOG and is running with the
|
||||
* same credentials it started with. This is because
|
||||
* access to files is checked at open() time, but %pK
|
||||
* checks permission at read() time. We don't want to
|
||||
* leak pointer values if a binary opens a file using
|
||||
* %pK and then elevates privileges before reading it.
|
||||
*/
|
||||
const struct cred *cred = current_cred();
|
||||
|
||||
if (!has_capability_noaudit(current, CAP_SYSLOG) ||
|
||||
(cred->euid != cred->uid) ||
|
||||
(cred->egid != cred->gid))
|
||||
ptr = NULL;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
default:
|
||||
/* Always print 0's for %pK */
|
||||
ptr = NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
switch (fmt[1]) {
|
||||
case 'F':
|
||||
|
||||
Reference in New Issue
Block a user