--- /dev/null
+From a90b037583d5f1ae3e54e9c687c79df82d1d34a4 Mon Sep 17 00:00:00 2001
+From: Dirk Eibach <eibach@gdsys.de>
+Date: Thu, 18 Jun 2009 16:49:15 -0700
+Subject: char: moxa, prevent opening unavailable ports
+
+From: Dirk Eibach <eibach@gdsys.de>
+
+commit a90b037583d5f1ae3e54e9c687c79df82d1d34a4 upstream.
+
+In moxa.c there are 32 minor numbers reserved for each device. The number
+of ports actually available per device is stored in
+moxa_board_conf->numPorts. This number is not considered in moxa_open().
+Opening a port that is not available results in a kernel oops. This patch
+adds a test to moxa_open() that prevents opening unavailable ports.
+
+[akpm@linux-foundation.org: avoid multiple returns]
+Signed-off-by: Dirk Eibach <eibach@gdsys.de>
+Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/moxa.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/moxa.c
++++ b/drivers/char/moxa.c
+@@ -1184,6 +1184,11 @@ static int moxa_open(struct tty_struct *
+ return -ENODEV;
+ }
+
++ if (port % MAX_PORTS_PER_BOARD >= brd->numPorts) {
++ retval = -ENODEV;
++ goto out_unlock;
++ }
++
+ ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
+ ch->port.count++;
+ tty->driver_data = ch;
+@@ -1208,8 +1213,8 @@ static int moxa_open(struct tty_struct *
+ moxa_close_port(tty);
+ } else
+ ch->port.flags |= ASYNC_NORMAL_ACTIVE;
++out_unlock:
+ mutex_unlock(&moxa_openlock);
+-
+ return retval;
+ }
+
--- /dev/null
+From 7caf6a49bb17d0377210693af5737563b31aa5ee Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <joerg.roedel@amd.com>
+Date: Fri, 5 Jun 2009 12:01:35 +0200
+Subject: dma-debug: change hash_bucket_find from first-fit to best-fit
+
+From: Joerg Roedel <joerg.roedel@amd.com>
+
+commit 7caf6a49bb17d0377210693af5737563b31aa5ee upstream.
+
+Some device drivers map the same physical address multiple times to a
+dma address. Without an IOMMU this results in the same dma address being
+put into the dma-debug hash multiple times. With a first-fit match in
+hash_bucket_find() this function may return the wrong dma_debug_entry.
+
+This can result in false positive warnings. This patch fixes it by
+changing the first-fit behavior of hash_bucket_find() into a best-fit
+algorithm.
+
+Reported-by: Torsten Kaiser <just.for.lkml@googlemail.com>
+Reported-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
+Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
+Cc: lethal@linux-sh.org
+Cc: just.for.lkml@googlemail.com
+Cc: hancockrwd@gmail.com
+Cc: jens.axboe@oracle.com
+Cc: bharrosh@panasas.com
+Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+LKML-Reference: <20090605104132.GE24836@amd.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ lib/dma-debug.c | 43 +++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 39 insertions(+), 4 deletions(-)
+
+--- a/lib/dma-debug.c
++++ b/lib/dma-debug.c
+@@ -185,15 +185,50 @@ static void put_hash_bucket(struct hash_
+ static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket,
+ struct dma_debug_entry *ref)
+ {
+- struct dma_debug_entry *entry;
++ struct dma_debug_entry *entry, *ret = NULL;
++ int matches = 0, match_lvl, last_lvl = 0;
+
+ list_for_each_entry(entry, &bucket->list, list) {
+- if ((entry->dev_addr == ref->dev_addr) &&
+- (entry->dev == ref->dev))
++ if ((entry->dev_addr != ref->dev_addr) ||
++ (entry->dev != ref->dev))
++ continue;
++
++ /*
++ * Some drivers map the same physical address multiple
++ * times. Without a hardware IOMMU this results in the
++ * same device addresses being put into the dma-debug
++ * hash multiple times too. This can result in false
++ * positives being reported. Therfore we implement a
++ * best-fit algorithm here which returns the entry from
++ * the hash which fits best to the reference value
++ * instead of the first-fit.
++ */
++ matches += 1;
++ match_lvl = 0;
++ entry->size == ref->size ? ++match_lvl : match_lvl;
++ entry->type == ref->type ? ++match_lvl : match_lvl;
++ entry->direction == ref->direction ? ++match_lvl : match_lvl;
++
++ if (match_lvl == 3) {
++ /* perfect-fit - return the result */
+ return entry;
++ } else if (match_lvl > last_lvl) {
++ /*
++ * We found an entry that fits better then the
++ * previous one
++ */
++ last_lvl = match_lvl;
++ ret = entry;
++ }
+ }
+
+- return NULL;
++ /*
++ * If we have multiple matches but no perfect-fit, just return
++ * NULL.
++ */
++ ret = (matches == 1) ? ret : NULL;
++
++ return ret;
+ }
+
+ /*
--- /dev/null
+From c3301a5c04800bcf8afc8a815bf9e570a4e25a08 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jirislaby@gmail.com>
+Date: Thu, 11 Jun 2009 12:41:05 +0100
+Subject: epca: fix test_bit parameters
+
+From: Jiri Slaby <jirislaby@gmail.com>
+
+commit c3301a5c04800bcf8afc8a815bf9e570a4e25a08 upstream.
+
+Switch from ASYNC_* to ASYNCB_*, because test_bit expects
+bit number, not mask.
+
+Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/epca.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/char/epca.c
++++ b/drivers/char/epca.c
+@@ -1518,7 +1518,7 @@ static void doevent(int crd)
+ if (event & MODEMCHG_IND) {
+ /* A modem signal change has been indicated */
+ ch->imodem = mstat;
+- if (test_bit(ASYNC_CHECK_CD, &ch->port.flags)) {
++ if (test_bit(ASYNCB_CHECK_CD, &ch->port.flags)) {
+ /* We are now receiving dcd */
+ if (mstat & ch->dcd)
+ wake_up_interruptible(&ch->port.open_wait);
+@@ -1765,9 +1765,9 @@ static void epcaparam(struct tty_struct
+ * that the driver will wait on carrier detect.
+ */
+ if (ts->c_cflag & CLOCAL)
+- clear_bit(ASYNC_CHECK_CD, &ch->port.flags);
++ clear_bit(ASYNCB_CHECK_CD, &ch->port.flags);
+ else
+- set_bit(ASYNC_CHECK_CD, &ch->port.flags);
++ set_bit(ASYNCB_CHECK_CD, &ch->port.flags);
+ mval = ch->m_dtr | ch->m_rts;
+ } /* End CBAUD not detected */
+ iflag = termios2digi_i(ch, ts->c_iflag);
+@@ -2244,7 +2244,8 @@ static void do_softint(struct work_struc
+ if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
+ tty_hangup(tty);
+ wake_up_interruptible(&ch->port.open_wait);
+- clear_bit(ASYNC_NORMAL_ACTIVE, &ch->port.flags);
++ clear_bit(ASYNCB_NORMAL_ACTIVE,
++ &ch->port.flags);
+ }
+ }
+ tty_kref_put(tty);
--- /dev/null
+From a391ad0f09014856bbc4eeea309593eba977b3b0 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jirislaby@gmail.com>
+Date: Thu, 11 Jun 2009 12:40:17 +0100
+Subject: rocket: fix test_bit parameters
+
+From: Jiri Slaby <jirislaby@gmail.com>
+
+commit a391ad0f09014856bbc4eeea309593eba977b3b0 upstream.
+
+Switch from ASYNC_* to ASYNCB_*, because {test,set}_bit expect
+bit number, not mask.
+
+Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/rocket.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/char/rocket.c
++++ b/drivers/char/rocket.c
+@@ -934,7 +934,7 @@ static int rp_open(struct tty_struct *tt
+ /*
+ * Info->count is now 1; so it's safe to sleep now.
+ */
+- if (!test_bit(ASYNC_INITIALIZED, &port->flags)) {
++ if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+ cp = &info->channel;
+ sSetRxTrigger(cp, TRIG_1);
+ if (sGetChanStatus(cp) & CD_ACT)
+@@ -958,7 +958,7 @@ static int rp_open(struct tty_struct *tt
+ sEnRxFIFO(cp);
+ sEnTransmit(cp);
+
+- set_bit(ASYNC_INITIALIZED, &info->port.flags);
++ set_bit(ASYNCB_INITIALIZED, &info->port.flags);
+
+ /*
+ * Set up the tty->alt_speed kludge
+@@ -1641,7 +1641,7 @@ static int rp_write(struct tty_struct *t
+ /* Write remaining data into the port's xmit_buf */
+ while (1) {
+ /* Hung up ? */
+- if (!test_bit(ASYNC_NORMAL_ACTIVE, &info->port.flags))
++ if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
+ goto end;
+ c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
+ c = min(c, XMIT_BUF_SIZE - info->xmit_head);
--- /dev/null
+From 70beaed22cbe12979e55d99b370e147e2e168562 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jirislaby@gmail.com>
+Date: Thu, 11 Jun 2009 12:39:12 +0100
+Subject: serial: refactor ASYNC_ flags
+
+From: Jiri Slaby <jirislaby@gmail.com>
+
+commit 70beaed22cbe12979e55d99b370e147e2e168562 upstream.
+
+Define ASYNCB_* flags which are bit numbers of the ASYNC_* flags.
+This is useful for {test,set,clear}_bit.
+
+Also convert each ASYNC_% to be (1 << ASYNCB_%) and define masks
+with the macros, not constants.
+
+Tested with:
+#include "PATH_TO_KERNEL/include/linux/serial.h"
+static struct {
+ unsigned int new, old;
+} as[] = {
+ { ASYNC_HUP_NOTIFY, 0x0001 },
+ { ASYNC_FOURPORT, 0x0002 },
+...
+ { ASYNC_BOOT_ONLYMCA, 0x00400000 },
+ { ASYNC_INTERNAL_FLAGS, 0xFFC00000 }
+};
+...
+ for (a = 0; a < ARRAY_SIZE(as); a++)
+ if (as[a].old != as[a].new)
+ printf("%.8x != %.8x\n", as[a].old, as[a].new);
+
+Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/serial.h | 116 +++++++++++++++++++++++++++++--------------------
+ 1 file changed, 69 insertions(+), 47 deletions(-)
+
+--- a/include/linux/serial.h
++++ b/include/linux/serial.h
+@@ -96,54 +96,76 @@ struct serial_uart_config {
+
+ /*
+ * Definitions for async_struct (and serial_struct) flags field
++ *
++ * Define ASYNCB_* for convenient use with {test,set,clear}_bit.
+ */
+-#define ASYNC_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes
+- on the callout port */
+-#define ASYNC_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */
+-#define ASYNC_SAK 0x0004 /* Secure Attention Key (Orange book) */
+-#define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+-
+-#define ASYNC_SPD_MASK 0x1030
+-#define ASYNC_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */
+-
+-#define ASYNC_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */
+-#define ASYNC_SPD_CUST 0x0030 /* Use user-specified divisor */
+-
+-#define ASYNC_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */
+-#define ASYNC_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */
+-#define ASYNC_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+-#define ASYNC_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */
+-#define ASYNC_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */
+-
+-#define ASYNC_HARDPPS_CD 0x0800 /* Call hardpps when CD goes high */
+-
+-#define ASYNC_SPD_SHI 0x1000 /* Use 230400 instead of 38400 bps */
+-#define ASYNC_SPD_WARP 0x1010 /* Use 460800 instead of 38400 bps */
+-
+-#define ASYNC_LOW_LATENCY 0x2000 /* Request low latency behaviour */
+-
+-#define ASYNC_BUGGY_UART 0x4000 /* This is a buggy UART, skip some safety
+- * checks. Note: can be dangerous! */
+-
+-#define ASYNC_AUTOPROBE 0x8000 /* Port was autoprobed by PCI or PNP code */
+-
+-#define ASYNC_FLAGS 0x7FFF /* Possible legal async flags */
+-#define ASYNC_USR_MASK 0x3430 /* Legal flags that non-privileged
+- * users can set or reset */
+-
+-/* Internal flags used only by kernel/chr_drv/serial.c */
+-#define ASYNC_INITIALIZED 0x80000000 /* Serial port was initialized */
+-#define ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device is active */
+-#define ASYNC_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */
+-#define ASYNC_CLOSING 0x08000000 /* Serial port is closing */
+-#define ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */
+-#define ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */
+-#define ASYNC_SHARE_IRQ 0x01000000 /* for multifunction cards
+- --- no longer used */
+-#define ASYNC_CONS_FLOW 0x00800000 /* flow control for console */
+-
+-#define ASYNC_BOOT_ONLYMCA 0x00400000 /* Probe only if MCA bus */
+-#define ASYNC_INTERNAL_FLAGS 0xFFC00000 /* Internal flags */
++#define ASYNCB_HUP_NOTIFY 0 /* Notify getty on hangups and closes
++ * on the callout port */
++#define ASYNCB_FOURPORT 1 /* Set OU1, OUT2 per AST Fourport settings */
++#define ASYNCB_SAK 2 /* Secure Attention Key (Orange book) */
++#define ASYNCB_SPLIT_TERMIOS 3 /* Separate termios for dialin/callout */
++#define ASYNCB_SPD_HI 4 /* Use 56000 instead of 38400 bps */
++#define ASYNCB_SPD_VHI 5 /* Use 115200 instead of 38400 bps */
++#define ASYNCB_SKIP_TEST 6 /* Skip UART test during autoconfiguration */
++#define ASYNCB_AUTO_IRQ 7 /* Do automatic IRQ during
++ * autoconfiguration */
++#define ASYNCB_SESSION_LOCKOUT 8 /* Lock out cua opens based on session */
++#define ASYNCB_PGRP_LOCKOUT 9 /* Lock out cua opens based on pgrp */
++#define ASYNCB_CALLOUT_NOHUP 10 /* Don't do hangups for cua device */
++#define ASYNCB_HARDPPS_CD 11 /* Call hardpps when CD goes high */
++#define ASYNCB_SPD_SHI 12 /* Use 230400 instead of 38400 bps */
++#define ASYNCB_LOW_LATENCY 13 /* Request low latency behaviour */
++#define ASYNCB_BUGGY_UART 14 /* This is a buggy UART, skip some safety
++ * checks. Note: can be dangerous! */
++#define ASYNCB_AUTOPROBE 15 /* Port was autoprobed by PCI or PNP code */
++#define ASYNCB_LAST_USER 15
++
++/* Internal flags used only by kernel */
++#define ASYNCB_INITIALIZED 31 /* Serial port was initialized */
++#define ASYNCB_NORMAL_ACTIVE 29 /* Normal device is active */
++#define ASYNCB_BOOT_AUTOCONF 28 /* Autoconfigure port on bootup */
++#define ASYNCB_CLOSING 27 /* Serial port is closing */
++#define ASYNCB_CTS_FLOW 26 /* Do CTS flow control */
++#define ASYNCB_CHECK_CD 25 /* i.e., CLOCAL */
++#define ASYNCB_SHARE_IRQ 24 /* for multifunction cards, no longer used */
++#define ASYNCB_CONS_FLOW 23 /* flow control for console */
++#define ASYNCB_BOOT_ONLYMCA 22 /* Probe only if MCA bus */
++#define ASYNCB_FIRST_KERNEL 22
++
++#define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY)
++#define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT)
++#define ASYNC_SAK (1U << ASYNCB_SAK)
++#define ASYNC_SPLIT_TERMIOS (1U << ASYNCB_SPLIT_TERMIOS)
++#define ASYNC_SPD_HI (1U << ASYNCB_SPD_HI)
++#define ASYNC_SPD_VHI (1U << ASYNCB_SPD_VHI)
++#define ASYNC_SKIP_TEST (1U << ASYNCB_SKIP_TEST)
++#define ASYNC_AUTO_IRQ (1U << ASYNCB_AUTO_IRQ)
++#define ASYNC_SESSION_LOCKOUT (1U << ASYNCB_SESSION_LOCKOUT)
++#define ASYNC_PGRP_LOCKOUT (1U << ASYNCB_PGRP_LOCKOUT)
++#define ASYNC_CALLOUT_NOHUP (1U << ASYNCB_CALLOUT_NOHUP)
++#define ASYNC_HARDPPS_CD (1U << ASYNCB_HARDPPS_CD)
++#define ASYNC_SPD_SHI (1U << ASYNCB_SPD_SHI)
++#define ASYNC_LOW_LATENCY (1U << ASYNCB_LOW_LATENCY)
++#define ASYNC_BUGGY_UART (1U << ASYNCB_BUGGY_UART)
++#define ASYNC_AUTOPROBE (1U << ASYNCB_AUTOPROBE)
++
++#define ASYNC_FLAGS ((1U << ASYNCB_LAST_USER) - 1)
++#define ASYNC_USR_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI| \
++ ASYNC_CALLOUT_NOHUP|ASYNC_SPD_SHI|ASYNC_LOW_LATENCY)
++#define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI)
++#define ASYNC_SPD_WARP (ASYNC_SPD_HI|ASYNC_SPD_SHI)
++#define ASYNC_SPD_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI)
++
++#define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED)
++#define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE)
++#define ASYNC_BOOT_AUTOCONF (1U << ASYNCB_BOOT_AUTOCONF)
++#define ASYNC_CLOSING (1U << ASYNCB_CLOSING)
++#define ASYNC_CTS_FLOW (1U << ASYNCB_CTS_FLOW)
++#define ASYNC_CHECK_CD (1U << ASYNCB_CHECK_CD)
++#define ASYNC_SHARE_IRQ (1U << ASYNCB_SHARE_IRQ)
++#define ASYNC_CONS_FLOW (1U << ASYNCB_CONS_FLOW)
++#define ASYNC_BOOT_ONLYMCA (1U << ASYNCB_BOOT_ONLYMCA)
++#define ASYNC_INTERNAL_FLAGS (~((1U << ASYNCB_FIRST_KERNEL) - 1))
+
+ /*
+ * Multiport serial configuration structure --- external structure
via-velocity-fix-velocity-driver-unmapping-incorrect-size.patch
x25-fix-sleep-from-timer-on-socket-destroy.patch
bonding-fix-multiple-module-load-problem.patch
+dma-debug-change-hash_bucket_find-from-first-fit-to-best-fit.patch
+char-moxa-prevent-opening-unavailable-ports.patch
+serial-refactor-async_-flags.patch
+rocket-fix-test_bit-parameters.patch
+epca-fix-test_bit-parameters.patch
+x86-detect-use-of-extended-apic-id-for-amd-cpus.patch
--- /dev/null
+From 42937e81a82b6bbc51a309c83da140b3a7ca5945 Mon Sep 17 00:00:00 2001
+From: Andreas Herrmann <andreas.herrmann3@amd.com>
+Date: Mon, 8 Jun 2009 15:55:09 +0200
+Subject: x86: Detect use of extended APIC ID for AMD CPUs
+
+From: Andreas Herrmann <andreas.herrmann3@amd.com>
+
+commit 42937e81a82b6bbc51a309c83da140b3a7ca5945 upstream.
+
+Booting a 32-bit kernel on Magny-Cours results in the following panic:
+
+ ...
+ Using APIC driver default
+ ...
+ Overriding APIC driver with bigsmp
+ ...
+ Getting VERSION: 80050010
+ Getting VERSION: 80050010
+ Getting ID: 10000000
+ Getting ID: ef000000
+ Getting LVT0: 700
+ Getting LVT1: 10000
+ Kernel panic - not syncing: Boot APIC ID in local APIC unexpected (16 vs 0)
+ Pid: 1, comm: swapper Not tainted 2.6.30-rcX #2
+ Call Trace:
+ [<c05194da>] ? panic+0x38/0xd3
+ [<c0743102>] ? native_smp_prepare_cpus+0x259/0x31f
+ [<c073b19d>] ? kernel_init+0x3e/0x141
+ [<c073b15f>] ? kernel_init+0x0/0x141
+ [<c020325f>] ? kernel_thread_helper+0x7/0x10
+
+The reason is that default_get_apic_id handled extension of local APIC
+ID field just in case of XAPIC.
+
+Thus for this AMD CPU, default_get_apic_id() returns 0 and
+bigsmp_get_apic_id() returns 16 which leads to the respective kernel
+panic.
+
+This patch introduces a Linux specific feature flag to indicate
+support for extended APIC id (8 bits instead of 4 bits width) and sets
+the flag on AMD CPUs if applicable.
+
+Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
+LKML-Reference: <20090608135509.GA12431@alberich.amd.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/include/asm/apic.h | 2 +-
+ arch/x86/include/asm/cpufeature.h | 1 +
+ arch/x86/kernel/cpu/amd.c | 10 ++++++++++
+ 3 files changed, 12 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/apic.h
++++ b/arch/x86/include/asm/apic.h
+@@ -410,7 +410,7 @@ static inline unsigned default_get_apic_
+ {
+ unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
+
+- if (APIC_XAPIC(ver))
++ if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
+ return (x >> 24) & 0xFF;
+ else
+ return (x >> 24) & 0x0F;
+--- a/arch/x86/include/asm/cpufeature.h
++++ b/arch/x86/include/asm/cpufeature.h
+@@ -94,6 +94,7 @@
+ #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */
+ #define X86_FEATURE_NONSTOP_TSC (3*32+24) /* TSC does not stop in C states */
+ #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */
++#define X86_FEATURE_EXTD_APICID (3*32+26) /* has extended APICID (8 bits) */
+
+ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+ #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -6,6 +6,7 @@
+ #include <asm/processor.h>
+ #include <asm/apic.h>
+ #include <asm/cpu.h>
++#include <asm/pci-direct.h>
+
+ #ifdef CONFIG_X86_64
+ # include <asm/numa_64.h>
+@@ -351,6 +352,15 @@ static void __cpuinit early_init_amd(str
+ (c->x86_model == 8 && c->x86_mask >= 8))
+ set_cpu_cap(c, X86_FEATURE_K6_MTRR);
+ #endif
++#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
++ /* check CPU config space for extended APIC ID */
++ if (c->x86 >= 0xf) {
++ unsigned int val;
++ val = read_pci_config(0, 24, 0, 0x68);
++ if ((val & ((1 << 17) | (1 << 18))) == ((1 << 17) | (1 << 18)))
++ set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
++ }
++#endif
+ }
+
+ static void __cpuinit init_amd(struct cpuinfo_x86 *c)