Merge 509a154216 ("Merge tag '5.10-rc6-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6") into android-mainline

Steps on the way to 5.10-rc7

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I122855676b56d2501cd65b604ccc8f5936d8fd71
This commit is contained in:
Greg Kroah-Hartman 2020-12-02 09:21:46 +01:00
commit ea89512d45
17 changed files with 212 additions and 88 deletions

View File

@ -137,15 +137,22 @@ Boot Kernel With a Boot Config
==============================
Since the boot configuration file is loaded with initrd, it will be added
to the end of the initrd (initramfs) image file with size, checksum and
12-byte magic word as below.
to the end of the initrd (initramfs) image file with padding, size,
checksum and 12-byte magic word as below.
[initrd][bootconfig][size(u32)][checksum(u32)][#BOOTCONFIG\n]
[initrd][bootconfig][padding][size(u32)][checksum(u32)][#BOOTCONFIG\n]
When the boot configuration is added to the initrd image, the total
file size is aligned to 4 bytes. To fill the gap, null characters
(``\0``) will be added. Thus the ``size`` is the length of the bootconfig
file + padding bytes.
The Linux kernel decodes the last part of the initrd image in memory to
get the boot configuration data.
Because of this "piggyback" method, there is no need to change or
update the boot loader and the kernel image itself.
update the boot loader and the kernel image itself as long as the boot
loader passes the correct initrd file size. If by any chance, the boot
loader passes a longer size, the kernel feils to find the bootconfig data.
To do this operation, Linux kernel provides "bootconfig" command under
tools/bootconfig, which allows admin to apply or delete the config file
@ -176,7 +183,8 @@ up to 512 key-value pairs. If keys contains 3 words in average, it can
contain 256 key-value pairs. In most cases, the number of config items
will be under 100 entries and smaller than 8KB, so it would be enough.
If the node number exceeds 1024, parser returns an error even if the file
size is smaller than 32KB.
size is smaller than 32KB. (Note that this maximum size is not including
the padding null characters.)
Anyway, since bootconfig command verifies it when appending a boot config
to initrd image, user can notice it before boot.

View File

@ -220,6 +220,7 @@ struct vhost_scsi_tmf {
struct list_head queue_entry;
struct se_cmd se_cmd;
u8 scsi_resp;
struct vhost_scsi_inflight *inflight;
struct iovec resp_iov;
int in_iovs;
@ -426,6 +427,7 @@ static void vhost_scsi_queue_tm_rsp(struct se_cmd *se_cmd)
struct vhost_scsi_tmf *tmf = container_of(se_cmd, struct vhost_scsi_tmf,
se_cmd);
tmf->scsi_resp = se_cmd->se_tmr_req->response;
transport_generic_free_cmd(&tmf->se_cmd, 0);
}
@ -1183,7 +1185,7 @@ static void vhost_scsi_tmf_resp_work(struct vhost_work *work)
vwork);
int resp_code;
if (tmf->se_cmd.se_tmr_req->response == TMR_FUNCTION_COMPLETE)
if (tmf->scsi_resp == TMR_FUNCTION_COMPLETE)
resp_code = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
else
resp_code = VIRTIO_SCSI_S_FUNCTION_REJECTED;

View File

@ -577,6 +577,8 @@ static int vhost_vdpa_map(struct vhost_vdpa *v,
if (r)
vhost_iotlb_del_range(dev->iotlb, iova, iova + size - 1);
else
atomic64_add(size >> PAGE_SHIFT, &dev->mm->pinned_vm);
return r;
}
@ -608,8 +610,9 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
unsigned long list_size = PAGE_SIZE / sizeof(struct page *);
unsigned int gup_flags = FOLL_LONGTERM;
unsigned long npages, cur_base, map_pfn, last_pfn = 0;
unsigned long locked, lock_limit, pinned, i;
unsigned long lock_limit, sz2pin, nchunks, i;
u64 iova = msg->iova;
long pinned;
int ret = 0;
if (msg->iova < v->range.first ||
@ -620,6 +623,7 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
msg->iova + msg->size - 1))
return -EEXIST;
/* Limit the use of memory for bookkeeping */
page_list = (struct page **) __get_free_page(GFP_KERNEL);
if (!page_list)
return -ENOMEM;
@ -628,52 +632,75 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
gup_flags |= FOLL_WRITE;
npages = PAGE_ALIGN(msg->size + (iova & ~PAGE_MASK)) >> PAGE_SHIFT;
if (!npages)
return -EINVAL;
if (!npages) {
ret = -EINVAL;
goto free;
}
mmap_read_lock(dev->mm);
locked = atomic64_add_return(npages, &dev->mm->pinned_vm);
lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
if (locked > lock_limit) {
if (npages + atomic64_read(&dev->mm->pinned_vm) > lock_limit) {
ret = -ENOMEM;
goto out;
goto unlock;
}
cur_base = msg->uaddr & PAGE_MASK;
iova &= PAGE_MASK;
nchunks = 0;
while (npages) {
pinned = min_t(unsigned long, npages, list_size);
ret = pin_user_pages(cur_base, pinned,
gup_flags, page_list, NULL);
if (ret != pinned)
sz2pin = min_t(unsigned long, npages, list_size);
pinned = pin_user_pages(cur_base, sz2pin,
gup_flags, page_list, NULL);
if (sz2pin != pinned) {
if (pinned < 0) {
ret = pinned;
} else {
unpin_user_pages(page_list, pinned);
ret = -ENOMEM;
}
goto out;
}
nchunks++;
if (!last_pfn)
map_pfn = page_to_pfn(page_list[0]);
for (i = 0; i < ret; i++) {
for (i = 0; i < pinned; i++) {
unsigned long this_pfn = page_to_pfn(page_list[i]);
u64 csize;
if (last_pfn && (this_pfn != last_pfn + 1)) {
/* Pin a contiguous chunk of memory */
csize = (last_pfn - map_pfn + 1) << PAGE_SHIFT;
if (vhost_vdpa_map(v, iova, csize,
map_pfn << PAGE_SHIFT,
msg->perm))
ret = vhost_vdpa_map(v, iova, csize,
map_pfn << PAGE_SHIFT,
msg->perm);
if (ret) {
/*
* Unpin the pages that are left unmapped
* from this point on in the current
* page_list. The remaining outstanding
* ones which may stride across several
* chunks will be covered in the common
* error path subsequently.
*/
unpin_user_pages(&page_list[i],
pinned - i);
goto out;
}
map_pfn = this_pfn;
iova += csize;
nchunks = 0;
}
last_pfn = this_pfn;
}
cur_base += ret << PAGE_SHIFT;
npages -= ret;
cur_base += pinned << PAGE_SHIFT;
npages -= pinned;
}
/* Pin the rest chunk */
@ -681,10 +708,27 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
map_pfn << PAGE_SHIFT, msg->perm);
out:
if (ret) {
if (nchunks) {
unsigned long pfn;
/*
* Unpin the outstanding pages which are yet to be
* mapped but haven't due to vdpa_map() or
* pin_user_pages() failure.
*
* Mapped pages are accounted in vdpa_map(), hence
* the corresponding unpinning will be handled by
* vdpa_unmap().
*/
WARN_ON(!last_pfn);
for (pfn = map_pfn; pfn <= last_pfn; pfn++)
unpin_user_page(pfn_to_page(pfn));
}
vhost_vdpa_unmap(v, msg->iova, msg->size);
atomic64_sub(npages, &dev->mm->pinned_vm);
}
unlock:
mmap_read_unlock(dev->mm);
free:
free_page((unsigned long)page_list);
return ret;
}

View File

@ -730,7 +730,7 @@ EXPORT_SYMBOL(vringh_iov_pull_user);
/**
* vringh_iov_push_user - copy bytes into vring_iov.
* @wiov: the wiov as passed to vringh_getdesc_user() (updated as we consume)
* @dst: the place to copy.
* @src: the place to copy from.
* @len: the maximum length to copy.
*
* Returns the bytes copied <= len or a negative errno.
@ -976,7 +976,7 @@ EXPORT_SYMBOL(vringh_iov_pull_kern);
/**
* vringh_iov_push_kern - copy bytes into vring_iov.
* @wiov: the wiov as passed to vringh_getdesc_kern() (updated as we consume)
* @dst: the place to copy.
* @src: the place to copy from.
* @len: the maximum length to copy.
*
* Returns the bytes copied <= len or a negative errno.
@ -1333,7 +1333,7 @@ EXPORT_SYMBOL(vringh_iov_pull_iotlb);
* vringh_iov_push_iotlb - copy bytes into vring_iov.
* @vrh: the vring.
* @wiov: the wiov as passed to vringh_getdesc_iotlb() (updated as we consume)
* @dst: the place to copy.
* @src: the place to copy from.
* @len: the maximum length to copy.
*
* Returns the bytes copied <= len or a negative errno.

View File

@ -876,6 +876,8 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
list_del_init(&server->tcp_ses_list);
spin_unlock(&cifs_tcp_ses_lock);
cancel_delayed_work_sync(&server->echo);
spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
spin_unlock(&GlobalMid_Lock);

View File

@ -339,8 +339,8 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
return -EAGAIN;
if (signal_pending(current)) {
cifs_dbg(FYI, "signal is pending before sending any data\n");
return -EINTR;
cifs_dbg(FYI, "signal pending before send request\n");
return -ERESTARTSYS;
}
/* cork the socket */

View File

@ -12,6 +12,9 @@
#define BOOTCONFIG_MAGIC "#BOOTCONFIG\n"
#define BOOTCONFIG_MAGIC_LEN 12
#define BOOTCONFIG_ALIGN_SHIFT 2
#define BOOTCONFIG_ALIGN (1 << BOOTCONFIG_ALIGN_SHIFT)
#define BOOTCONFIG_ALIGN_MASK (BOOTCONFIG_ALIGN - 1)
/* XBC tree node */
struct xbc_node {

View File

@ -202,7 +202,7 @@ config DYNAMIC_FTRACE_WITH_REGS
config DYNAMIC_FTRACE_WITH_DIRECT_CALLS
def_bool y
depends on DYNAMIC_FTRACE
depends on DYNAMIC_FTRACE_WITH_REGS
depends on HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
config FUNCTION_PROFILER

View File

@ -1629,6 +1629,8 @@ static bool test_rec_ops_needs_regs(struct dyn_ftrace *rec)
static struct ftrace_ops *
ftrace_find_tramp_ops_any(struct dyn_ftrace *rec);
static struct ftrace_ops *
ftrace_find_tramp_ops_any_other(struct dyn_ftrace *rec, struct ftrace_ops *op_exclude);
static struct ftrace_ops *
ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops);
static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
@ -1778,7 +1780,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
* to it.
*/
if (ftrace_rec_count(rec) == 1 &&
ftrace_find_tramp_ops_any(rec))
ftrace_find_tramp_ops_any_other(rec, ops))
rec->flags |= FTRACE_FL_TRAMP;
else
rec->flags &= ~FTRACE_FL_TRAMP;
@ -2244,6 +2246,24 @@ ftrace_find_tramp_ops_any(struct dyn_ftrace *rec)
return NULL;
}
static struct ftrace_ops *
ftrace_find_tramp_ops_any_other(struct dyn_ftrace *rec, struct ftrace_ops *op_exclude)
{
struct ftrace_ops *op;
unsigned long ip = rec->ip;
do_for_each_ftrace_op(op, ftrace_ops_list) {
if (op == op_exclude || !op->trampoline)
continue;
if (hash_contains_ip(ip, op->func_hash))
return op;
} while_for_each_ftrace_op(op);
return NULL;
}
static struct ftrace_ops *
ftrace_find_tramp_ops_next(struct dyn_ftrace *rec,
struct ftrace_ops *op)

View File

@ -3234,14 +3234,12 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
/* See if we shot pass the end of this buffer page */
if (unlikely(write > BUF_PAGE_SIZE)) {
if (tail != w) {
/* before and after may now different, fix it up*/
b_ok = rb_time_read(&cpu_buffer->before_stamp, &info->before);
a_ok = rb_time_read(&cpu_buffer->write_stamp, &info->after);
if (a_ok && b_ok && info->before != info->after)
(void)rb_time_cmpxchg(&cpu_buffer->before_stamp,
info->before, info->after);
}
/* before and after may now different, fix it up*/
b_ok = rb_time_read(&cpu_buffer->before_stamp, &info->before);
a_ok = rb_time_read(&cpu_buffer->write_stamp, &info->after);
if (a_ok && b_ok && info->before != info->after)
(void)rb_time_cmpxchg(&cpu_buffer->before_stamp,
info->before, info->after);
return rb_move_tail(cpu_buffer, tail, info);
}
@ -3287,11 +3285,11 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
ts = rb_time_stamp(cpu_buffer->buffer);
barrier();
/*E*/ if (write == (local_read(&tail_page->write) & RB_WRITE_MASK) &&
info->after < ts) {
info->after < ts &&
rb_time_cmpxchg(&cpu_buffer->write_stamp,
info->after, ts)) {
/* Nothing came after this event between C and E */
info->delta = ts - info->after;
(void)rb_time_cmpxchg(&cpu_buffer->write_stamp,
info->after, info->ts);
info->ts = ts;
} else {
/*

View File

@ -3534,7 +3534,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu,
}
#define STATIC_TEMP_BUF_SIZE 128
static char static_temp_buf[STATIC_TEMP_BUF_SIZE];
static char static_temp_buf[STATIC_TEMP_BUF_SIZE] __aligned(4);
/* Find the next real entry, without updating the iterator itself */
struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,

View File

@ -368,7 +368,7 @@ static int start_kthread(struct trace_array *tr)
struct task_struct *kthread;
int next_cpu;
if (WARN_ON(hwlat_kthread))
if (hwlat_kthread)
return 0;
/* Just pick the first CPU on first iteration */

View File

@ -21,6 +21,7 @@ static unsigned long my_ip = (unsigned long)schedule;
asm (
" .pushsection .text, \"ax\", @progbits\n"
" .type my_tramp1, @function\n"
" .globl my_tramp1\n"
" my_tramp1:"
" pushq %rbp\n"
" movq %rsp, %rbp\n"
@ -29,6 +30,7 @@ asm (
" .size my_tramp1, .-my_tramp1\n"
" ret\n"
" .type my_tramp2, @function\n"
" .globl my_tramp2\n"
" my_tramp2:"
" pushq %rbp\n"
" movq %rsp, %rbp\n"

View File

@ -16,6 +16,7 @@ extern void my_tramp(void *);
asm (
" .pushsection .text, \"ax\", @progbits\n"
" .type my_tramp, @function\n"
" .globl my_tramp\n"
" my_tramp:"
" pushq %rbp\n"
" movq %rsp, %rbp\n"

View File

@ -14,6 +14,7 @@ extern void my_tramp(void *);
asm (
" .pushsection .text, \"ax\", @progbits\n"
" .type my_tramp, @function\n"
" .globl my_tramp\n"
" my_tramp:"
" pushq %rbp\n"
" movq %rsp, %rbp\n"

View File

@ -147,6 +147,12 @@ static int load_xbc_file(const char *path, char **buf)
return ret;
}
static int pr_errno(const char *msg, int err)
{
pr_err("%s: %d\n", msg, err);
return err;
}
static int load_xbc_from_initrd(int fd, char **buf)
{
struct stat stat;
@ -162,26 +168,24 @@ static int load_xbc_from_initrd(int fd, char **buf)
if (stat.st_size < 8 + BOOTCONFIG_MAGIC_LEN)
return 0;
if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0) {
pr_err("Failed to lseek: %d\n", -errno);
return -errno;
}
if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0)
return pr_errno("Failed to lseek for magic", -errno);
if (read(fd, magic, BOOTCONFIG_MAGIC_LEN) < 0)
return -errno;
return pr_errno("Failed to read", -errno);
/* Check the bootconfig magic bytes */
if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0)
return 0;
if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0) {
pr_err("Failed to lseek: %d\n", -errno);
return -errno;
}
if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0)
return pr_errno("Failed to lseek for size", -errno);
if (read(fd, &size, sizeof(u32)) < 0)
return -errno;
return pr_errno("Failed to read size", -errno);
if (read(fd, &csum, sizeof(u32)) < 0)
return -errno;
return pr_errno("Failed to read checksum", -errno);
/* Wrong size error */
if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) {
@ -190,10 +194,8 @@ static int load_xbc_from_initrd(int fd, char **buf)
}
if (lseek(fd, stat.st_size - (size + 8 + BOOTCONFIG_MAGIC_LEN),
SEEK_SET) < 0) {
pr_err("Failed to lseek: %d\n", -errno);
return -errno;
}
SEEK_SET) < 0)
return pr_errno("Failed to lseek", -errno);
ret = load_xbc_fd(fd, buf, size);
if (ret < 0)
@ -262,14 +264,16 @@ static int show_xbc(const char *path, bool list)
ret = stat(path, &st);
if (ret < 0) {
pr_err("Failed to stat %s: %d\n", path, -errno);
return -errno;
ret = -errno;
pr_err("Failed to stat %s: %d\n", path, ret);
return ret;
}
fd = open(path, O_RDONLY);
if (fd < 0) {
pr_err("Failed to open initrd %s: %d\n", path, fd);
return -errno;
ret = -errno;
pr_err("Failed to open initrd %s: %d\n", path, ret);
return ret;
}
ret = load_xbc_from_initrd(fd, &buf);
@ -307,8 +311,9 @@ static int delete_xbc(const char *path)
fd = open(path, O_RDWR);
if (fd < 0) {
pr_err("Failed to open initrd %s: %d\n", path, fd);
return -errno;
ret = -errno;
pr_err("Failed to open initrd %s: %d\n", path, ret);
return ret;
}
size = load_xbc_from_initrd(fd, &buf);
@ -332,11 +337,13 @@ static int delete_xbc(const char *path)
static int apply_xbc(const char *path, const char *xbc_path)
{
u32 size, csum;
char *buf, *data;
int ret, fd;
char *buf, *data, *p;
size_t total_size;
struct stat stat;
const char *msg;
int pos;
u32 size, csum;
int pos, pad;
int ret, fd;
ret = load_xbc_file(xbc_path, &buf);
if (ret < 0) {
@ -346,13 +353,12 @@ static int apply_xbc(const char *path, const char *xbc_path)
size = strlen(buf) + 1;
csum = checksum((unsigned char *)buf, size);
/* Prepare xbc_path data */
data = malloc(size + 8);
/* Backup the bootconfig data */
data = calloc(size + BOOTCONFIG_ALIGN +
sizeof(u32) + sizeof(u32) + BOOTCONFIG_MAGIC_LEN, 1);
if (!data)
return -ENOMEM;
strcpy(data, buf);
*(u32 *)(data + size) = size;
*(u32 *)(data + size + 4) = csum;
memcpy(data, buf, size);
/* Check the data format */
ret = xbc_init(buf, &msg, &pos);
@ -383,28 +389,61 @@ static int apply_xbc(const char *path, const char *xbc_path)
/* Apply new one */
fd = open(path, O_RDWR | O_APPEND);
if (fd < 0) {
pr_err("Failed to open %s: %d\n", path, fd);
ret = -errno;
pr_err("Failed to open %s: %d\n", path, ret);
free(data);
return fd;
return ret;
}
/* TODO: Ensure the @path is initramfs/initrd image */
ret = write(fd, data, size + 8);
if (ret < 0) {
if (fstat(fd, &stat) < 0) {
pr_err("Failed to get the size of %s\n", path);
goto out;
}
/* To align up the total size to BOOTCONFIG_ALIGN, get padding size */
total_size = stat.st_size + size + sizeof(u32) * 2 + BOOTCONFIG_MAGIC_LEN;
pad = ((total_size + BOOTCONFIG_ALIGN - 1) & (~BOOTCONFIG_ALIGN_MASK)) - total_size;
size += pad;
/* Add a footer */
p = data + size;
*(u32 *)p = size;
p += sizeof(u32);
*(u32 *)p = csum;
p += sizeof(u32);
memcpy(p, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
p += BOOTCONFIG_MAGIC_LEN;
total_size = p - data;
ret = write(fd, data, total_size);
if (ret < total_size) {
if (ret < 0)
ret = -errno;
pr_err("Failed to apply a boot config: %d\n", ret);
goto out;
}
/* Write a magic word of the bootconfig */
ret = write(fd, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
if (ret < 0) {
pr_err("Failed to apply a boot config magic: %d\n", ret);
goto out;
}
ret = 0;
if (ret >= 0)
goto out_rollback;
} else
ret = 0;
out:
close(fd);
free(data);
return ret;
out_rollback:
/* Map the partial write to -ENOSPC */
if (ret >= 0)
ret = -ENOSPC;
if (ftruncate(fd, stat.st_size) < 0) {
ret = -errno;
pr_err("Failed to rollback the write error: %d\n", ret);
pr_err("The initrd %s may be corrupted. Recommend to rebuild.\n", path);
}
goto out;
}
static int usage(void)

View File

@ -9,6 +9,7 @@ else
TESTDIR=.
fi
BOOTCONF=${TESTDIR}/bootconfig
ALIGN=4
INITRD=`mktemp ${TESTDIR}/initrd-XXXX`
TEMPCONF=`mktemp ${TESTDIR}/temp-XXXX.bconf`
@ -59,7 +60,10 @@ echo "Show command test"
xpass $BOOTCONF $INITRD
echo "File size check"
xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9 + 12)
total_size=$(expr $bconf_size + $initrd_size + 9 + 12 + $ALIGN - 1 )
total_size=$(expr $total_size / $ALIGN)
total_size=$(expr $total_size \* $ALIGN)
xpass test $new_size -eq $total_size
echo "Apply command repeat test"
xpass $BOOTCONF -a $TEMPCONF $INITRD