1983 lines
66 KiB
Diff
1983 lines
66 KiB
Diff
From tiwai@suse.de Tue Apr 8 14:31:41 2014
|
|
From: Takashi Iwai <tiwai@suse.de>
|
|
Date: Tue, 8 Apr 2014 18:49:00 +0200
|
|
Subject: Revert "ALSA: hda - Increment default stream numbers for AMD HDMI controllers"
|
|
To: stable@vger.kernel.org
|
|
Cc: Anssi Hannula <anssi.hannula@iki.fi>, Christian Güdel <cg@dmesg.ch>
|
|
Message-ID: <1396975740-22160-1-git-send-email-tiwai@suse.de>
|
|
|
|
From: Takashi Iwai <tiwai@suse.de>
|
|
|
|
This reverts commit 7546abfb8e1f9933b549f05898377e9444ee4cb2.
|
|
|
|
The commit [7546abfb: ALSA: hda - Increment default stream numbers for
|
|
AMD HDMI controllers] introduced a regression where the AMD HDMI
|
|
playback streams don't work properly. As the simplest fix, this patch
|
|
reverts that commit.
|
|
|
|
The upstream code has been changed largely and already contains
|
|
another fix (by changing the stream assignment order), this revert
|
|
should be applied only to 3.14 kernel where the regression was
|
|
introduced.
|
|
|
|
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77002
|
|
Reported-by: Christian Güdel <cg@dmesg.ch>
|
|
Reported-by: Anssi Hannula <anssi.hannula@iki.fi>
|
|
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
|
|
Greg, there is no upstream commit id due to the reason describe in the
|
|
above. It's a simple revert, so please take as is.
|
|
|
|
thanks,
|
|
|
|
Takashi
|
|
|
|
sound/pci/hda/hda_intel.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
--- a/sound/pci/hda/hda_intel.c
|
|
+++ b/sound/pci/hda/hda_intel.c
|
|
@@ -297,9 +297,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO
|
|
#define ULI_NUM_CAPTURE 5
|
|
#define ULI_NUM_PLAYBACK 6
|
|
|
|
-/* ATI HDMI may have up to 8 playbacks and 0 capture */
|
|
+/* ATI HDMI has 1 playback and 0 capture */
|
|
#define ATIHDMI_NUM_CAPTURE 0
|
|
-#define ATIHDMI_NUM_PLAYBACK 8
|
|
+#define ATIHDMI_NUM_PLAYBACK 1
|
|
|
|
/* TERA has 4 playback and 3 capture */
|
|
#define TERA_NUM_CAPTURE 3
|
|
From f64410ec665479d7b4b77b7519e814253ed0f686 Mon Sep 17 00:00:00 2001
|
|
From: Paul Moore <pmoore@redhat.com>
|
|
Date: Wed, 19 Mar 2014 16:46:18 -0400
|
|
Subject: selinux: correctly label /proc inodes in use before the policy is loaded
|
|
|
|
From: Paul Moore <pmoore@redhat.com>
|
|
|
|
commit f64410ec665479d7b4b77b7519e814253ed0f686 upstream.
|
|
|
|
This patch is based on an earlier patch by Eric Paris, he describes
|
|
the problem below:
|
|
|
|
"If an inode is accessed before policy load it will get placed on a
|
|
list of inodes to be initialized after policy load. After policy
|
|
load we call inode_doinit() which calls inode_doinit_with_dentry()
|
|
on all inodes accessed before policy load. In the case of inodes
|
|
in procfs that means we'll end up at the bottom where it does:
|
|
|
|
/* Default to the fs superblock SID. */
|
|
isec->sid = sbsec->sid;
|
|
|
|
if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
|
|
if (opt_dentry) {
|
|
isec->sclass = inode_mode_to_security_class(...)
|
|
rc = selinux_proc_get_sid(opt_dentry,
|
|
isec->sclass,
|
|
&sid);
|
|
if (rc)
|
|
goto out_unlock;
|
|
isec->sid = sid;
|
|
}
|
|
}
|
|
|
|
Since opt_dentry is null, we'll never call selinux_proc_get_sid()
|
|
and will leave the inode labeled with the label on the superblock.
|
|
I believe a fix would be to mimic the behavior of xattrs. Look
|
|
for an alias of the inode. If it can't be found, just leave the
|
|
inode uninitialized (and pick it up later) if it can be found, we
|
|
should be able to call selinux_proc_get_sid() ..."
|
|
|
|
On a system exhibiting this problem, you will notice a lot of files in
|
|
/proc with the generic "proc_t" type (at least the ones that were
|
|
accessed early in the boot), for example:
|
|
|
|
# ls -Z /proc/sys/kernel/shmmax | awk '{ print $4 " " $5 }'
|
|
system_u:object_r:proc_t:s0 /proc/sys/kernel/shmmax
|
|
|
|
However, with this patch in place we see the expected result:
|
|
|
|
# ls -Z /proc/sys/kernel/shmmax | awk '{ print $4 " " $5 }'
|
|
system_u:object_r:sysctl_kernel_t:s0 /proc/sys/kernel/shmmax
|
|
|
|
Cc: Eric Paris <eparis@redhat.com>
|
|
Signed-off-by: Paul Moore <pmoore@redhat.com>
|
|
Acked-by: Eric Paris <eparis@redhat.com>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
security/selinux/hooks.c | 36 +++++++++++++++++++++++++++---------
|
|
1 file changed, 27 insertions(+), 9 deletions(-)
|
|
|
|
--- a/security/selinux/hooks.c
|
|
+++ b/security/selinux/hooks.c
|
|
@@ -1418,15 +1418,33 @@ static int inode_doinit_with_dentry(stru
|
|
isec->sid = sbsec->sid;
|
|
|
|
if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
|
|
- if (opt_dentry) {
|
|
- isec->sclass = inode_mode_to_security_class(inode->i_mode);
|
|
- rc = selinux_proc_get_sid(opt_dentry,
|
|
- isec->sclass,
|
|
- &sid);
|
|
- if (rc)
|
|
- goto out_unlock;
|
|
- isec->sid = sid;
|
|
- }
|
|
+ /* We must have a dentry to determine the label on
|
|
+ * procfs inodes */
|
|
+ if (opt_dentry)
|
|
+ /* Called from d_instantiate or
|
|
+ * d_splice_alias. */
|
|
+ dentry = dget(opt_dentry);
|
|
+ else
|
|
+ /* Called from selinux_complete_init, try to
|
|
+ * find a dentry. */
|
|
+ dentry = d_find_alias(inode);
|
|
+ /*
|
|
+ * This can be hit on boot when a file is accessed
|
|
+ * before the policy is loaded. When we load policy we
|
|
+ * may find inodes that have no dentry on the
|
|
+ * sbsec->isec_head list. No reason to complain as
|
|
+ * these will get fixed up the next time we go through
|
|
+ * inode_doinit() with a dentry, before these inodes
|
|
+ * could be used again by userspace.
|
|
+ */
|
|
+ if (!dentry)
|
|
+ goto out_unlock;
|
|
+ isec->sclass = inode_mode_to_security_class(inode->i_mode);
|
|
+ rc = selinux_proc_get_sid(dentry, isec->sclass, &sid);
|
|
+ dput(dentry);
|
|
+ if (rc)
|
|
+ goto out_unlock;
|
|
+ isec->sid = sid;
|
|
}
|
|
break;
|
|
}
|
|
From 42a5477251f0e0f33ad5f6a95c48d685ec03191e Mon Sep 17 00:00:00 2001
|
|
From: Borislav Petkov <bp@suse.de>
|
|
Date: Sat, 18 Jan 2014 12:48:16 +0100
|
|
Subject: x86, pageattr: Export page unmapping interface
|
|
|
|
From: Borislav Petkov <bp@suse.de>
|
|
|
|
commit 42a5477251f0e0f33ad5f6a95c48d685ec03191e upstream.
|
|
|
|
We will use it in efi so expose it.
|
|
|
|
Signed-off-by: Borislav Petkov <bp@suse.de>
|
|
Tested-by: Toshi Kani <toshi.kani@hp.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
arch/x86/include/asm/pgtable_types.h | 2 +
|
|
arch/x86/mm/pageattr.c | 44 ++++++++++++++++++++++++-----------
|
|
2 files changed, 33 insertions(+), 13 deletions(-)
|
|
|
|
--- a/arch/x86/include/asm/pgtable_types.h
|
|
+++ b/arch/x86/include/asm/pgtable_types.h
|
|
@@ -385,6 +385,8 @@ extern pte_t *lookup_address(unsigned lo
|
|
extern phys_addr_t slow_virt_to_phys(void *__address);
|
|
extern int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
|
|
unsigned numpages, unsigned long page_flags);
|
|
+void kernel_unmap_pages_in_pgd(pgd_t *root, unsigned long address,
|
|
+ unsigned numpages);
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
#endif /* _ASM_X86_PGTABLE_DEFS_H */
|
|
--- a/arch/x86/mm/pageattr.c
|
|
+++ b/arch/x86/mm/pageattr.c
|
|
@@ -692,6 +692,18 @@ static bool try_to_free_pmd_page(pmd_t *
|
|
return true;
|
|
}
|
|
|
|
+static bool try_to_free_pud_page(pud_t *pud)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < PTRS_PER_PUD; i++)
|
|
+ if (!pud_none(pud[i]))
|
|
+ return false;
|
|
+
|
|
+ free_page((unsigned long)pud);
|
|
+ return true;
|
|
+}
|
|
+
|
|
static bool unmap_pte_range(pmd_t *pmd, unsigned long start, unsigned long end)
|
|
{
|
|
pte_t *pte = pte_offset_kernel(pmd, start);
|
|
@@ -805,6 +817,16 @@ static void unmap_pud_range(pgd_t *pgd,
|
|
*/
|
|
}
|
|
|
|
+static void unmap_pgd_range(pgd_t *root, unsigned long addr, unsigned long end)
|
|
+{
|
|
+ pgd_t *pgd_entry = root + pgd_index(addr);
|
|
+
|
|
+ unmap_pud_range(pgd_entry, addr, end);
|
|
+
|
|
+ if (try_to_free_pud_page((pud_t *)pgd_page_vaddr(*pgd_entry)))
|
|
+ pgd_clear(pgd_entry);
|
|
+}
|
|
+
|
|
static int alloc_pte_page(pmd_t *pmd)
|
|
{
|
|
pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL | __GFP_NOTRACK);
|
|
@@ -999,9 +1021,8 @@ static int populate_pud(struct cpa_data
|
|
static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
|
|
{
|
|
pgprot_t pgprot = __pgprot(_KERNPG_TABLE);
|
|
- bool allocd_pgd = false;
|
|
- pgd_t *pgd_entry;
|
|
pud_t *pud = NULL; /* shut up gcc */
|
|
+ pgd_t *pgd_entry;
|
|
int ret;
|
|
|
|
pgd_entry = cpa->pgd + pgd_index(addr);
|
|
@@ -1015,7 +1036,6 @@ static int populate_pgd(struct cpa_data
|
|
return -1;
|
|
|
|
set_pgd(pgd_entry, __pgd(__pa(pud) | _KERNPG_TABLE));
|
|
- allocd_pgd = true;
|
|
}
|
|
|
|
pgprot_val(pgprot) &= ~pgprot_val(cpa->mask_clr);
|
|
@@ -1023,19 +1043,11 @@ static int populate_pgd(struct cpa_data
|
|
|
|
ret = populate_pud(cpa, addr, pgd_entry, pgprot);
|
|
if (ret < 0) {
|
|
- unmap_pud_range(pgd_entry, addr,
|
|
+ unmap_pgd_range(cpa->pgd, addr,
|
|
addr + (cpa->numpages << PAGE_SHIFT));
|
|
-
|
|
- if (allocd_pgd) {
|
|
- /*
|
|
- * If I allocated this PUD page, I can just as well
|
|
- * free it in this error path.
|
|
- */
|
|
- pgd_clear(pgd_entry);
|
|
- free_page((unsigned long)pud);
|
|
- }
|
|
return ret;
|
|
}
|
|
+
|
|
cpa->numpages = ret;
|
|
return 0;
|
|
}
|
|
@@ -1861,6 +1873,12 @@ out:
|
|
return retval;
|
|
}
|
|
|
|
+void kernel_unmap_pages_in_pgd(pgd_t *root, unsigned long address,
|
|
+ unsigned numpages)
|
|
+{
|
|
+ unmap_pgd_range(root, address, address + (numpages << PAGE_SHIFT));
|
|
+}
|
|
+
|
|
/*
|
|
* The testcases use internal knowledge of the implementation that shouldn't
|
|
* be exposed to the rest of the kernel. Include these directly here.
|
|
From b7b898ae0c0a82489511a1ce1b35f26215e6beb5 Mon Sep 17 00:00:00 2001
|
|
From: Borislav Petkov <bp@suse.de>
|
|
Date: Sat, 18 Jan 2014 12:48:17 +0100
|
|
Subject: x86/efi: Make efi virtual runtime map passing more robust
|
|
|
|
From: Borislav Petkov <bp@suse.de>
|
|
|
|
commit b7b898ae0c0a82489511a1ce1b35f26215e6beb5 upstream.
|
|
|
|
Currently, running SetVirtualAddressMap() and passing the physical
|
|
address of the virtual map array was working only by a lucky coincidence
|
|
because the memory was present in the EFI page table too. Until Toshi
|
|
went and booted this on a big HP box - the krealloc() manner of resizing
|
|
the memmap we're doing did allocate from such physical addresses which
|
|
were not mapped anymore and boom:
|
|
|
|
http://lkml.kernel.org/r/1386806463.1791.295.camel@misato.fc.hp.com
|
|
|
|
One way to take care of that issue is to reimplement the krealloc thing
|
|
but with pages. We start with contiguous pages of order 1, i.e. 2 pages,
|
|
and when we deplete that memory (shouldn't happen all that often but you
|
|
know firmware) we realloc the next power-of-two pages.
|
|
|
|
Having the pages, it is much more handy and easy to map them into the
|
|
EFI page table with the already existing mapping code which we're using
|
|
for building the virtual mappings.
|
|
|
|
Thanks to Toshi Kani and Matt for the great debugging help.
|
|
|
|
Reported-by: Toshi Kani <toshi.kani@hp.com>
|
|
Signed-off-by: Borislav Petkov <bp@suse.de>
|
|
Tested-by: Toshi Kani <toshi.kani@hp.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Signed-off-by: Borislav Petkov <bp@suse.de>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
arch/x86/include/asm/efi.h | 3 -
|
|
arch/x86/platform/efi/efi.c | 99 ++++++++++++++++++++++++++++++++---------
|
|
arch/x86/platform/efi/efi_32.c | 7 ++
|
|
arch/x86/platform/efi/efi_64.c | 32 ++++++++++++-
|
|
4 files changed, 115 insertions(+), 26 deletions(-)
|
|
|
|
--- a/arch/x86/include/asm/efi.h
|
|
+++ b/arch/x86/include/asm/efi.h
|
|
@@ -130,7 +130,8 @@ extern void efi_memory_uc(u64 addr, unsi
|
|
extern void __init efi_map_region(efi_memory_desc_t *md);
|
|
extern void __init efi_map_region_fixed(efi_memory_desc_t *md);
|
|
extern void efi_sync_low_kernel_mappings(void);
|
|
-extern void efi_setup_page_tables(void);
|
|
+extern int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages);
|
|
+extern void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages);
|
|
extern void __init old_map_region(efi_memory_desc_t *md);
|
|
extern void __init runtime_code_page_mkexec(void);
|
|
extern void __init efi_runtime_mkexec(void);
|
|
--- a/arch/x86/platform/efi/efi.c
|
|
+++ b/arch/x86/platform/efi/efi.c
|
|
@@ -939,14 +939,36 @@ static void __init efi_map_regions_fixed
|
|
|
|
}
|
|
|
|
+static void *realloc_pages(void *old_memmap, int old_shift)
|
|
+{
|
|
+ void *ret;
|
|
+
|
|
+ ret = (void *)__get_free_pages(GFP_KERNEL, old_shift + 1);
|
|
+ if (!ret)
|
|
+ goto out;
|
|
+
|
|
+ /*
|
|
+ * A first-time allocation doesn't have anything to copy.
|
|
+ */
|
|
+ if (!old_memmap)
|
|
+ return ret;
|
|
+
|
|
+ memcpy(ret, old_memmap, PAGE_SIZE << old_shift);
|
|
+
|
|
+out:
|
|
+ free_pages((unsigned long)old_memmap, old_shift);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
/*
|
|
- * Map efi memory ranges for runtime serivce and update new_memmap with virtual
|
|
- * addresses.
|
|
+ * Map the efi memory ranges of the runtime services and update new_mmap with
|
|
+ * virtual addresses.
|
|
*/
|
|
-static void * __init efi_map_regions(int *count)
|
|
+static void * __init efi_map_regions(int *count, int *pg_shift)
|
|
{
|
|
+ void *p, *new_memmap = NULL;
|
|
+ unsigned long left = 0;
|
|
efi_memory_desc_t *md;
|
|
- void *p, *tmp, *new_memmap = NULL;
|
|
|
|
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
|
md = p;
|
|
@@ -961,20 +983,23 @@ static void * __init efi_map_regions(int
|
|
efi_map_region(md);
|
|
get_systab_virt_addr(md);
|
|
|
|
- tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
|
|
- GFP_KERNEL);
|
|
- if (!tmp)
|
|
- goto out;
|
|
- new_memmap = tmp;
|
|
+ if (left < memmap.desc_size) {
|
|
+ new_memmap = realloc_pages(new_memmap, *pg_shift);
|
|
+ if (!new_memmap)
|
|
+ return NULL;
|
|
+
|
|
+ left += PAGE_SIZE << *pg_shift;
|
|
+ (*pg_shift)++;
|
|
+ }
|
|
+
|
|
memcpy(new_memmap + (*count * memmap.desc_size), md,
|
|
memmap.desc_size);
|
|
+
|
|
+ left -= memmap.desc_size;
|
|
(*count)++;
|
|
}
|
|
|
|
return new_memmap;
|
|
-out:
|
|
- kfree(new_memmap);
|
|
- return NULL;
|
|
}
|
|
|
|
/*
|
|
@@ -1000,9 +1025,9 @@ out:
|
|
*/
|
|
void __init efi_enter_virtual_mode(void)
|
|
{
|
|
- efi_status_t status;
|
|
+ int err, count = 0, pg_shift = 0;
|
|
void *new_memmap = NULL;
|
|
- int err, count = 0;
|
|
+ efi_status_t status;
|
|
|
|
efi.systab = NULL;
|
|
|
|
@@ -1019,20 +1044,24 @@ void __init efi_enter_virtual_mode(void)
|
|
efi_map_regions_fixed();
|
|
} else {
|
|
efi_merge_regions();
|
|
- new_memmap = efi_map_regions(&count);
|
|
+ new_memmap = efi_map_regions(&count, &pg_shift);
|
|
if (!new_memmap) {
|
|
pr_err("Error reallocating memory, EFI runtime non-functional!\n");
|
|
return;
|
|
}
|
|
- }
|
|
|
|
- err = save_runtime_map();
|
|
- if (err)
|
|
- pr_err("Error saving runtime map, efi runtime on kexec non-functional!!\n");
|
|
+ err = save_runtime_map();
|
|
+ if (err)
|
|
+ pr_err("Error saving runtime map, efi runtime on kexec non-functional!!\n");
|
|
+ }
|
|
|
|
BUG_ON(!efi.systab);
|
|
|
|
- efi_setup_page_tables();
|
|
+ if (!efi_setup) {
|
|
+ if (efi_setup_page_tables(__pa(new_memmap), 1 << pg_shift))
|
|
+ return;
|
|
+ }
|
|
+
|
|
efi_sync_low_kernel_mappings();
|
|
|
|
if (!efi_setup) {
|
|
@@ -1072,7 +1101,35 @@ void __init efi_enter_virtual_mode(void)
|
|
|
|
efi_runtime_mkexec();
|
|
|
|
- kfree(new_memmap);
|
|
+
|
|
+ /*
|
|
+ * We mapped the descriptor array into the EFI pagetable above but we're
|
|
+ * not unmapping it here. Here's why:
|
|
+ *
|
|
+ * We're copying select PGDs from the kernel page table to the EFI page
|
|
+ * table and when we do so and make changes to those PGDs like unmapping
|
|
+ * stuff from them, those changes appear in the kernel page table and we
|
|
+ * go boom.
|
|
+ *
|
|
+ * From setup_real_mode():
|
|
+ *
|
|
+ * ...
|
|
+ * trampoline_pgd[0] = init_level4_pgt[pgd_index(__PAGE_OFFSET)].pgd;
|
|
+ *
|
|
+ * In this particular case, our allocation is in PGD 0 of the EFI page
|
|
+ * table but we've copied that PGD from PGD[272] of the EFI page table:
|
|
+ *
|
|
+ * pgd_index(__PAGE_OFFSET = 0xffff880000000000) = 272
|
|
+ *
|
|
+ * where the direct memory mapping in kernel space is.
|
|
+ *
|
|
+ * new_memmap's VA comes from that direct mapping and thus clearing it,
|
|
+ * it would get cleared in the kernel page table too.
|
|
+ *
|
|
+ * efi_cleanup_page_tables(__pa(new_memmap), 1 << pg_shift);
|
|
+ */
|
|
+ if (!efi_setup)
|
|
+ free_pages((unsigned long)new_memmap, pg_shift);
|
|
|
|
/* clean DUMMY object */
|
|
efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
|
|
--- a/arch/x86/platform/efi/efi_32.c
|
|
+++ b/arch/x86/platform/efi/efi_32.c
|
|
@@ -40,7 +40,12 @@
|
|
static unsigned long efi_rt_eflags;
|
|
|
|
void efi_sync_low_kernel_mappings(void) {}
|
|
-void efi_setup_page_tables(void) {}
|
|
+void __init efi_dump_pagetable(void) {}
|
|
+int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) {}
|
|
|
|
void __init efi_map_region(efi_memory_desc_t *md)
|
|
{
|
|
--- a/arch/x86/platform/efi/efi_64.c
|
|
+++ b/arch/x86/platform/efi/efi_64.c
|
|
@@ -137,12 +137,38 @@ void efi_sync_low_kernel_mappings(void)
|
|
sizeof(pgd_t) * num_pgds);
|
|
}
|
|
|
|
-void efi_setup_page_tables(void)
|
|
+int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
|
|
{
|
|
+ pgd_t *pgd;
|
|
+
|
|
+ if (efi_enabled(EFI_OLD_MEMMAP))
|
|
+ return 0;
|
|
+
|
|
efi_scratch.efi_pgt = (pgd_t *)(unsigned long)real_mode_header->trampoline_pgd;
|
|
+ pgd = __va(efi_scratch.efi_pgt);
|
|
+
|
|
+ /*
|
|
+ * It can happen that the physical address of new_memmap lands in memory
|
|
+ * which is not mapped in the EFI page table. Therefore we need to go
|
|
+ * and ident-map those pages containing the map before calling
|
|
+ * phys_efi_set_virtual_address_map().
|
|
+ */
|
|
+ if (kernel_map_pages_in_pgd(pgd, pa_memmap, pa_memmap, num_pages, _PAGE_NX)) {
|
|
+ pr_err("Error ident-mapping new memmap (0x%lx)!\n", pa_memmap);
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ efi_scratch.use_pgd = true;
|
|
+
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages)
|
|
+{
|
|
+ pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd);
|
|
|
|
- if (!efi_enabled(EFI_OLD_MEMMAP))
|
|
- efi_scratch.use_pgd = true;
|
|
+ kernel_unmap_pages_in_pgd(pgd, pa_memmap, num_pages);
|
|
}
|
|
|
|
static void __init __map_region(efi_memory_desc_t *md, u64 va)
|
|
From 69cd9eba38867a493a043bb13eb9b33cad5f1a9a Mon Sep 17 00:00:00 2001
|
|
From: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Date: Tue, 8 Apr 2014 15:30:07 -0700
|
|
Subject: futex: avoid race between requeue and wake
|
|
|
|
From: Linus Torvalds <torvalds@linux-foundation.org>
|
|
|
|
commit 69cd9eba38867a493a043bb13eb9b33cad5f1a9a upstream.
|
|
|
|
Jan Stancek reported:
|
|
"pthread_cond_broadcast/4-1.c testcase from openposix testsuite (LTP)
|
|
occasionally fails, because some threads fail to wake up.
|
|
|
|
Testcase creates 5 threads, which are all waiting on same condition.
|
|
Main thread then calls pthread_cond_broadcast() without holding mutex,
|
|
which calls:
|
|
|
|
futex(uaddr1, FUTEX_CMP_REQUEUE_PRIVATE, 1, 2147483647, uaddr2, ..)
|
|
|
|
This immediately wakes up single thread A, which unlocks mutex and
|
|
tries to wake up another thread:
|
|
|
|
futex(uaddr2, FUTEX_WAKE_PRIVATE, 1)
|
|
|
|
If thread A manages to call futex_wake() before any waiters are
|
|
requeued for uaddr2, no other thread is woken up"
|
|
|
|
The ordering constraints for the hash bucket waiter counting are that
|
|
the waiter counts have to be incremented _before_ getting the spinlock
|
|
(because the spinlock acts as part of the memory barrier), but the
|
|
"requeue" operation didn't honor those rules, and nobody had even
|
|
thought about that case.
|
|
|
|
This fairly simple patch just increments the waiter count for the target
|
|
hash bucket (hb2) when requeing a futex before taking the locks. It
|
|
then decrements them again after releasing the lock - the code that
|
|
actually moves the futex(es) between hash buckets will do the additional
|
|
required waiter count housekeeping.
|
|
|
|
Reported-and-tested-by: Jan Stancek <jstancek@redhat.com>
|
|
Acked-by: Davidlohr Bueso <davidlohr@hp.com>
|
|
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
Cc: Thomas Gleixner <tglx@linutronix.de>
|
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
kernel/futex.c | 5 +++++
|
|
1 file changed, 5 insertions(+)
|
|
|
|
--- a/kernel/futex.c
|
|
+++ b/kernel/futex.c
|
|
@@ -1450,6 +1450,7 @@ retry:
|
|
hb2 = hash_futex(&key2);
|
|
|
|
retry_private:
|
|
+ hb_waiters_inc(hb2);
|
|
double_lock_hb(hb1, hb2);
|
|
|
|
if (likely(cmpval != NULL)) {
|
|
@@ -1459,6 +1460,7 @@ retry_private:
|
|
|
|
if (unlikely(ret)) {
|
|
double_unlock_hb(hb1, hb2);
|
|
+ hb_waiters_dec(hb2);
|
|
|
|
ret = get_user(curval, uaddr1);
|
|
if (ret)
|
|
@@ -1508,6 +1510,7 @@ retry_private:
|
|
break;
|
|
case -EFAULT:
|
|
double_unlock_hb(hb1, hb2);
|
|
+ hb_waiters_dec(hb2);
|
|
put_futex_key(&key2);
|
|
put_futex_key(&key1);
|
|
ret = fault_in_user_writeable(uaddr2);
|
|
@@ -1517,6 +1520,7 @@ retry_private:
|
|
case -EAGAIN:
|
|
/* The owner was exiting, try again. */
|
|
double_unlock_hb(hb1, hb2);
|
|
+ hb_waiters_dec(hb2);
|
|
put_futex_key(&key2);
|
|
put_futex_key(&key1);
|
|
cond_resched();
|
|
@@ -1592,6 +1596,7 @@ retry_private:
|
|
|
|
out_unlock:
|
|
double_unlock_hb(hb1, hb2);
|
|
+ hb_waiters_dec(hb2);
|
|
|
|
/*
|
|
* drop_futex_key_refs() must be called outside the spinlocks. During
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Paul Durrant <Paul.Durrant@citrix.com>
|
|
Date: Fri, 28 Mar 2014 11:39:05 +0000
|
|
Subject: xen-netback: remove pointless clause from if statement
|
|
|
|
From: Paul Durrant <Paul.Durrant@citrix.com>
|
|
|
|
[ Upstream commit 0576eddf24df716d8570ef8ca11452a9f98eaab2 ]
|
|
|
|
This patch removes a test in start_new_rx_buffer() that checks whether
|
|
a copy operation is less than MAX_BUFFER_OFFSET in length, since
|
|
MAX_BUFFER_OFFSET is defined to be PAGE_SIZE and the only caller of
|
|
start_new_rx_buffer() already limits copy operations to PAGE_SIZE or less.
|
|
|
|
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
|
|
Cc: Ian Campbell <ian.campbell@citrix.com>
|
|
Cc: Wei Liu <wei.liu2@citrix.com>
|
|
Cc: Sander Eikelenboom <linux@eikelenboom.it>
|
|
Reported-By: Sander Eikelenboom <linux@eikelenboom.it>
|
|
Tested-By: Sander Eikelenboom <linux@eikelenboom.it>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/net/xen-netback/netback.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
--- a/drivers/net/xen-netback/netback.c
|
|
+++ b/drivers/net/xen-netback/netback.c
|
|
@@ -192,8 +192,8 @@ static bool start_new_rx_buffer(int offs
|
|
* into multiple copies tend to give large frags their
|
|
* own buffers as before.
|
|
*/
|
|
- if ((offset + size > MAX_BUFFER_OFFSET) &&
|
|
- (size <= MAX_BUFFER_OFFSET) && offset && !head)
|
|
+ BUG_ON(size > MAX_BUFFER_OFFSET);
|
|
+ if ((offset + size > MAX_BUFFER_OFFSET) && offset && !head)
|
|
return true;
|
|
|
|
return false;
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Paul Durrant <Paul.Durrant@citrix.com>
|
|
Date: Fri, 28 Mar 2014 11:39:06 +0000
|
|
Subject: xen-netback: worse-case estimate in xenvif_rx_action is underestimating
|
|
|
|
From: Paul Durrant <Paul.Durrant@citrix.com>
|
|
|
|
[ Upstream commit a02eb4732cf975d7fc71b6d1a71c058c9988b949 ]
|
|
|
|
The worse-case estimate for skb ring slot usage in xenvif_rx_action()
|
|
fails to take fragment page_offset into account. The page_offset does,
|
|
however, affect the number of times the fragmentation code calls
|
|
start_new_rx_buffer() (i.e. consume another slot) and the worse-case
|
|
should assume that will always return true. This patch adds the page_offset
|
|
into the DIV_ROUND_UP for each frag.
|
|
|
|
Unfortunately some frontends aggressively limit the number of requests
|
|
they post into the shared ring so to avoid an estimate that is 'too'
|
|
pessimal it is capped at MAX_SKB_FRAGS.
|
|
|
|
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
|
|
Cc: Ian Campbell <ian.campbell@citrix.com>
|
|
Cc: Wei Liu <wei.liu2@citrix.com>
|
|
Cc: Sander Eikelenboom <linux@eikelenboom.it>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/net/xen-netback/netback.c | 21 ++++++++++++++++++++-
|
|
1 file changed, 20 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/net/xen-netback/netback.c
|
|
+++ b/drivers/net/xen-netback/netback.c
|
|
@@ -493,9 +493,28 @@ static void xenvif_rx_action(struct xenv
|
|
PAGE_SIZE);
|
|
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
|
unsigned int size;
|
|
+ unsigned int offset;
|
|
+
|
|
size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
|
|
- max_slots_needed += DIV_ROUND_UP(size, PAGE_SIZE);
|
|
+ offset = skb_shinfo(skb)->frags[i].page_offset;
|
|
+
|
|
+ /* For a worse-case estimate we need to factor in
|
|
+ * the fragment page offset as this will affect the
|
|
+ * number of times xenvif_gop_frag_copy() will
|
|
+ * call start_new_rx_buffer().
|
|
+ */
|
|
+ max_slots_needed += DIV_ROUND_UP(offset + size,
|
|
+ PAGE_SIZE);
|
|
}
|
|
+
|
|
+ /* To avoid the estimate becoming too pessimal for some
|
|
+ * frontends that limit posted rx requests, cap the estimate
|
|
+ * at MAX_SKB_FRAGS.
|
|
+ */
|
|
+ if (max_slots_needed > MAX_SKB_FRAGS)
|
|
+ max_slots_needed = MAX_SKB_FRAGS;
|
|
+
|
|
+ /* We may need one more slot for GSO metadata */
|
|
if (skb_is_gso(skb) &&
|
|
(skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 ||
|
|
skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6))
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Paul Durrant <Paul.Durrant@citrix.com>
|
|
Date: Fri, 28 Mar 2014 11:39:07 +0000
|
|
Subject: xen-netback: BUG_ON in xenvif_rx_action() not catching overflow
|
|
|
|
From: Paul Durrant <Paul.Durrant@citrix.com>
|
|
|
|
[ Upstream commit 1425c7a4e8d3d2eebf308bcbdc3fa3c1247686b4 ]
|
|
|
|
The BUG_ON to catch ring overflow in xenvif_rx_action() makes the assumption
|
|
that meta_slots_used == ring slots used. This is not necessarily the case
|
|
for GSO packets, because the non-prefix GSO protocol consumes one more ring
|
|
slot than meta-slot for the 'extra_info'. This patch changes the test to
|
|
actually check ring slots.
|
|
|
|
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
|
|
Cc: Ian Campbell <ian.campbell@citrix.com>
|
|
Cc: Wei Liu <wei.liu2@citrix.com>
|
|
Cc: Sander Eikelenboom <linux@eikelenboom.it>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/net/xen-netback/netback.c | 8 +++++++-
|
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/net/xen-netback/netback.c
|
|
+++ b/drivers/net/xen-netback/netback.c
|
|
@@ -482,6 +482,8 @@ static void xenvif_rx_action(struct xenv
|
|
|
|
while ((skb = skb_dequeue(&vif->rx_queue)) != NULL) {
|
|
RING_IDX max_slots_needed;
|
|
+ RING_IDX old_req_cons;
|
|
+ RING_IDX ring_slots_used;
|
|
int i;
|
|
|
|
/* We need a cheap worse case estimate for the number of
|
|
@@ -530,8 +532,12 @@ static void xenvif_rx_action(struct xenv
|
|
vif->rx_last_skb_slots = 0;
|
|
|
|
sco = (struct skb_cb_overlay *)skb->cb;
|
|
+
|
|
+ old_req_cons = vif->rx.req_cons;
|
|
sco->meta_slots_used = xenvif_gop_skb(skb, &npo);
|
|
- BUG_ON(sco->meta_slots_used > max_slots_needed);
|
|
+ ring_slots_used = vif->rx.req_cons - old_req_cons;
|
|
+
|
|
+ BUG_ON(ring_slots_used > max_slots_needed);
|
|
|
|
__skb_queue_tail(&rxq, skb);
|
|
}
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
|
Date: Mon, 31 Mar 2014 20:14:10 +0200
|
|
Subject: ipv6: some ipv6 statistic counters failed to disable bh
|
|
|
|
From: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
|
|
|
[ Upstream commit 43a43b6040165f7b40b5b489fe61a4cb7f8c4980 ]
|
|
|
|
After commit c15b1ccadb323ea ("ipv6: move DAD and addrconf_verify
|
|
processing to workqueue") some counters are now updated in process context
|
|
and thus need to disable bh before doing so, otherwise deadlocks can
|
|
happen on 32-bit archs. Fabio Estevam noticed this while while mounting
|
|
a NFS volume on an ARM board.
|
|
|
|
As a compensation for missing this I looked after the other *_STATS_BH
|
|
and found three other calls which need updating:
|
|
|
|
1) icmp6_send: ip6_fragment -> icmpv6_send -> icmp6_send (error handling)
|
|
2) ip6_push_pending_frames: rawv6_sendmsg -> rawv6_push_pending_frames -> ...
|
|
(only in case of icmp protocol with raw sockets in error handling)
|
|
3) ping6_v6_sendmsg (error handling)
|
|
|
|
Fixes: c15b1ccadb323ea ("ipv6: move DAD and addrconf_verify processing to workqueue")
|
|
Reported-by: Fabio Estevam <festevam@gmail.com>
|
|
Tested-by: Fabio Estevam <fabio.estevam@freescale.com>
|
|
Cc: Eric Dumazet <eric.dumazet@gmail.com>
|
|
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
net/ipv6/icmp.c | 2 +-
|
|
net/ipv6/ip6_output.c | 4 ++--
|
|
net/ipv6/mcast.c | 11 ++++++-----
|
|
net/ipv6/ping.c | 4 ++--
|
|
4 files changed, 11 insertions(+), 10 deletions(-)
|
|
|
|
--- a/net/ipv6/icmp.c
|
|
+++ b/net/ipv6/icmp.c
|
|
@@ -520,7 +520,7 @@ static void icmp6_send(struct sk_buff *s
|
|
np->tclass, NULL, &fl6, (struct rt6_info *)dst,
|
|
MSG_DONTWAIT, np->dontfrag);
|
|
if (err) {
|
|
- ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
|
|
+ ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
|
|
ip6_flush_pending_frames(sk);
|
|
} else {
|
|
err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
|
|
--- a/net/ipv6/ip6_output.c
|
|
+++ b/net/ipv6/ip6_output.c
|
|
@@ -1566,8 +1566,8 @@ int ip6_push_pending_frames(struct sock
|
|
if (proto == IPPROTO_ICMPV6) {
|
|
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
|
|
|
|
- ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type);
|
|
- ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
|
|
+ ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
|
|
+ ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
|
|
}
|
|
|
|
err = ip6_local_out(skb);
|
|
--- a/net/ipv6/mcast.c
|
|
+++ b/net/ipv6/mcast.c
|
|
@@ -1620,11 +1620,12 @@ static void mld_sendpack(struct sk_buff
|
|
dst_output);
|
|
out:
|
|
if (!err) {
|
|
- ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
|
|
- ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
|
|
- IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
|
|
- } else
|
|
- IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
|
|
+ ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT);
|
|
+ ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
|
|
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
|
|
+ } else {
|
|
+ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
|
|
+ }
|
|
|
|
rcu_read_unlock();
|
|
return;
|
|
--- a/net/ipv6/ping.c
|
|
+++ b/net/ipv6/ping.c
|
|
@@ -182,8 +182,8 @@ int ping_v6_sendmsg(struct kiocb *iocb,
|
|
MSG_DONTWAIT, np->dontfrag);
|
|
|
|
if (err) {
|
|
- ICMP6_INC_STATS_BH(sock_net(sk), rt->rt6i_idev,
|
|
- ICMP6_MIB_OUTERRORS);
|
|
+ ICMP6_INC_STATS(sock_net(sk), rt->rt6i_idev,
|
|
+ ICMP6_MIB_OUTERRORS);
|
|
ip6_flush_pending_frames(sk);
|
|
} else {
|
|
err = icmpv6_push_pending_frames(sk, &fl6,
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Pablo Neira <pablo@netfilter.org>
|
|
Date: Tue, 1 Apr 2014 19:38:44 +0200
|
|
Subject: netlink: don't compare the nul-termination in nla_strcmp
|
|
|
|
From: Pablo Neira <pablo@netfilter.org>
|
|
|
|
[ Upstream commit 8b7b932434f5eee495b91a2804f5b64ebb2bc835 ]
|
|
|
|
nla_strcmp compares the string length plus one, so it's implicitly
|
|
including the nul-termination in the comparison.
|
|
|
|
int nla_strcmp(const struct nlattr *nla, const char *str)
|
|
{
|
|
int len = strlen(str) + 1;
|
|
...
|
|
d = memcmp(nla_data(nla), str, len);
|
|
|
|
However, if NLA_STRING is used, userspace can send us a string without
|
|
the nul-termination. This is a problem since the string
|
|
comparison will not match as the last byte may be not the
|
|
nul-termination.
|
|
|
|
Fix this by skipping the comparison of the nul-termination if the
|
|
attribute data is nul-terminated. Suggested by Thomas Graf.
|
|
|
|
Cc: Florian Westphal <fw@strlen.de>
|
|
Cc: Thomas Graf <tgraf@suug.ch>
|
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
lib/nlattr.c | 10 ++++++++--
|
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
|
|
|
--- a/lib/nlattr.c
|
|
+++ b/lib/nlattr.c
|
|
@@ -303,9 +303,15 @@ int nla_memcmp(const struct nlattr *nla,
|
|
*/
|
|
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);
|
|
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Wei Liu <wei.liu2@citrix.com>
|
|
Date: Tue, 1 Apr 2014 12:46:12 +0100
|
|
Subject: xen-netback: disable rogue vif in kthread context
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
From: Wei Liu <wei.liu2@citrix.com>
|
|
|
|
[ Upstream commit e9d8b2c2968499c1f96563e6522c56958d5a1d0d ]
|
|
|
|
When netback discovers frontend is sending malformed packet it will
|
|
disables the interface which serves that frontend.
|
|
|
|
However disabling a network interface involving taking a mutex which
|
|
cannot be done in softirq context, so we need to defer this process to
|
|
kthread context.
|
|
|
|
This patch does the following:
|
|
1. introduce a flag to indicate the interface is disabled.
|
|
2. check that flag in TX path, don't do any work if it's true.
|
|
3. check that flag in RX path, turn off that interface if it's true.
|
|
|
|
The reason to disable it in RX path is because RX uses kthread. After
|
|
this change the behavior of netback is still consistent -- it won't do
|
|
any TX work for a rogue frontend, and the interface will be eventually
|
|
turned off.
|
|
|
|
Also change a "continue" to "break" after xenvif_fatal_tx_err, as it
|
|
doesn't make sense to continue processing packets if frontend is rogue.
|
|
|
|
This is a fix for XSA-90.
|
|
|
|
Reported-by: Török Edwin <edwin@etorok.net>
|
|
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
|
|
Cc: Ian Campbell <ian.campbell@citrix.com>
|
|
Reviewed-by: David Vrabel <david.vrabel@citrix.com>
|
|
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/net/xen-netback/common.h | 5 +++++
|
|
drivers/net/xen-netback/interface.c | 11 +++++++++++
|
|
drivers/net/xen-netback/netback.c | 16 ++++++++++++++--
|
|
3 files changed, 30 insertions(+), 2 deletions(-)
|
|
|
|
--- a/drivers/net/xen-netback/common.h
|
|
+++ b/drivers/net/xen-netback/common.h
|
|
@@ -113,6 +113,11 @@ struct xenvif {
|
|
domid_t domid;
|
|
unsigned int handle;
|
|
|
|
+ /* Is this interface disabled? True when backend discovers
|
|
+ * frontend is rogue.
|
|
+ */
|
|
+ bool disabled;
|
|
+
|
|
/* Use NAPI for guest TX */
|
|
struct napi_struct napi;
|
|
/* When feature-split-event-channels = 0, tx_irq = rx_irq. */
|
|
--- a/drivers/net/xen-netback/interface.c
|
|
+++ b/drivers/net/xen-netback/interface.c
|
|
@@ -62,6 +62,15 @@ static int xenvif_poll(struct napi_struc
|
|
struct xenvif *vif = container_of(napi, struct xenvif, napi);
|
|
int work_done;
|
|
|
|
+ /* This vif is rogue, we pretend we've there is nothing to do
|
|
+ * for this vif to deschedule it from NAPI. But this interface
|
|
+ * will be turned off in thread context later.
|
|
+ */
|
|
+ if (unlikely(vif->disabled)) {
|
|
+ napi_complete(napi);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
work_done = xenvif_tx_action(vif, budget);
|
|
|
|
if (work_done < budget) {
|
|
@@ -321,6 +330,8 @@ struct xenvif *xenvif_alloc(struct devic
|
|
vif->ip_csum = 1;
|
|
vif->dev = dev;
|
|
|
|
+ vif->disabled = false;
|
|
+
|
|
vif->credit_bytes = vif->remaining_credit = ~0UL;
|
|
vif->credit_usec = 0UL;
|
|
init_timer(&vif->credit_timeout);
|
|
--- a/drivers/net/xen-netback/netback.c
|
|
+++ b/drivers/net/xen-netback/netback.c
|
|
@@ -680,7 +680,8 @@ static void xenvif_tx_err(struct xenvif
|
|
static void xenvif_fatal_tx_err(struct xenvif *vif)
|
|
{
|
|
netdev_err(vif->dev, "fatal error; disabling device\n");
|
|
- xenvif_carrier_off(vif);
|
|
+ vif->disabled = true;
|
|
+ xenvif_kick_thread(vif);
|
|
}
|
|
|
|
static int xenvif_count_requests(struct xenvif *vif,
|
|
@@ -1151,7 +1152,7 @@ static unsigned xenvif_tx_build_gops(str
|
|
vif->tx.sring->req_prod, vif->tx.req_cons,
|
|
XEN_NETIF_TX_RING_SIZE);
|
|
xenvif_fatal_tx_err(vif);
|
|
- continue;
|
|
+ break;
|
|
}
|
|
|
|
work_to_do = RING_HAS_UNCONSUMED_REQUESTS(&vif->tx);
|
|
@@ -1573,7 +1574,18 @@ int xenvif_kthread(void *data)
|
|
while (!kthread_should_stop()) {
|
|
wait_event_interruptible(vif->wq,
|
|
rx_work_todo(vif) ||
|
|
+ vif->disabled ||
|
|
kthread_should_stop());
|
|
+
|
|
+ /* This frontend is found to be rogue, disable it in
|
|
+ * kthread context. Currently this is only set when
|
|
+ * netback finds out frontend sends malformed packet,
|
|
+ * but we cannot disable the interface in softirq
|
|
+ * context so we defer it here.
|
|
+ */
|
|
+ if (unlikely(vif->disabled && netif_carrier_ok(vif->dev)))
|
|
+ xenvif_carrier_off(vif);
|
|
+
|
|
if (kthread_should_stop())
|
|
break;
|
|
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Daniel Pieczko <dpieczko@solarflare.com>
|
|
Date: Tue, 1 Apr 2014 13:10:34 +0100
|
|
Subject: Call efx_set_channels() before efx->type->dimension_resources()
|
|
|
|
From: Daniel Pieczko <dpieczko@solarflare.com>
|
|
|
|
[ Upstream commit 52ad762b85ed7947ec9eff6b036eb985352f6874 ]
|
|
|
|
When using the "separate_tx_channels=1" module parameter, the TX queues are
|
|
initially numbered starting from the first TX-only channel number (after all the
|
|
RX-only channels). efx_set_channels() renumbers the queues so that they are
|
|
indexed from zero.
|
|
|
|
On EF10, the TX queues need to be relabelled in this way before calling the
|
|
dimension_resources NIC type operation, otherwise the TX queue PIO buffers can be
|
|
linked to the wrong VIs when using "separate_tx_channels=1".
|
|
|
|
Added comments to explain UC/WC mappings for PIO buffers
|
|
|
|
Signed-off-by: Shradha Shah <sshah@solarflare.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/net/ethernet/sfc/ef10.c | 7 +++++++
|
|
drivers/net/ethernet/sfc/efx.c | 3 ++-
|
|
2 files changed, 9 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/net/ethernet/sfc/ef10.c
|
|
+++ b/drivers/net/ethernet/sfc/ef10.c
|
|
@@ -565,10 +565,17 @@ static int efx_ef10_dimension_resources(
|
|
* several of each (in fact that's the only option if host
|
|
* page size is >4K). So we may allocate some extra VIs just
|
|
* for writing PIO buffers through.
|
|
+ *
|
|
+ * The UC mapping contains (min_vis - 1) complete VIs and the
|
|
+ * first half of the next VI. Then the WC mapping begins with
|
|
+ * the second half of this last VI.
|
|
*/
|
|
uc_mem_map_size = PAGE_ALIGN((min_vis - 1) * EFX_VI_PAGE_SIZE +
|
|
ER_DZ_TX_PIOBUF);
|
|
if (nic_data->n_piobufs) {
|
|
+ /* pio_write_vi_base rounds down to give the number of complete
|
|
+ * VIs inside the UC mapping.
|
|
+ */
|
|
pio_write_vi_base = uc_mem_map_size / EFX_VI_PAGE_SIZE;
|
|
wc_mem_map_size = (PAGE_ALIGN((pio_write_vi_base +
|
|
nic_data->n_piobufs) *
|
|
--- a/drivers/net/ethernet/sfc/efx.c
|
|
+++ b/drivers/net/ethernet/sfc/efx.c
|
|
@@ -1603,6 +1603,8 @@ static int efx_probe_nic(struct efx_nic
|
|
if (rc)
|
|
goto fail1;
|
|
|
|
+ efx_set_channels(efx);
|
|
+
|
|
rc = efx->type->dimension_resources(efx);
|
|
if (rc)
|
|
goto fail2;
|
|
@@ -1613,7 +1615,6 @@ static int efx_probe_nic(struct efx_nic
|
|
efx->rx_indir_table[i] =
|
|
ethtool_rxfh_indir_default(i, efx->rss_spread);
|
|
|
|
- efx_set_channels(efx);
|
|
netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
|
|
netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels);
|
|
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Mike Rapoport <mike.rapoport@ravellosystems.com>
|
|
Date: Tue, 1 Apr 2014 09:23:01 +0300
|
|
Subject: net: vxlan: fix crash when interface is created with no group
|
|
|
|
From: Mike Rapoport <mike.rapoport@ravellosystems.com>
|
|
|
|
[ Upstream commit 5933a7bbb5de66482ea8aa874a7ebaf8e67603c4 ]
|
|
|
|
If the vxlan interface is created without explicit group definition,
|
|
there are corner cases which may cause kernel panic.
|
|
|
|
For instance, in the following scenario:
|
|
|
|
node A:
|
|
$ ip link add dev vxlan42 address 2c:c2:60:00:10:20 type vxlan id 42
|
|
$ ip addr add dev vxlan42 10.0.0.1/24
|
|
$ ip link set up dev vxlan42
|
|
$ arp -i vxlan42 -s 10.0.0.2 2c:c2:60:00:01:02
|
|
$ bridge fdb add dev vxlan42 to 2c:c2:60:00:01:02 dst <IPv4 address>
|
|
$ ping 10.0.0.2
|
|
|
|
node B:
|
|
$ ip link add dev vxlan42 address 2c:c2:60:00:01:02 type vxlan id 42
|
|
$ ip addr add dev vxlan42 10.0.0.2/24
|
|
$ ip link set up dev vxlan42
|
|
$ arp -i vxlan42 -s 10.0.0.1 2c:c2:60:00:10:20
|
|
|
|
node B crashes:
|
|
|
|
vxlan42: 2c:c2:60:00:10:20 migrated from 4011:eca4:c0a8:6466:c0a8:6415:8e09:2118 to (invalid address)
|
|
vxlan42: 2c:c2:60:00:10:20 migrated from 4011:eca4:c0a8:6466:c0a8:6415:8e09:2118 to (invalid address)
|
|
BUG: unable to handle kernel NULL pointer dereference at 0000000000000046
|
|
IP: [<ffffffff8143c459>] ip6_route_output+0x58/0x82
|
|
PGD 7bd89067 PUD 7bd4e067 PMD 0
|
|
Oops: 0000 [#1] SMP
|
|
Modules linked in:
|
|
CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.14.0-rc8-hvx-xen-00019-g97a5221-dirty #154
|
|
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
|
|
task: ffff88007c774f50 ti: ffff88007c79c000 task.ti: ffff88007c79c000
|
|
RIP: 0010:[<ffffffff8143c459>] [<ffffffff8143c459>] ip6_route_output+0x58/0x82
|
|
RSP: 0018:ffff88007fd03668 EFLAGS: 00010282
|
|
RAX: 0000000000000000 RBX: ffffffff8186a000 RCX: 0000000000000040
|
|
RDX: 0000000000000000 RSI: ffff88007b0e4a80 RDI: ffff88007fd03754
|
|
RBP: ffff88007fd03688 R08: ffff88007b0e4a80 R09: 0000000000000000
|
|
R10: 0200000a0100000a R11: 0001002200000000 R12: ffff88007fd03740
|
|
R13: ffff88007b0e4a80 R14: ffff88007b0e4a80 R15: ffff88007bba0c50
|
|
FS: 0000000000000000(0000) GS:ffff88007fd00000(0000) knlGS:0000000000000000
|
|
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
|
|
CR2: 0000000000000046 CR3: 000000007bb60000 CR4: 00000000000006e0
|
|
Stack:
|
|
0000000000000000 ffff88007fd037a0 ffffffff8186a000 ffff88007fd03740
|
|
ffff88007fd036c8 ffffffff814320bb 0000000000006e49 ffff88007b8b7360
|
|
ffff88007bdbf200 ffff88007bcbc000 ffff88007b8b7000 ffff88007b8b7360
|
|
Call Trace:
|
|
<IRQ>
|
|
[<ffffffff814320bb>] ip6_dst_lookup_tail+0x2d/0xa4
|
|
[<ffffffff814322a5>] ip6_dst_lookup+0x10/0x12
|
|
[<ffffffff81323b4e>] vxlan_xmit_one+0x32a/0x68c
|
|
[<ffffffff814a325a>] ? _raw_spin_unlock_irqrestore+0x12/0x14
|
|
[<ffffffff8104c551>] ? lock_timer_base.isra.23+0x26/0x4b
|
|
[<ffffffff8132451a>] vxlan_xmit+0x66a/0x6a8
|
|
[<ffffffff8141a365>] ? ipt_do_table+0x35f/0x37e
|
|
[<ffffffff81204ba2>] ? selinux_ip_postroute+0x41/0x26e
|
|
[<ffffffff8139d0c1>] dev_hard_start_xmit+0x2ce/0x3ce
|
|
[<ffffffff8139d491>] __dev_queue_xmit+0x2d0/0x392
|
|
[<ffffffff813b380f>] ? eth_header+0x28/0xb5
|
|
[<ffffffff8139d569>] dev_queue_xmit+0xb/0xd
|
|
[<ffffffff813a5aa6>] neigh_resolve_output+0x134/0x152
|
|
[<ffffffff813db741>] ip_finish_output2+0x236/0x299
|
|
[<ffffffff813dc074>] ip_finish_output+0x98/0x9d
|
|
[<ffffffff813dc749>] ip_output+0x62/0x67
|
|
[<ffffffff813da9f2>] dst_output+0xf/0x11
|
|
[<ffffffff813dc11c>] ip_local_out+0x1b/0x1f
|
|
[<ffffffff813dcf1b>] ip_send_skb+0x11/0x37
|
|
[<ffffffff813dcf70>] ip_push_pending_frames+0x2f/0x33
|
|
[<ffffffff813ff732>] icmp_push_reply+0x106/0x115
|
|
[<ffffffff813ff9e4>] icmp_reply+0x142/0x164
|
|
[<ffffffff813ffb3b>] icmp_echo.part.16+0x46/0x48
|
|
[<ffffffff813c1d30>] ? nf_iterate+0x43/0x80
|
|
[<ffffffff813d8037>] ? xfrm4_policy_check.constprop.11+0x52/0x52
|
|
[<ffffffff813ffb62>] icmp_echo+0x25/0x27
|
|
[<ffffffff814005f7>] icmp_rcv+0x1d2/0x20a
|
|
[<ffffffff813d8037>] ? xfrm4_policy_check.constprop.11+0x52/0x52
|
|
[<ffffffff813d810d>] ip_local_deliver_finish+0xd6/0x14f
|
|
[<ffffffff813d8037>] ? xfrm4_policy_check.constprop.11+0x52/0x52
|
|
[<ffffffff813d7fde>] NF_HOOK.constprop.10+0x4c/0x53
|
|
[<ffffffff813d82bf>] ip_local_deliver+0x4a/0x4f
|
|
[<ffffffff813d7f7b>] ip_rcv_finish+0x253/0x26a
|
|
[<ffffffff813d7d28>] ? inet_add_protocol+0x3e/0x3e
|
|
[<ffffffff813d7fde>] NF_HOOK.constprop.10+0x4c/0x53
|
|
[<ffffffff813d856a>] ip_rcv+0x2a6/0x2ec
|
|
[<ffffffff8139a9a0>] __netif_receive_skb_core+0x43e/0x478
|
|
[<ffffffff812a346f>] ? virtqueue_poll+0x16/0x27
|
|
[<ffffffff8139aa2f>] __netif_receive_skb+0x55/0x5a
|
|
[<ffffffff8139aaaa>] process_backlog+0x76/0x12f
|
|
[<ffffffff8139add8>] net_rx_action+0xa2/0x1ab
|
|
[<ffffffff81047847>] __do_softirq+0xca/0x1d1
|
|
[<ffffffff81047ace>] irq_exit+0x3e/0x85
|
|
[<ffffffff8100b98b>] do_IRQ+0xa9/0xc4
|
|
[<ffffffff814a37ad>] common_interrupt+0x6d/0x6d
|
|
<EOI>
|
|
[<ffffffff810378db>] ? native_safe_halt+0x6/0x8
|
|
[<ffffffff810110c7>] default_idle+0x9/0xd
|
|
[<ffffffff81011694>] arch_cpu_idle+0x13/0x1c
|
|
[<ffffffff8107480d>] cpu_startup_entry+0xbc/0x137
|
|
[<ffffffff8102e741>] start_secondary+0x1a0/0x1a5
|
|
Code: 24 14 e8 f1 e5 01 00 31 d2 a8 32 0f 95 c2 49 8b 44 24 2c 49 0b 44 24 24 74 05 83 ca 04 eb 1c 4d 85 ed 74 17 49 8b 85 a8 02 00 00 <66> 8b 40 46 66 c1 e8 07 83 e0 07 c1 e0 03 09 c2 4c 89 e6 48 89
|
|
RIP [<ffffffff8143c459>] ip6_route_output+0x58/0x82
|
|
RSP <ffff88007fd03668>
|
|
CR2: 0000000000000046
|
|
---[ end trace 4612329caab37efd ]---
|
|
|
|
When vxlan interface is created without explicit group definition, the
|
|
default_dst protocol family is initialiazed to AF_UNSPEC and the driver
|
|
assumes IPv4 configuration. On the other side, the default_dst protocol
|
|
family is used to differentiate between IPv4 and IPv6 cases and, since,
|
|
AF_UNSPEC != AF_INET, the processing takes the IPv6 path.
|
|
|
|
Making the IPv4 assumption explicit by settting default_dst protocol
|
|
family to AF_INET4 and preventing mixing of IPv4 and IPv6 addresses in
|
|
snooped fdb entries fixes the corner case crashes.
|
|
|
|
Signed-off-by: Mike Rapoport <mike.rapoport@ravellosystems.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/net/vxlan.c | 6 +++++-
|
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/net/vxlan.c
|
|
+++ b/drivers/net/vxlan.c
|
|
@@ -871,6 +871,9 @@ static int vxlan_fdb_add(struct ndmsg *n
|
|
if (err)
|
|
return err;
|
|
|
|
+ if (vxlan->default_dst.remote_ip.sa.sa_family != ip.sa.sa_family)
|
|
+ return -EAFNOSUPPORT;
|
|
+
|
|
spin_lock_bh(&vxlan->hash_lock);
|
|
err = vxlan_fdb_create(vxlan, addr, &ip, ndm->ndm_state, flags,
|
|
port, vni, ifindex, ndm->ndm_flags);
|
|
@@ -2612,9 +2615,10 @@ static int vxlan_newlink(struct net *net
|
|
vni = nla_get_u32(data[IFLA_VXLAN_ID]);
|
|
dst->remote_vni = vni;
|
|
|
|
+ /* Unless IPv6 is explicitly requested, assume IPv4 */
|
|
+ dst->remote_ip.sa.sa_family = AF_INET;
|
|
if (data[IFLA_VXLAN_GROUP]) {
|
|
dst->remote_ip.sin.sin_addr.s_addr = nla_get_be32(data[IFLA_VXLAN_GROUP]);
|
|
- dst->remote_ip.sa.sa_family = AF_INET;
|
|
} else if (data[IFLA_VXLAN_GROUP6]) {
|
|
if (!IS_ENABLED(CONFIG_IPV6))
|
|
return -EPFNOSUPPORT;
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
|
|
Date: Wed, 2 Apr 2014 12:48:42 +0900
|
|
Subject: isdnloop: Validate NUL-terminated strings from user.
|
|
|
|
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
|
|
|
|
[ Upstream commit 77bc6bed7121936bb2e019a8c336075f4c8eef62 ]
|
|
|
|
Return -EINVAL unless all of user-given strings are correctly
|
|
NUL-terminated.
|
|
|
|
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/isdn/isdnloop/isdnloop.c | 6 ++++++
|
|
1 file changed, 6 insertions(+)
|
|
|
|
--- a/drivers/isdn/isdnloop/isdnloop.c
|
|
+++ b/drivers/isdn/isdnloop/isdnloop.c
|
|
@@ -1070,6 +1070,12 @@ isdnloop_start(isdnloop_card *card, isdn
|
|
return -EBUSY;
|
|
if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef)))
|
|
return -EFAULT;
|
|
+
|
|
+ for (i = 0; i < 3; i++) {
|
|
+ if (!memchr(sdef.num[i], 0, sizeof(sdef.num[i])))
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
spin_lock_irqsave(&card->isdnloop_lock, flags);
|
|
switch (sdef.ptype) {
|
|
case ISDN_PTYPE_EURO:
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Dan Carpenter <dan.carpenter@oracle.com>
|
|
Date: Tue, 8 Apr 2014 12:23:09 +0300
|
|
Subject: isdnloop: several buffer overflows
|
|
|
|
From: Dan Carpenter <dan.carpenter@oracle.com>
|
|
|
|
[ Upstream commit 7563487cbf865284dcd35e9ef5a95380da046737 ]
|
|
|
|
There are three buffer overflows addressed in this patch.
|
|
|
|
1) In isdnloop_fake_err() we add an 'E' to a 60 character string and
|
|
then copy it into a 60 character buffer. I have made the destination
|
|
buffer 64 characters and I'm changed the sprintf() to a snprintf().
|
|
|
|
2) In isdnloop_parse_cmd(), p points to a 6 characters into a 60
|
|
character buffer so we have 54 characters. The ->eazlist[] is 11
|
|
characters long. I have modified the code to return if the source
|
|
buffer is too long.
|
|
|
|
3) In isdnloop_command() the cbuf[] array was 60 characters long but the
|
|
max length of the string then can be up to 79 characters. I made the
|
|
cbuf array 80 characters long and changed the sprintf() to snprintf().
|
|
I also removed the temporary "dial" buffer and changed it to use "p"
|
|
directly.
|
|
|
|
Unfortunately, we pass the "cbuf" string from isdnloop_command() to
|
|
isdnloop_writecmd() which truncates anything over 60 characters to make
|
|
it fit in card->omsg[]. (It can accept values up to 255 characters so
|
|
long as there is a '\n' character every 60 characters). For now I have
|
|
just fixed the memory corruption bug and left the other problems in this
|
|
driver alone.
|
|
|
|
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/isdn/isdnloop/isdnloop.c | 17 +++++++++--------
|
|
1 file changed, 9 insertions(+), 8 deletions(-)
|
|
|
|
--- a/drivers/isdn/isdnloop/isdnloop.c
|
|
+++ b/drivers/isdn/isdnloop/isdnloop.c
|
|
@@ -518,9 +518,9 @@ static isdnloop_stat isdnloop_cmd_table[
|
|
static void
|
|
isdnloop_fake_err(isdnloop_card *card)
|
|
{
|
|
- char buf[60];
|
|
+ char buf[64];
|
|
|
|
- sprintf(buf, "E%s", card->omsg);
|
|
+ snprintf(buf, sizeof(buf), "E%s", card->omsg);
|
|
isdnloop_fake(card, buf, -1);
|
|
isdnloop_fake(card, "NAK", -1);
|
|
}
|
|
@@ -903,6 +903,8 @@ isdnloop_parse_cmd(isdnloop_card *card)
|
|
case 7:
|
|
/* 0x;EAZ */
|
|
p += 3;
|
|
+ if (strlen(p) >= sizeof(card->eazlist[0]))
|
|
+ break;
|
|
strcpy(card->eazlist[ch - 1], p);
|
|
break;
|
|
case 8:
|
|
@@ -1133,7 +1135,7 @@ isdnloop_command(isdn_ctrl *c, isdnloop_
|
|
{
|
|
ulong a;
|
|
int i;
|
|
- char cbuf[60];
|
|
+ char cbuf[80];
|
|
isdn_ctrl cmd;
|
|
isdnloop_cdef cdef;
|
|
|
|
@@ -1198,7 +1200,6 @@ isdnloop_command(isdn_ctrl *c, isdnloop_
|
|
break;
|
|
if ((c->arg & 255) < ISDNLOOP_BCH) {
|
|
char *p;
|
|
- char dial[50];
|
|
char dcode[4];
|
|
|
|
a = c->arg;
|
|
@@ -1210,10 +1211,10 @@ isdnloop_command(isdn_ctrl *c, isdnloop_
|
|
} else
|
|
/* Normal Dial */
|
|
strcpy(dcode, "CAL");
|
|
- strcpy(dial, p);
|
|
- sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
|
|
- dcode, dial, c->parm.setup.si1,
|
|
- c->parm.setup.si2, c->parm.setup.eazmsn);
|
|
+ snprintf(cbuf, sizeof(cbuf),
|
|
+ "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
|
|
+ dcode, p, c->parm.setup.si1,
|
|
+ c->parm.setup.si2, c->parm.setup.eazmsn);
|
|
i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
|
|
}
|
|
break;
|
|
From foo@baz Thu Apr 10 20:31:46 PDT 2014
|
|
From: Sasha Levin <sasha.levin@oracle.com>
|
|
Date: Sat, 29 Mar 2014 20:39:35 -0400
|
|
Subject: rds: prevent dereference of a NULL device in rds_iw_laddr_check
|
|
|
|
From: Sasha Levin <sasha.levin@oracle.com>
|
|
|
|
[ Upstream commit bf39b4247b8799935ea91d90db250ab608a58e50 ]
|
|
|
|
Binding might result in a NULL device which is later dereferenced
|
|
without checking.
|
|
|
|
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
net/rds/iw.c | 3 ++-
|
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
|
|
--- a/net/rds/iw.c
|
|
+++ b/net/rds/iw.c
|
|
@@ -239,7 +239,8 @@ static int rds_iw_laddr_check(__be32 add
|
|
ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin);
|
|
/* due to this, we will claim to support IB devices unless we
|
|
check node_type. */
|
|
- if (ret || cm_id->device->node_type != RDMA_NODE_RNIC)
|
|
+ if (ret || !cm_id->device ||
|
|
+ cm_id->device->node_type != RDMA_NODE_RNIC)
|
|
ret = -EADDRNOTAVAIL;
|
|
|
|
rdsdebug("addr %pI4 ret %d node type %d\n",
|
|
From foo@baz Thu Apr 10 20:31:47 PDT 2014
|
|
From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
|
|
Date: Sun, 6 Apr 2014 20:37:44 +0200
|
|
Subject: net/at91_ether: avoid NULL pointer dereference
|
|
|
|
From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
|
|
|
|
[ Upstream commit c293fb785bdda64d88f197e6758a3c16ae83e569 ]
|
|
|
|
The at91_ether driver calls macb_mii_init passing a 'struct macb'
|
|
structure whose tx_clk member is initialized to 0. However,
|
|
macb_handle_link_change() expects tx_clk to be the result of
|
|
a call to clk_get, and so IS_ERR(tx_clk) to be true if the clock
|
|
is invalid. This causes an oops when booting Linux 3.14 on the
|
|
csb637 board. The following changes avoids this.
|
|
|
|
Signed-off-by: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
|
|
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/net/ethernet/cadence/at91_ether.c | 3 +++
|
|
1 file changed, 3 insertions(+)
|
|
|
|
--- a/drivers/net/ethernet/cadence/at91_ether.c
|
|
+++ b/drivers/net/ethernet/cadence/at91_ether.c
|
|
@@ -342,6 +342,9 @@ static int __init at91ether_probe(struct
|
|
}
|
|
clk_enable(lp->pclk);
|
|
|
|
+ lp->hclk = ERR_PTR(-ENOENT);
|
|
+ lp->tx_clk = ERR_PTR(-ENOENT);
|
|
+
|
|
/* Install the interrupt handler */
|
|
dev->irq = platform_get_irq(pdev, 0);
|
|
res = devm_request_irq(&pdev->dev, dev->irq, at91ether_interrupt, 0, dev->name, dev);
|
|
From 8930b05090acd321b1fc7c642528c697cb105c42 Mon Sep 17 00:00:00 2001
|
|
From: Eyal Shapira <eyal@wizery.com>
|
|
Date: Sun, 16 Mar 2014 05:23:21 +0200
|
|
Subject: iwlwifi: mvm: rs: fix search cycle rules
|
|
|
|
From: Eyal Shapira <eyal@wizery.com>
|
|
|
|
commit 8930b05090acd321b1fc7c642528c697cb105c42 upstream.
|
|
|
|
We should explore all possible columns when searching to be
|
|
as resilient as possible to changing conditions. This fixes
|
|
for example a scenario where even after a sudden creation of
|
|
rssi difference between the 2 antennas we would keep doing MIMO
|
|
at a low rate instead of switching to SISO at a higher rate using
|
|
the better antenna which was the optimal configuration.
|
|
|
|
Signed-off-by: Eyal Shapira <eyalx.shapira@intel.com>
|
|
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
drivers/net/wireless/iwlwifi/mvm/rs.c | 36 +++++++++++++++++-----------------
|
|
1 file changed, 18 insertions(+), 18 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
|
|
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
|
|
@@ -211,9 +211,9 @@ static const struct rs_tx_column rs_tx_c
|
|
.next_columns = {
|
|
RS_COLUMN_LEGACY_ANT_B,
|
|
RS_COLUMN_SISO_ANT_A,
|
|
+ RS_COLUMN_SISO_ANT_B,
|
|
RS_COLUMN_MIMO2,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
+ RS_COLUMN_MIMO2_SGI,
|
|
},
|
|
},
|
|
[RS_COLUMN_LEGACY_ANT_B] = {
|
|
@@ -221,10 +221,10 @@ static const struct rs_tx_column rs_tx_c
|
|
.ant = ANT_B,
|
|
.next_columns = {
|
|
RS_COLUMN_LEGACY_ANT_A,
|
|
+ RS_COLUMN_SISO_ANT_A,
|
|
RS_COLUMN_SISO_ANT_B,
|
|
RS_COLUMN_MIMO2,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
+ RS_COLUMN_MIMO2_SGI,
|
|
},
|
|
},
|
|
[RS_COLUMN_SISO_ANT_A] = {
|
|
@@ -234,8 +234,8 @@ static const struct rs_tx_column rs_tx_c
|
|
RS_COLUMN_SISO_ANT_B,
|
|
RS_COLUMN_MIMO2,
|
|
RS_COLUMN_SISO_ANT_A_SGI,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
+ RS_COLUMN_SISO_ANT_B_SGI,
|
|
+ RS_COLUMN_MIMO2_SGI,
|
|
},
|
|
.checks = {
|
|
rs_siso_allow,
|
|
@@ -248,8 +248,8 @@ static const struct rs_tx_column rs_tx_c
|
|
RS_COLUMN_SISO_ANT_A,
|
|
RS_COLUMN_MIMO2,
|
|
RS_COLUMN_SISO_ANT_B_SGI,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
+ RS_COLUMN_SISO_ANT_A_SGI,
|
|
+ RS_COLUMN_MIMO2_SGI,
|
|
},
|
|
.checks = {
|
|
rs_siso_allow,
|
|
@@ -263,8 +263,8 @@ static const struct rs_tx_column rs_tx_c
|
|
RS_COLUMN_SISO_ANT_B_SGI,
|
|
RS_COLUMN_MIMO2_SGI,
|
|
RS_COLUMN_SISO_ANT_A,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
+ RS_COLUMN_SISO_ANT_B,
|
|
+ RS_COLUMN_MIMO2,
|
|
},
|
|
.checks = {
|
|
rs_siso_allow,
|
|
@@ -279,8 +279,8 @@ static const struct rs_tx_column rs_tx_c
|
|
RS_COLUMN_SISO_ANT_A_SGI,
|
|
RS_COLUMN_MIMO2_SGI,
|
|
RS_COLUMN_SISO_ANT_B,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
+ RS_COLUMN_SISO_ANT_A,
|
|
+ RS_COLUMN_MIMO2,
|
|
},
|
|
.checks = {
|
|
rs_siso_allow,
|
|
@@ -292,10 +292,10 @@ static const struct rs_tx_column rs_tx_c
|
|
.ant = ANT_AB,
|
|
.next_columns = {
|
|
RS_COLUMN_SISO_ANT_A,
|
|
+ RS_COLUMN_SISO_ANT_B,
|
|
+ RS_COLUMN_SISO_ANT_A_SGI,
|
|
+ RS_COLUMN_SISO_ANT_B_SGI,
|
|
RS_COLUMN_MIMO2_SGI,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
},
|
|
.checks = {
|
|
rs_mimo_allow,
|
|
@@ -307,10 +307,10 @@ static const struct rs_tx_column rs_tx_c
|
|
.sgi = true,
|
|
.next_columns = {
|
|
RS_COLUMN_SISO_ANT_A_SGI,
|
|
+ RS_COLUMN_SISO_ANT_B_SGI,
|
|
+ RS_COLUMN_SISO_ANT_A,
|
|
+ RS_COLUMN_SISO_ANT_B,
|
|
RS_COLUMN_MIMO2,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
- RS_COLUMN_INVALID,
|
|
},
|
|
.checks = {
|
|
rs_mimo_allow,
|
|
From 6eda477b3c54b8236868c8784e5e042ff14244f0 Mon Sep 17 00:00:00 2001
|
|
From: Mischa Jonker <mjonker@synopsys.com>
|
|
Date: Thu, 16 May 2013 19:36:08 +0200
|
|
Subject: ARC: [nsimosci] Change .dts to use generic 8250 UART
|
|
|
|
From: Mischa Jonker <mjonker@synopsys.com>
|
|
|
|
commit 6eda477b3c54b8236868c8784e5e042ff14244f0 upstream.
|
|
|
|
The Synopsys APB DW UART has a couple of special features that are not
|
|
in the System C model. In 3.8, the 8250_dw driver didn't really use these
|
|
features, but from 3.9 onwards, the 8250_dw driver has become incompatible
|
|
with our model.
|
|
|
|
Signed-off-by: Mischa Jonker <mjonker@synopsys.com>
|
|
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
|
|
Cc: Francois Bedard <Francois.Bedard@synopsys.com>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
arch/arc/boot/dts/nsimosci.dts | 7 +++----
|
|
1 file changed, 3 insertions(+), 4 deletions(-)
|
|
|
|
--- a/arch/arc/boot/dts/nsimosci.dts
|
|
+++ b/arch/arc/boot/dts/nsimosci.dts
|
|
@@ -11,7 +11,7 @@
|
|
|
|
/ {
|
|
compatible = "snps,nsimosci";
|
|
- clock-frequency = <80000000>; /* 80 MHZ */
|
|
+ clock-frequency = <20000000>; /* 20 MHZ */
|
|
#address-cells = <1>;
|
|
#size-cells = <1>;
|
|
interrupt-parent = <&intc>;
|
|
@@ -44,15 +44,14 @@
|
|
};
|
|
|
|
uart0: serial@c0000000 {
|
|
- compatible = "snps,dw-apb-uart";
|
|
+ compatible = "ns8250";
|
|
reg = <0xc0000000 0x2000>;
|
|
interrupts = <11>;
|
|
- #clock-frequency = <80000000>;
|
|
clock-frequency = <3686400>;
|
|
baud = <115200>;
|
|
reg-shift = <2>;
|
|
reg-io-width = <4>;
|
|
- status = "okay";
|
|
+ no-loopback-test = <1>;
|
|
};
|
|
|
|
pgu0: pgu@c9000000 {
|
|
From 61fb4bfc010b0d2940f7fd87acbce6a0f03217cb Mon Sep 17 00:00:00 2001
|
|
From: Vineet Gupta <vgupta@synopsys.com>
|
|
Date: Sat, 5 Apr 2014 15:30:22 +0530
|
|
Subject: ARC: [nsimosci] Unbork console
|
|
|
|
From: Vineet Gupta <vgupta@synopsys.com>
|
|
|
|
commit 61fb4bfc010b0d2940f7fd87acbce6a0f03217cb upstream.
|
|
|
|
Despite the switch to right UART driver (prev patch), serial console
|
|
still doesn't work due to missing CONFIG_SERIAL_OF_PLATFORM
|
|
|
|
Also fix the default cmdline in DT to not refer to out-of-tree
|
|
ARC framebuffer driver for console.
|
|
|
|
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
|
|
Cc: Francois Bedard <Francois.Bedard@synopsys.com>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
arch/arc/boot/dts/nsimosci.dts | 5 ++++-
|
|
arch/arc/configs/nsimosci_defconfig | 1 +
|
|
2 files changed, 5 insertions(+), 1 deletion(-)
|
|
|
|
--- a/arch/arc/boot/dts/nsimosci.dts
|
|
+++ b/arch/arc/boot/dts/nsimosci.dts
|
|
@@ -17,7 +17,10 @@
|
|
interrupt-parent = <&intc>;
|
|
|
|
chosen {
|
|
- bootargs = "console=tty0 consoleblank=0";
|
|
+ /* this is for console on PGU */
|
|
+ /* bootargs = "console=tty0 consoleblank=0"; */
|
|
+ /* this is for console on serial */
|
|
+ bootargs = "earlycon=uart8250,mmio32,0xc0000000,115200n8 console=ttyS0,115200n8 consoleblank=0 debug";
|
|
};
|
|
|
|
aliases {
|
|
--- a/arch/arc/configs/nsimosci_defconfig
|
|
+++ b/arch/arc/configs/nsimosci_defconfig
|
|
@@ -54,6 +54,7 @@ CONFIG_SERIO_ARC_PS2=y
|
|
CONFIG_SERIAL_8250=y
|
|
CONFIG_SERIAL_8250_CONSOLE=y
|
|
CONFIG_SERIAL_8250_DW=y
|
|
+CONFIG_SERIAL_OF_PLATFORM=y
|
|
CONFIG_SERIAL_ARC=y
|
|
CONFIG_SERIAL_ARC_CONSOLE=y
|
|
# CONFIG_HW_RANDOM is not set
|
|
From 03b8c7b623c80af264c4c8d6111e5c6289933666 Mon Sep 17 00:00:00 2001
|
|
From: Heiko Carstens <heiko.carstens@de.ibm.com>
|
|
Date: Sun, 2 Mar 2014 13:09:47 +0100
|
|
Subject: futex: Allow architectures to skip futex_atomic_cmpxchg_inatomic() test
|
|
|
|
From: Heiko Carstens <heiko.carstens@de.ibm.com>
|
|
|
|
commit 03b8c7b623c80af264c4c8d6111e5c6289933666 upstream.
|
|
|
|
If an architecture has futex_atomic_cmpxchg_inatomic() implemented and there
|
|
is no runtime check necessary, allow to skip the test within futex_init().
|
|
|
|
This allows to get rid of some code which would always give the same result,
|
|
and also allows the compiler to optimize a couple of if statements away.
|
|
|
|
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
|
|
Cc: Finn Thain <fthain@telegraphics.com.au>
|
|
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
|
|
Link: http://lkml.kernel.org/r/20140302120947.GA3641@osiris
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
arch/s390/Kconfig | 1 +
|
|
include/linux/futex.h | 4 ++++
|
|
init/Kconfig | 7 +++++++
|
|
kernel/futex.c | 37 ++++++++++++++++++++++++-------------
|
|
4 files changed, 36 insertions(+), 13 deletions(-)
|
|
|
|
--- a/arch/s390/Kconfig
|
|
+++ b/arch/s390/Kconfig
|
|
@@ -117,6 +117,7 @@ config S390
|
|
select HAVE_FUNCTION_GRAPH_TRACER
|
|
select HAVE_FUNCTION_TRACER
|
|
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
|
|
+ select HAVE_FUTEX_CMPXCHG if FUTEX
|
|
select HAVE_KERNEL_BZIP2
|
|
select HAVE_KERNEL_GZIP
|
|
select HAVE_KERNEL_LZ4
|
|
--- a/include/linux/futex.h
|
|
+++ b/include/linux/futex.h
|
|
@@ -55,7 +55,11 @@ union futex_key {
|
|
#ifdef CONFIG_FUTEX
|
|
extern void exit_robust_list(struct task_struct *curr);
|
|
extern void exit_pi_state_list(struct task_struct *curr);
|
|
+#ifdef CONFIG_HAVE_FUTEX_CMPXCHG
|
|
+#define futex_cmpxchg_enabled 1
|
|
+#else
|
|
extern int futex_cmpxchg_enabled;
|
|
+#endif
|
|
#else
|
|
static inline void exit_robust_list(struct task_struct *curr)
|
|
{
|
|
--- a/init/Kconfig
|
|
+++ b/init/Kconfig
|
|
@@ -1387,6 +1387,13 @@ config FUTEX
|
|
support for "fast userspace mutexes". The resulting kernel may not
|
|
run glibc-based applications correctly.
|
|
|
|
+config HAVE_FUTEX_CMPXCHG
|
|
+ bool
|
|
+ help
|
|
+ Architectures should select this if futex_atomic_cmpxchg_inatomic()
|
|
+ is implemented and always working. This removes a couple of runtime
|
|
+ checks.
|
|
+
|
|
config EPOLL
|
|
bool "Enable eventpoll support" if EXPERT
|
|
default y
|
|
--- a/kernel/futex.c
|
|
+++ b/kernel/futex.c
|
|
@@ -157,7 +157,9 @@
|
|
* enqueue.
|
|
*/
|
|
|
|
+#ifndef CONFIG_HAVE_FUTEX_CMPXCHG
|
|
int __read_mostly futex_cmpxchg_enabled;
|
|
+#endif
|
|
|
|
/*
|
|
* Futex flags used to encode options to functions and preserve them across
|
|
@@ -2880,9 +2882,28 @@ SYSCALL_DEFINE6(futex, u32 __user *, uad
|
|
return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
|
|
}
|
|
|
|
-static int __init futex_init(void)
|
|
+static void __init futex_detect_cmpxchg(void)
|
|
{
|
|
+#ifndef CONFIG_HAVE_FUTEX_CMPXCHG
|
|
u32 curval;
|
|
+
|
|
+ /*
|
|
+ * This will fail and we want it. Some arch implementations do
|
|
+ * runtime detection of the futex_atomic_cmpxchg_inatomic()
|
|
+ * functionality. We want to know that before we call in any
|
|
+ * of the complex code paths. Also we want to prevent
|
|
+ * registration of robust lists in that case. NULL is
|
|
+ * guaranteed to fault and we get -EFAULT on functional
|
|
+ * implementation, the non-functional ones will return
|
|
+ * -ENOSYS.
|
|
+ */
|
|
+ if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT)
|
|
+ futex_cmpxchg_enabled = 1;
|
|
+#endif
|
|
+}
|
|
+
|
|
+static int __init futex_init(void)
|
|
+{
|
|
unsigned int futex_shift;
|
|
unsigned long i;
|
|
|
|
@@ -2898,18 +2919,8 @@ static int __init futex_init(void)
|
|
&futex_shift, NULL,
|
|
futex_hashsize, futex_hashsize);
|
|
futex_hashsize = 1UL << futex_shift;
|
|
- /*
|
|
- * This will fail and we want it. Some arch implementations do
|
|
- * runtime detection of the futex_atomic_cmpxchg_inatomic()
|
|
- * functionality. We want to know that before we call in any
|
|
- * of the complex code paths. Also we want to prevent
|
|
- * registration of robust lists in that case. NULL is
|
|
- * guaranteed to fault and we get -EFAULT on functional
|
|
- * implementation, the non-functional ones will return
|
|
- * -ENOSYS.
|
|
- */
|
|
- if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT)
|
|
- futex_cmpxchg_enabled = 1;
|
|
+
|
|
+ futex_detect_cmpxchg();
|
|
|
|
for (i = 0; i < futex_hashsize; i++) {
|
|
atomic_set(&futex_queues[i].waiters, 0);
|
|
From e571c58f313d35c56e0018470e3375ddd1fd320e Mon Sep 17 00:00:00 2001
|
|
From: Finn Thain <fthain@telegraphics.com.au>
|
|
Date: Thu, 6 Mar 2014 10:29:27 +1100
|
|
Subject: m68k: Skip futex_atomic_cmpxchg_inatomic() test
|
|
|
|
From: Finn Thain <fthain@telegraphics.com.au>
|
|
|
|
commit e571c58f313d35c56e0018470e3375ddd1fd320e upstream.
|
|
|
|
Skip the futex_atomic_cmpxchg_inatomic() test in futex_init(). It causes a
|
|
fatal exception on 68030 (and presumably 68020 also).
|
|
|
|
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
|
|
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
|
|
Link: http://lkml.kernel.org/r/alpine.LNX.2.00.1403061006440.5525@nippy.intranet
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
arch/m68k/Kconfig | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
--- a/arch/m68k/Kconfig
|
|
+++ b/arch/m68k/Kconfig
|
|
@@ -17,6 +17,7 @@ config M68K
|
|
select FPU if MMU
|
|
select ARCH_WANT_IPC_PARSE_VERSION
|
|
select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE
|
|
+ select HAVE_FUTEX_CMPXCHG if MMU && FUTEX
|
|
select HAVE_MOD_ARCH_SPECIFIC
|
|
select MODULES_USE_ELF_REL
|
|
select MODULES_USE_ELF_RELA
|
|
From 8ceee72808d1ae3fb191284afc2257a2be964725 Mon Sep 17 00:00:00 2001
|
|
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
|
Date: Thu, 27 Mar 2014 18:14:40 +0100
|
|
Subject: crypto: ghash-clmulni-intel - use C implementation for setkey()
|
|
|
|
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
|
|
|
commit 8ceee72808d1ae3fb191284afc2257a2be964725 upstream.
|
|
|
|
The GHASH setkey() function uses SSE registers but fails to call
|
|
kernel_fpu_begin()/kernel_fpu_end(). Instead of adding these calls, and
|
|
then having to deal with the restriction that they cannot be called from
|
|
interrupt context, move the setkey() implementation to the C domain.
|
|
|
|
Note that setkey() does not use any particular SSE features and is not
|
|
expected to become a performance bottleneck.
|
|
|
|
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
|
Acked-by: H. Peter Anvin <hpa@linux.intel.com>
|
|
Fixes: 0e1227d356e9b (crypto: ghash - Add PCLMULQDQ accelerated implementation)
|
|
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
arch/x86/crypto/ghash-clmulni-intel_asm.S | 29 -----------------------------
|
|
arch/x86/crypto/ghash-clmulni-intel_glue.c | 14 +++++++++++---
|
|
2 files changed, 11 insertions(+), 32 deletions(-)
|
|
|
|
--- a/arch/x86/crypto/ghash-clmulni-intel_asm.S
|
|
+++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S
|
|
@@ -24,10 +24,6 @@
|
|
.align 16
|
|
.Lbswap_mask:
|
|
.octa 0x000102030405060708090a0b0c0d0e0f
|
|
-.Lpoly:
|
|
- .octa 0xc2000000000000000000000000000001
|
|
-.Ltwo_one:
|
|
- .octa 0x00000001000000000000000000000001
|
|
|
|
#define DATA %xmm0
|
|
#define SHASH %xmm1
|
|
@@ -134,28 +130,3 @@ ENTRY(clmul_ghash_update)
|
|
.Lupdate_just_ret:
|
|
ret
|
|
ENDPROC(clmul_ghash_update)
|
|
-
|
|
-/*
|
|
- * void clmul_ghash_setkey(be128 *shash, const u8 *key);
|
|
- *
|
|
- * Calculate hash_key << 1 mod poly
|
|
- */
|
|
-ENTRY(clmul_ghash_setkey)
|
|
- movaps .Lbswap_mask, BSWAP
|
|
- movups (%rsi), %xmm0
|
|
- PSHUFB_XMM BSWAP %xmm0
|
|
- movaps %xmm0, %xmm1
|
|
- psllq $1, %xmm0
|
|
- psrlq $63, %xmm1
|
|
- movaps %xmm1, %xmm2
|
|
- pslldq $8, %xmm1
|
|
- psrldq $8, %xmm2
|
|
- por %xmm1, %xmm0
|
|
- # reduction
|
|
- pshufd $0b00100100, %xmm2, %xmm1
|
|
- pcmpeqd .Ltwo_one, %xmm1
|
|
- pand .Lpoly, %xmm1
|
|
- pxor %xmm1, %xmm0
|
|
- movups %xmm0, (%rdi)
|
|
- ret
|
|
-ENDPROC(clmul_ghash_setkey)
|
|
--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c
|
|
+++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
|
|
@@ -30,8 +30,6 @@ void clmul_ghash_mul(char *dst, const be
|
|
void clmul_ghash_update(char *dst, const char *src, unsigned int srclen,
|
|
const be128 *shash);
|
|
|
|
-void clmul_ghash_setkey(be128 *shash, const u8 *key);
|
|
-
|
|
struct ghash_async_ctx {
|
|
struct cryptd_ahash *cryptd_tfm;
|
|
};
|
|
@@ -58,13 +56,23 @@ static int ghash_setkey(struct crypto_sh
|
|
const u8 *key, unsigned int keylen)
|
|
{
|
|
struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
|
|
+ be128 *x = (be128 *)key;
|
|
+ u64 a, b;
|
|
|
|
if (keylen != GHASH_BLOCK_SIZE) {
|
|
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
|
return -EINVAL;
|
|
}
|
|
|
|
- clmul_ghash_setkey(&ctx->shash, key);
|
|
+ /* perform multiplication by 'x' in GF(2^128) */
|
|
+ a = be64_to_cpu(x->a);
|
|
+ b = be64_to_cpu(x->b);
|
|
+
|
|
+ ctx->shash.a = (__be64)((b << 1) | (a >> 63));
|
|
+ ctx->shash.b = (__be64)((a << 1) | (b >> 63));
|
|
+
|
|
+ if (a >> 63)
|
|
+ ctx->shash.b ^= cpu_to_be64(0xc2);
|
|
|
|
return 0;
|
|
}
|