Commit 45a1b8cc authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'x86_misc_for_7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull misc x86 updates from Dave Hansen:
 "The usual smattering of x86/misc changes.

  The IPv6 patch in here surprised me in a couple of ways. First, the
  function it inlines is able to eat a lot more CPU time than I would
  have expected. Second, the inlining does not seem to bloat the kernel,
  at least in the configs folks have tested.

   - Inline x86-specific IPv6 checksum helper

   - Update IOMMU docs to use stable identifiers

   - Print unhashed pointers on fatal stack overflows"

* tag 'x86_misc_for_7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/traps: Print unhashed pointers on stack overflow
  Documentation/x86: Update IOMMU spec references to use stable identifiers
  x86/lib: Inline csum_ipv6_magic()
parents 6f7e6393 6b32c935
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -2,10 +2,11 @@
x86 IOMMU Support
=================

The architecture specs can be obtained from the below locations.
The architecture specs can be obtained from the vendor websites.
Search for the following documents to obtain the latest versions:

- Intel: http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/vt-directed-io-spec.pdf
- AMD: https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/specifications/48882_3_07_PUB.pdf
- Intel: Intel Virtualization Technology for Directed I/O Architecture Specification (ID: D51397)
- AMD: AMD I/O Virtualization Technology (IOMMU) Specification (ID: 48882)

This guide gives a quick cheat sheet for some basic understanding.

+33 −12
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
 */

#include <linux/compiler.h>
#include <linux/in6.h>
#include <asm/byteorder.h>

/**
@@ -145,6 +146,17 @@ extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len);
 */
extern __sum16 ip_compute_csum(const void *buff, int len);

static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
	asm("addl %2,%0\n\t"
	    "adcl $0,%0"
	    : "=r" (a)
	    : "0" (a), "rm" (b));
	return a;
}

#define _HAVE_ARCH_IPV6_CSUM 1

/**
 * csum_ipv6_magic - Compute checksum of an IPv6 pseudo header.
 * @saddr: source address
@@ -158,20 +170,29 @@ extern __sum16 ip_compute_csum(const void *buff, int len);
 * Returns the unfolded 32bit checksum.
 */

struct in6_addr;
static inline __sum16 csum_ipv6_magic(
	const struct in6_addr *_saddr, const struct in6_addr *_daddr,
	__u32 len, __u8 proto, __wsum sum)
{
	const unsigned long *saddr = (const unsigned long *)_saddr;
	const unsigned long *daddr = (const unsigned long *)_daddr;
	__u64 sum64;

#define _HAVE_ARCH_IPV6_CSUM 1
extern __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
		__u32 len, __u8 proto, __wsum sum);
	sum64 = (__force __u64)htonl(len) + (__force __u64)htons(proto) +
		(__force __u64)sum;

static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
	asm("addl %2,%0\n\t"
	    "adcl $0,%0"
	    : "=r" (a)
	    : "0" (a), "rm" (b));
	return a;
	asm("	addq %1,%[sum64]\n"
	    "	adcq %2,%[sum64]\n"
	    "	adcq %3,%[sum64]\n"
	    "	adcq %4,%[sum64]\n"
	    "	adcq $0,%[sum64]\n"

	    : [sum64] "+r" (sum64)
	    : "m" (saddr[0]), "m" (saddr[1]),
	      "m" (daddr[0]), "m" (daddr[1]));

	return csum_fold(
	       (__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32));
}

#define HAVE_ARCH_CSUM_ADD
+1 −1
Original line number Diff line number Diff line
@@ -549,7 +549,7 @@ __visible void __noreturn handle_stack_overflow(struct pt_regs *regs,
{
	const char *name = stack_type_name(info->type);

	printk(KERN_EMERG "BUG: %s stack guard page was hit at %p (stack is %p..%p)\n",
	printk(KERN_EMERG "BUG: %s stack guard page was hit at %px (stack is %px..%px)\n",
	       name, (void *)fault_address, info->begin, info->end);

	die("stack guard page", regs, 0);
+0 −22
Original line number Diff line number Diff line
@@ -68,25 +68,3 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len)
}
EXPORT_SYMBOL(csum_partial_copy_nocheck);
__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
			const struct in6_addr *daddr,
			__u32 len, __u8 proto, __wsum sum)
{
	__u64 rest, sum64;

	rest = (__force __u64)htonl(len) + (__force __u64)htons(proto) +
		(__force __u64)sum;

	asm("	addq (%[saddr]),%[sum]\n"
	    "	adcq 8(%[saddr]),%[sum]\n"
	    "	adcq (%[daddr]),%[sum]\n"
	    "	adcq 8(%[daddr]),%[sum]\n"
	    "	adcq $0,%[sum]\n"

	    : [sum] "=r" (sum64)
	    : "[sum]" (rest), [saddr] "r" (saddr), [daddr] "r" (daddr));

	return csum_fold(
	       (__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32));
}
EXPORT_SYMBOL(csum_ipv6_magic);