]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.26 patches added
authorGreg Kroah-Hartman <gregkh@suse.de>
Sat, 16 Aug 2008 23:52:03 +0000 (16:52 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sat, 16 Aug 2008 23:52:03 +0000 (16:52 -0700)
17 files changed:
queue-2.6.26/alsa-asoc-fix-sndctl_dsp_sync-support-in-freescale-8610-sound-drivers.patch [new file with mode: 0644]
queue-2.6.26/alsa-asoc-restrict-sample-rate-and-size-in-freescale-mpc8610-sound-drivers.patch [new file with mode: 0644]
queue-2.6.26/cifs-fix-compiler-warning-on-64-bit.patch [new file with mode: 0644]
queue-2.6.26/cs5520-add-enablebits-checking.patch [new file with mode: 0644]
queue-2.6.26/i2c-fix-null-pointer-dereference-in-i2c_new_probed_device.patch [new file with mode: 0644]
queue-2.6.26/i2c-let-users-select-algorithm-drivers-manually-again.patch [new file with mode: 0644]
queue-2.6.26/ide-it821x-in-pass-through-mode-segfaults-in-2.6.26-stable.patch [new file with mode: 0644]
queue-2.6.26/kvm-avoid-instruction-emulation-when-event-delivery-is-pending.patch [new file with mode: 0644]
queue-2.6.26/kvm-ia64-fix-irq-disabling-leak-in-error-handling-code.patch [new file with mode: 0644]
queue-2.6.26/kvm-task-switch-segment-base-is-linear-address.patch [new file with mode: 0644]
queue-2.6.26/kvm-task-switch-translate-guest-segment-limit-to-virt-extension-byte-granular-field.patch [new file with mode: 0644]
queue-2.6.26/kvm-task-switch-use-seg-regs-provided-by-subarch-instead-of-reading-from-gdt.patch [new file with mode: 0644]
queue-2.6.26/r8169-avoid-thrashing-pci-conf-space-above-rtl_giga_mac_ver_06.patch [new file with mode: 0644]
queue-2.6.26/radeon-misc-corrections.patch [new file with mode: 0644]
queue-2.6.26/rtl8187-fix-lockups-due-to-concurrent-access-to-config-routine.patch [new file with mode: 0644]
queue-2.6.26/series
queue-2.6.26/x86-amd-opteron-tom2-mask-val-fix.patch [new file with mode: 0644]

diff --git a/queue-2.6.26/alsa-asoc-fix-sndctl_dsp_sync-support-in-freescale-8610-sound-drivers.patch b/queue-2.6.26/alsa-asoc-fix-sndctl_dsp_sync-support-in-freescale-8610-sound-drivers.patch
new file mode 100644 (file)
index 0000000..39db78c
--- /dev/null
@@ -0,0 +1,327 @@
+From stable-bounces@linux.kernel.org Tue Aug 12 08:45:39 2008
+From: Timur Tabi <timur@freescale.com>
+Date: Tue, 12 Aug 2008 17:11:11 +0200
+Subject: ALSA: ASoC: fix SNDCTL_DSP_SYNC support in Freescale 8610 sound drivers
+To: stable@kernel.org
+Cc: Timur Tabi <timur@freescale.com>
+Message-ID: <s5hk5emjmk0.wl%tiwai@suse.de>
+
+From: Timur Tabi <timur@freescale.com>
+
+Upstream-commit-id: bf9c8c9ddef7ef761ae9747349175adad0ef16ce
+
+If an OSS application calls SNDCTL_DSP_SYNC, then ALSA will call the driver's
+_hw_params and _prepare functions again.  On the Freescale MPC8610 DMA ASoC
+driver, this caused the DMA controller to be unneccessarily re-programmed, and
+apparently it doesn't like that.  The DMA will then not operate when
+instructed.  This patch relocates much of the DMA programming to
+fsl_dma_open(), which is called only once.
+
+Signed-off-by: Timur Tabi <timur@freescale.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/soc/fsl/fsl_dma.c |  235 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 124 insertions(+), 111 deletions(-)
+
+--- a/sound/soc/fsl/fsl_dma.c
++++ b/sound/soc/fsl/fsl_dma.c
+@@ -327,14 +327,75 @@ static int fsl_dma_new(struct snd_card *
+  * fsl_dma_open: open a new substream.
+  *
+  * Each substream has its own DMA buffer.
++ *
++ * ALSA divides the DMA buffer into N periods.  We create NUM_DMA_LINKS link
++ * descriptors that ping-pong from one period to the next.  For example, if
++ * there are six periods and two link descriptors, this is how they look
++ * before playback starts:
++ *
++ *               The last link descriptor
++ *   ____________  points back to the first
++ *  |          |
++ *  V          |
++ *  ___    ___   |
++ * |   |->|   |->|
++ * |___|  |___|
++ *   |      |
++ *   |      |
++ *   V      V
++ *  _________________________________________
++ * |      |      |      |      |      |      |  The DMA buffer is
++ * |      |      |      |      |      |      |    divided into 6 parts
++ * |______|______|______|______|______|______|
++ *
++ * and here's how they look after the first period is finished playing:
++ *
++ *   ____________
++ *  |          |
++ *  V          |
++ *  ___    ___   |
++ * |   |->|   |->|
++ * |___|  |___|
++ *   |      |
++ *   |______________
++ *          |       |
++ *          V       V
++ *  _________________________________________
++ * |      |      |      |      |      |      |
++ * |      |      |      |      |      |      |
++ * |______|______|______|______|______|______|
++ *
++ * The first link descriptor now points to the third period.  The DMA
++ * controller is currently playing the second period.  When it finishes, it
++ * will jump back to the first descriptor and play the third period.
++ *
++ * There are four reasons we do this:
++ *
++ * 1. The only way to get the DMA controller to automatically restart the
++ *    transfer when it gets to the end of the buffer is to use chaining
++ *    mode.  Basic direct mode doesn't offer that feature.
++ * 2. We need to receive an interrupt at the end of every period.  The DMA
++ *    controller can generate an interrupt at the end of every link transfer
++ *    (aka segment).  Making each period into a DMA segment will give us the
++ *    interrupts we need.
++ * 3. By creating only two link descriptors, regardless of the number of
++ *    periods, we do not need to reallocate the link descriptors if the
++ *    number of periods changes.
++ * 4. All of the audio data is still stored in a single, contiguous DMA
++ *    buffer, which is what ALSA expects.  We're just dividing it into
++ *    contiguous parts, and creating a link descriptor for each one.
+  */
+ static int fsl_dma_open(struct snd_pcm_substream *substream)
+ {
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct fsl_dma_private *dma_private;
++      struct ccsr_dma_channel __iomem *dma_channel;
+       dma_addr_t ld_buf_phys;
++      u64 temp_link;          /* Pointer to next link descriptor */
++      u32 mr;
+       unsigned int channel;
+       int ret = 0;
++      unsigned int i;
+       /*
+        * Reject any DMA buffer whose size is not a multiple of the period
+@@ -395,68 +456,74 @@ static int fsl_dma_open(struct snd_pcm_s
+       snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware);
+       runtime->private_data = dma_private;
++      /* Program the fixed DMA controller parameters */
++
++      dma_channel = dma_private->dma_channel;
++
++      temp_link = dma_private->ld_buf_phys +
++              sizeof(struct fsl_dma_link_descriptor);
++
++      for (i = 0; i < NUM_DMA_LINKS; i++) {
++              struct fsl_dma_link_descriptor *link = &dma_private->link[i];
++
++              link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
++              link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
++              link->next = cpu_to_be64(temp_link);
++
++              temp_link += sizeof(struct fsl_dma_link_descriptor);
++      }
++      /* The last link descriptor points to the first */
++      dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys);
++
++      /* Tell the DMA controller where the first link descriptor is */
++      out_be32(&dma_channel->clndar,
++              CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys));
++      out_be32(&dma_channel->eclndar,
++              CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys));
++
++      /* The manual says the BCR must be clear before enabling EMP */
++      out_be32(&dma_channel->bcr, 0);
++
++      /*
++       * Program the mode register for interrupts, external master control,
++       * and source/destination hold.  Also clear the Channel Abort bit.
++       */
++      mr = in_be32(&dma_channel->mr) &
++              ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE);
++
++      /*
++       * We want External Master Start and External Master Pause enabled,
++       * because the SSI is controlling the DMA controller.  We want the DMA
++       * controller to be set up in advance, and then we signal only the SSI
++       * to start transferring.
++       *
++       * We want End-Of-Segment Interrupts enabled, because this will generate
++       * an interrupt at the end of each segment (each link descriptor
++       * represents one segment).  Each DMA segment is the same thing as an
++       * ALSA period, so this is how we get an interrupt at the end of every
++       * period.
++       *
++       * We want Error Interrupt enabled, so that we can get an error if
++       * the DMA controller is mis-programmed somehow.
++       */
++      mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN |
++              CCSR_DMA_MR_EMS_EN;
++
++      /* For playback, we want the destination address to be held.  For
++         capture, set the source address to be held. */
++      mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
++              CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE;
++
++      out_be32(&dma_channel->mr, mr);
++
+       return 0;
+ }
+ /**
+- * fsl_dma_hw_params: allocate the DMA buffer and the DMA link descriptors.
+- *
+- * ALSA divides the DMA buffer into N periods.  We create NUM_DMA_LINKS link
+- * descriptors that ping-pong from one period to the next.  For example, if
+- * there are six periods and two link descriptors, this is how they look
+- * before playback starts:
+- *
+- *               The last link descriptor
+- *   ____________  points back to the first
+- *  |          |
+- *  V          |
+- *  ___    ___   |
+- * |   |->|   |->|
+- * |___|  |___|
+- *   |      |
+- *   |      |
+- *   V      V
+- *  _________________________________________
+- * |      |      |      |      |      |      |  The DMA buffer is
+- * |      |      |      |      |      |      |    divided into 6 parts
+- * |______|______|______|______|______|______|
+- *
+- * and here's how they look after the first period is finished playing:
+- *
+- *   ____________
+- *  |          |
+- *  V          |
+- *  ___    ___   |
+- * |   |->|   |->|
+- * |___|  |___|
+- *   |      |
+- *   |______________
+- *          |       |
+- *          V       V
+- *  _________________________________________
+- * |      |      |      |      |      |      |
+- * |      |      |      |      |      |      |
+- * |______|______|______|______|______|______|
++ * fsl_dma_hw_params: continue initializing the DMA links
+  *
+- * The first link descriptor now points to the third period.  The DMA
+- * controller is currently playing the second period.  When it finishes, it
+- * will jump back to the first descriptor and play the third period.
+- *
+- * There are four reasons we do this:
+- *
+- * 1. The only way to get the DMA controller to automatically restart the
+- *    transfer when it gets to the end of the buffer is to use chaining
+- *    mode.  Basic direct mode doesn't offer that feature.
+- * 2. We need to receive an interrupt at the end of every period.  The DMA
+- *    controller can generate an interrupt at the end of every link transfer
+- *    (aka segment).  Making each period into a DMA segment will give us the
+- *    interrupts we need.
+- * 3. By creating only two link descriptors, regardless of the number of
+- *    periods, we do not need to reallocate the link descriptors if the
+- *    number of periods changes.
+- * 4. All of the audio data is still stored in a single, contiguous DMA
+- *    buffer, which is what ALSA expects.  We're just dividing it into
+- *    contiguous parts, and creating a link descriptor for each one.
++ * This function obtains hardware parameters about the opened stream and
++ * programs the DMA controller accordingly.
+  *
+  * Note that due to a quirk of the SSI's STX register, the target address
+  * for the DMA operations depends on the sample size.  So we don't program
+@@ -468,11 +535,8 @@ static int fsl_dma_hw_params(struct snd_
+ {
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct fsl_dma_private *dma_private = runtime->private_data;
+-      struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
+       dma_addr_t temp_addr;   /* Pointer to next period */
+-      u64 temp_link;          /* Pointer to next link descriptor */
+-      u32 mr;                 /* Temporary variable for MR register */
+       unsigned int i;
+@@ -490,8 +554,6 @@ static int fsl_dma_hw_params(struct snd_
+               dma_private->dma_buf_next = dma_private->dma_buf_phys;
+       /*
+-       * Initialize each link descriptor.
+-       *
+        * The actual address in STX0 (destination for playback, source for
+        * capture) is based on the sample size, but we don't know the sample
+        * size in this function, so we'll have to adjust that later.  See
+@@ -507,16 +569,11 @@ static int fsl_dma_hw_params(struct snd_
+        * buffer itself.
+        */
+       temp_addr = substream->dma_buffer.addr;
+-      temp_link = dma_private->ld_buf_phys +
+-              sizeof(struct fsl_dma_link_descriptor);
+       for (i = 0; i < NUM_DMA_LINKS; i++) {
+               struct fsl_dma_link_descriptor *link = &dma_private->link[i];
+               link->count = cpu_to_be32(period_size);
+-              link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
+-              link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
+-              link->next = cpu_to_be64(temp_link);
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       link->source_addr = cpu_to_be32(temp_addr);
+@@ -524,51 +581,7 @@ static int fsl_dma_hw_params(struct snd_
+                       link->dest_addr = cpu_to_be32(temp_addr);
+               temp_addr += period_size;
+-              temp_link += sizeof(struct fsl_dma_link_descriptor);
+       }
+-      /* The last link descriptor points to the first */
+-      dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys);
+-
+-      /* Tell the DMA controller where the first link descriptor is */
+-      out_be32(&dma_channel->clndar,
+-              CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys));
+-      out_be32(&dma_channel->eclndar,
+-              CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys));
+-
+-      /* The manual says the BCR must be clear before enabling EMP */
+-      out_be32(&dma_channel->bcr, 0);
+-
+-      /*
+-       * Program the mode register for interrupts, external master control,
+-       * and source/destination hold.  Also clear the Channel Abort bit.
+-       */
+-      mr = in_be32(&dma_channel->mr) &
+-              ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE);
+-
+-      /*
+-       * We want External Master Start and External Master Pause enabled,
+-       * because the SSI is controlling the DMA controller.  We want the DMA
+-       * controller to be set up in advance, and then we signal only the SSI
+-       * to start transfering.
+-       *
+-       * We want End-Of-Segment Interrupts enabled, because this will generate
+-       * an interrupt at the end of each segment (each link descriptor
+-       * represents one segment).  Each DMA segment is the same thing as an
+-       * ALSA period, so this is how we get an interrupt at the end of every
+-       * period.
+-       *
+-       * We want Error Interrupt enabled, so that we can get an error if
+-       * the DMA controller is mis-programmed somehow.
+-       */
+-      mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN |
+-              CCSR_DMA_MR_EMS_EN;
+-
+-      /* For playback, we want the destination address to be held.  For
+-         capture, set the source address to be held. */
+-      mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+-              CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE;
+-
+-      out_be32(&dma_channel->mr, mr);
+       return 0;
+ }
diff --git a/queue-2.6.26/alsa-asoc-restrict-sample-rate-and-size-in-freescale-mpc8610-sound-drivers.patch b/queue-2.6.26/alsa-asoc-restrict-sample-rate-and-size-in-freescale-mpc8610-sound-drivers.patch
new file mode 100644 (file)
index 0000000..f4fb348
--- /dev/null
@@ -0,0 +1,181 @@
+From stable-bounces@linux.kernel.org Tue Aug 12 09:25:40 2008
+From: Timur Tabi <timur@freescale.com>
+Date: Tue, 12 Aug 2008 17:09:25 +0200
+Subject: ALSA: asoc: restrict sample rate and size in Freescale MPC8610 sound drivers
+To: stable@kernel.org
+Cc: Timur Tabi <timur@freescale.com>
+Message-ID: <s5hljz2jmmy.wl%tiwai@suse.de>
+
+
+From: Timur Tabi <timur@freescale.com>
+
+Upstream-commid-id: be41e941d5f1a48bde7f44d09d56e8d2605f98e1
+
+The Freescale MPC8610 SSI device has the option of using one clock for both
+transmit and receive (synchronous mode), or independent clocks (asynchronous).
+The SSI driver, however, programs the SSI into synchronous mode and then
+tries to program the clock registers independently.  The result is that the wrong
+sample size is usually generated during recording.
+
+This patch fixes the discrepancy by restricting the sample rate and sample size
+of the playback and capture streams.  The SSI driver remembers which stream
+is opened first.  When a second stream is opened, that stream is constrained
+to the same sample rate and size as the first stream.
+
+A future version of this driver will lift the sample size restriction.
+Supporting independent sample rates is more difficult, because only certain
+codecs provide dual independent clocks.
+
+Signed-off-by: Timur Tabi <timur@freescale.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/soc/fsl/fsl_dma.c |    7 +++-
+ sound/soc/fsl/fsl_ssi.c |   74 +++++++++++++++++++++++++++++++++++++++++-------
+ 2 files changed, 70 insertions(+), 11 deletions(-)
+
+--- a/sound/soc/fsl/fsl_dma.c
++++ b/sound/soc/fsl/fsl_dma.c
+@@ -132,12 +132,17 @@ struct fsl_dma_private {
+  * Since each link descriptor has a 32-bit byte count field, we set
+  * period_bytes_max to the largest 32-bit number.  We also have no maximum
+  * number of periods.
++ *
++ * Note that we specify SNDRV_PCM_INFO_JOINT_DUPLEX here, but only because a
++ * limitation in the SSI driver requires the sample rates for playback and
++ * capture to be the same.
+  */
+ static const struct snd_pcm_hardware fsl_dma_hardware = {
+       .info                   = SNDRV_PCM_INFO_INTERLEAVED |
+                                 SNDRV_PCM_INFO_MMAP |
+-                                SNDRV_PCM_INFO_MMAP_VALID,
++                                SNDRV_PCM_INFO_MMAP_VALID |
++                                SNDRV_PCM_INFO_JOINT_DUPLEX,
+       .formats                = FSLDMA_PCM_FORMATS,
+       .rates                  = FSLDMA_PCM_RATES,
+       .rate_min               = 5512,
+--- a/sound/soc/fsl/fsl_ssi.c
++++ b/sound/soc/fsl/fsl_ssi.c
+@@ -67,6 +67,8 @@
+  * @ssi: pointer to the SSI's registers
+  * @ssi_phys: physical address of the SSI registers
+  * @irq: IRQ of this SSI
++ * @first_stream: pointer to the stream that was opened first
++ * @second_stream: pointer to second stream
+  * @dev: struct device pointer
+  * @playback: the number of playback streams opened
+  * @capture: the number of capture streams opened
+@@ -79,6 +81,8 @@ struct fsl_ssi_private {
+       struct ccsr_ssi __iomem *ssi;
+       dma_addr_t ssi_phys;
+       unsigned int irq;
++      struct snd_pcm_substream *first_stream;
++      struct snd_pcm_substream *second_stream;
+       struct device *dev;
+       unsigned int playback;
+       unsigned int capture;
+@@ -342,6 +346,49 @@ static int fsl_ssi_startup(struct snd_pc
+                */
+       }
++      if (!ssi_private->first_stream)
++              ssi_private->first_stream = substream;
++      else {
++              /* This is the second stream open, so we need to impose sample
++               * rate and maybe sample size constraints.  Note that this can
++               * cause a race condition if the second stream is opened before
++               * the first stream is fully initialized.
++               *
++               * We provide some protection by checking to make sure the first
++               * stream is initialized, but it's not perfect.  ALSA sometimes
++               * re-initializes the driver with a different sample rate or
++               * size.  If the second stream is opened before the first stream
++               * has received its final parameters, then the second stream may
++               * be constrained to the wrong sample rate or size.
++               *
++               * FIXME: This code does not handle opening and closing streams
++               * repeatedly.  If you open two streams and then close the first
++               * one, you may not be able to open another stream until you
++               * close the second one as well.
++               */
++              struct snd_pcm_runtime *first_runtime =
++                      ssi_private->first_stream->runtime;
++
++              if (!first_runtime->rate || !first_runtime->sample_bits) {
++                      dev_err(substream->pcm->card->dev,
++                              "set sample rate and size in %s stream first\n",
++                              substream->stream == SNDRV_PCM_STREAM_PLAYBACK
++                              ? "capture" : "playback");
++                      return -EAGAIN;
++              }
++
++              snd_pcm_hw_constraint_minmax(substream->runtime,
++                      SNDRV_PCM_HW_PARAM_RATE,
++                      first_runtime->rate, first_runtime->rate);
++
++              snd_pcm_hw_constraint_minmax(substream->runtime,
++                      SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
++                      first_runtime->sample_bits,
++                      first_runtime->sample_bits);
++
++              ssi_private->second_stream = substream;
++      }
++
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               ssi_private->playback++;
+@@ -371,18 +418,16 @@ static int fsl_ssi_prepare(struct snd_pc
+       struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
+       struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+-      u32 wl;
+-      wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format));
++      if (substream == ssi_private->first_stream) {
++              u32 wl;
+-      clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
++              /* The SSI should always be disabled at this points (SSIEN=0) */
++              wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format));
+-      if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++              /* In synchronous mode, the SSI uses STCCR for capture */
+               clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
+-      else
+-              clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
+-
+-      setbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
++      }
+       return 0;
+ }
+@@ -407,9 +452,13 @@ static int fsl_ssi_trigger(struct snd_pc
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+-                      setbits32(&ssi->scr, CCSR_SSI_SCR_TE);
++                      clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
++                      setbits32(&ssi->scr,
++                              CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
+               } else {
+-                      setbits32(&ssi->scr, CCSR_SSI_SCR_RE);
++                      clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
++                      setbits32(&ssi->scr,
++                              CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
+                       /*
+                        * I think we need this delay to allow time for the SSI
+@@ -452,6 +501,11 @@ static void fsl_ssi_shutdown(struct snd_
+       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+               ssi_private->capture--;
++      if (ssi_private->first_stream == substream)
++              ssi_private->first_stream = ssi_private->second_stream;
++
++      ssi_private->second_stream = NULL;
++
+       /*
+        * If this is the last active substream, disable the SSI and release
+        * the IRQ.
diff --git a/queue-2.6.26/cifs-fix-compiler-warning-on-64-bit.patch b/queue-2.6.26/cifs-fix-compiler-warning-on-64-bit.patch
new file mode 100644 (file)
index 0000000..80ada00
--- /dev/null
@@ -0,0 +1,29 @@
+From 04e1e0cccade330ab3715ce59234f7e3b087e246 Mon Sep 17 00:00:00 2001
+From: Jan Beulich <jbeulich@novell.com>
+Date: Tue, 22 Jul 2008 13:04:18 +0000
+Subject: CIFS: Fix compiler warning on 64-bit
+Message-ID: <489B8E32.3030703@redhat.com>
+
+From: Jan Beulich <jbeulich@novell.com>
+
+commit 04e1e0cccade330ab3715ce59234f7e3b087e246 upstream.
+
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Cc: Eugene Teo <eteo@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/cifs/asn1.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/asn1.c
++++ b/fs/cifs/asn1.c
+@@ -400,7 +400,7 @@ asn1_oid_decode(struct asn1_ctx *ctx,
+       size = eoc - ctx->pointer + 1;
+       /* first subid actually encodes first two subids */
+-      if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
++      if (size < 2 || size > UINT_MAX/sizeof(unsigned long))
+               return 0;
+       *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
diff --git a/queue-2.6.26/cs5520-add-enablebits-checking.patch b/queue-2.6.26/cs5520-add-enablebits-checking.patch
new file mode 100644 (file)
index 0000000..c2d8cf4
--- /dev/null
@@ -0,0 +1,37 @@
+From stable-bounces@linux.kernel.org Wed Aug  6 09:43:49 2008
+From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Date: Wed, 6 Aug 2008 18:40:27 +0200
+Subject: cs5520: add enablebits checking
+To: stable@kernel.org
+Cc: TAKADA Yoshihito <takada@mbf.nifty.com>
+Message-ID: <200808061840.27701.bzolnier@gmail.com>
+Content-Disposition: inline
+
+From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+
+upstream commit is 24307ffabd5b39bad443641f54b12ee2ba7a38ac
+
+Based on sparse comments in OpenFirmware code
+(no Cx5510/Cx5520 datasheet here).
+
+This fixes 2.6.26 regression reported by TAKADA
+and caused by addition of warm-plug support.
+
+Tested-by: TAKADA Yoshihito <takada@mbf.nifty.com>
+Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ide/pci/cs5520.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/ide/pci/cs5520.c
++++ b/drivers/ide/pci/cs5520.c
+@@ -123,6 +123,7 @@ static const struct ide_dma_ops cs5520_d
+ #define DECLARE_CS_DEV(name_str)                              \
+       {                                                       \
+               .name           = name_str,                     \
++              .enablebits     = { {0x60, 0x01, 0x01}, {0x60, 0x02, 0x02} }, \
+               .port_ops       = &cs5520_port_ops,             \
+               .dma_ops        = &cs5520_dma_ops,              \
+               .host_flags     = IDE_HFLAG_ISA_PORTS |         \
diff --git a/queue-2.6.26/i2c-fix-null-pointer-dereference-in-i2c_new_probed_device.patch b/queue-2.6.26/i2c-fix-null-pointer-dereference-in-i2c_new_probed_device.patch
new file mode 100644 (file)
index 0000000..8be62d6
--- /dev/null
@@ -0,0 +1,42 @@
+From stable-bounces@linux.kernel.org Tue Aug 12 02:34:13 2008
+From: Hans Verkuil <hverkuil@xs4all.nl>
+Date: Tue, 12 Aug 2008 10:50:29 +0200
+Subject: i2c: Fix NULL pointer dereference in i2c_new_probed_device
+To: stable@kernel.org
+Cc: Hans Verkuil <hverkuil@xs4all.nl>
+Message-ID: <20080812105029.3d156597@hyperion.delvare>
+
+
+From: Hans Verkuil <hverkuil@xs4all.nl>
+
+Already in Linus' tree:
+http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b25b791b13aaa336b56c4f9bd417ff126363f80b
+
+Fix a NULL pointer dereference that happened when calling
+i2c_new_probed_device on one of the addresses for which we use byte
+reads instead of quick write for detection purpose (that is: 0x30-0x37
+and 0x50-0x5f).
+
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/i2c-core.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -1196,9 +1196,11 @@ i2c_new_probed_device(struct i2c_adapter
+               if ((addr_list[i] & ~0x07) == 0x30
+                || (addr_list[i] & ~0x0f) == 0x50
+                || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
++                      union i2c_smbus_data data;
++
+                       if (i2c_smbus_xfer(adap, addr_list[i], 0,
+                                          I2C_SMBUS_READ, 0,
+-                                         I2C_SMBUS_BYTE, NULL) >= 0)
++                                         I2C_SMBUS_BYTE, &data) >= 0)
+                               break;
+               } else {
+                       if (i2c_smbus_xfer(adap, addr_list[i], 0,
diff --git a/queue-2.6.26/i2c-let-users-select-algorithm-drivers-manually-again.patch b/queue-2.6.26/i2c-let-users-select-algorithm-drivers-manually-again.patch
new file mode 100644 (file)
index 0000000..69882d4
--- /dev/null
@@ -0,0 +1,79 @@
+From stable-bounces@linux.kernel.org Tue Aug 12 02:34:23 2008
+From: Jean Delvare <khali@linux-fr.org>
+Date: Tue, 12 Aug 2008 10:52:06 +0200
+Subject: i2c: Let users select algorithm drivers manually again
+To: stable@kernel.org
+Message-ID: <20080812105206.0ab76058@hyperion.delvare>
+
+From: Jean Delvare <khali@linux-fr.org>
+
+Already in Linus' tree:
+http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8d24f8dcb7ead491704e274883b2c627062f6235
+
+In kernel 2.6.26, the ability to select I2C algorithm drivers manually
+was removed, as all in-kernel drivers do that automatically. However
+there were some complaints that it was a problem for out-of-tree I2C
+bus drivers. In order to address these complaints, let's allow manual
+selection of these drivers again, but still hide them by default for
+better general user experience.
+
+This closes bug #11140:
+http://bugzilla.kernel.org/show_bug.cgi?id=11140
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/Kconfig       |   14 ++++++++++++++
+ drivers/i2c/algos/Kconfig |   11 ++++++++---
+ 2 files changed, 22 insertions(+), 3 deletions(-)
+
+--- a/drivers/i2c/algos/Kconfig
++++ b/drivers/i2c/algos/Kconfig
+@@ -2,15 +2,20 @@
+ # I2C algorithm drivers configuration
+ #
++menu "I2C Algorithms"
++      depends on !I2C_HELPER_AUTO
++
+ config I2C_ALGOBIT
+-      tristate
++      tristate "I2C bit-banging interfaces"
+ config I2C_ALGOPCF
+-      tristate
++      tristate "I2C PCF 8584 interfaces"
+ config I2C_ALGOPCA
+-      tristate
++      tristate "I2C PCA 9564 interfaces"
+ config I2C_ALGO_SGI
+       tristate
+       depends on SGI_IP22 || SGI_IP32 || X86_VISWS
++
++endmenu
+--- a/drivers/i2c/Kconfig
++++ b/drivers/i2c/Kconfig
+@@ -38,6 +38,20 @@ config I2C_CHARDEV
+         This support is also available as a module.  If so, the module 
+         will be called i2c-dev.
++config I2C_HELPER_AUTO
++      bool "Autoselect pertinent helper modules"
++      default y
++      help
++        Some I2C bus drivers require so-called "I2C algorithm" modules
++        to work. These are basically software-only abstractions of generic
++        I2C interfaces. This option will autoselect them so that you don't
++        have to care.
++
++        Unselect this only if you need to enable additional helper
++        modules, for example for use with external I2C bus drivers.
++
++        In doubt, say Y.
++
+ source drivers/i2c/algos/Kconfig
+ source drivers/i2c/busses/Kconfig
+ source drivers/i2c/chips/Kconfig
diff --git a/queue-2.6.26/ide-it821x-in-pass-through-mode-segfaults-in-2.6.26-stable.patch b/queue-2.6.26/ide-it821x-in-pass-through-mode-segfaults-in-2.6.26-stable.patch
new file mode 100644 (file)
index 0000000..498c37a
--- /dev/null
@@ -0,0 +1,39 @@
+From 84e0f3f6c1e26588fdcb9f1b0f99d0275229bc99 Mon Sep 17 00:00:00 2001
+From: Dimitri Gorokhovik <dimitri.gorokhovik@free.fr>
+Date: Wed, 16 Jul 2008 20:33:34 +0200
+Subject: ide: it821x in pass-through mode segfaults in 2.6.26-stable
+Message-ID: <200808102332.38330.bzolnier@gmail.com>
+
+commit 84e0f3f6c1e26588fdcb9f1b0f99d0275229bc99 upstream
+
+The driver of ITE8212 in pass-through mode (it8212.noraid=1 on cmndline)
+attempts to use the field `.dma_host_set' of the struct ide_dma_ops in
+`ide_config_drive_speed' which is set to NULL by default.
+
+So give a value to all fields of the struct ide_dma_ops.
+
+Signed-off-by: Dimitri Gorokhovik <dimitri.gorokhovik@free.fr>
+Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ide/pci/it821x.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/ide/pci/it821x.c
++++ b/drivers/ide/pci/it821x.c
+@@ -512,8 +512,14 @@ static void __devinit it821x_quirkproc(i
+ }
+ static struct ide_dma_ops it821x_pass_through_dma_ops = {
++      .dma_host_set           = ide_dma_host_set,
++      .dma_setup              = ide_dma_setup,
++      .dma_exec_cmd           = ide_dma_exec_cmd,
+       .dma_start              = it821x_dma_start,
+       .dma_end                = it821x_dma_end,
++      .dma_test_irq           = ide_dma_test_irq,
++      .dma_timeout            = ide_dma_timeout,
++      .dma_lost_irq           = ide_dma_lost_irq,
+ };
+ /**
diff --git a/queue-2.6.26/kvm-avoid-instruction-emulation-when-event-delivery-is-pending.patch b/queue-2.6.26/kvm-avoid-instruction-emulation-when-event-delivery-is-pending.patch
new file mode 100644 (file)
index 0000000..c3d66eb
--- /dev/null
@@ -0,0 +1,76 @@
+From stable-bounces@linux.kernel.org Wed Aug 13 08:00:55 2008
+From: Avi Kivity <avi@qumranet.com>
+Date: Wed, 13 Aug 2008 18:00:28 +0300
+Subject: KVM: Avoid instruction emulation when event delivery is pending
+To: stable@kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Message-ID: <1218639630-28692-4-git-send-email-avi@qumranet.com>
+
+From: Avi Kivity <avi@qumranet.com>
+
+(cherry-picked from commit 577bdc496614ced56d999bbb425e85adf2386490)
+
+When an event (such as an interrupt) is injected, and the stack is
+shadowed (and therefore write protected), the guest will exit.  The
+current code will see that the stack is shadowed and emulate a few
+instructions, each time postponing the injection.  Eventually the
+injection may succeed, but at that time the guest may be unwilling
+to accept the interrupt (for example, the TPR may have changed).
+
+This occurs every once in a while during a Windows 2008 boot.
+
+Fix by unshadowing the fault address if the fault was due to an event
+injection.
+
+Signed-off-by: Avi Kivity <avi@qumranet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kvm/mmu.c |    1 +
+ arch/x86/kvm/svm.c |    7 ++++++-
+ arch/x86/kvm/vmx.c |    2 ++
+ 3 files changed, 9 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/mmu.c
++++ b/arch/x86/kvm/mmu.c
+@@ -1792,6 +1792,7 @@ int kvm_mmu_unprotect_page_virt(struct k
+       spin_unlock(&vcpu->kvm->mmu_lock);
+       return r;
+ }
++EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt);
+ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
+ {
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -1007,13 +1007,18 @@ static int pf_interception(struct vcpu_s
+       struct kvm *kvm = svm->vcpu.kvm;
+       u64 fault_address;
+       u32 error_code;
++      bool event_injection = false;
+       if (!irqchip_in_kernel(kvm) &&
+-              is_external_interrupt(exit_int_info))
++          is_external_interrupt(exit_int_info)) {
++              event_injection = true;
+               push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK);
++      }
+       fault_address  = svm->vmcb->control.exit_info_2;
+       error_code = svm->vmcb->control.exit_info_1;
++      if (event_injection)
++              kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
+       return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
+ }
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -2258,6 +2258,8 @@ static int handle_exception(struct kvm_v
+               cr2 = vmcs_readl(EXIT_QUALIFICATION);
+               KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2,
+                           (u32)((u64)cr2 >> 32), handler);
++              if (vect_info & VECTORING_INFO_VALID_MASK)
++                      kvm_mmu_unprotect_page_virt(vcpu, cr2);
+               return kvm_mmu_page_fault(vcpu, cr2, error_code);
+       }
diff --git a/queue-2.6.26/kvm-ia64-fix-irq-disabling-leak-in-error-handling-code.patch b/queue-2.6.26/kvm-ia64-fix-irq-disabling-leak-in-error-handling-code.patch
new file mode 100644 (file)
index 0000000..c0013a5
--- /dev/null
@@ -0,0 +1,88 @@
+From stable-bounces@linux.kernel.org Wed Aug 13 08:00:59 2008
+From: Julia Lawall <julia@diku.dk>
+Date: Wed, 13 Aug 2008 18:00:30 +0300
+Subject: KVM: ia64: Fix irq disabling leak in error handling code
+To: stable@kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>, Julia Lawall <julia@diku.dk>
+Message-ID: <1218639630-28692-6-git-send-email-avi@qumranet.com>
+
+
+From: Julia Lawall <julia@diku.dk>
+
+(cherry picked from commit cab7a1eeeb007be309cd99cf14407261a72d2418)
+
+There is a call to local_irq_restore in the normal exit case, so it would
+seem that there should be one on an error return as well.
+
+The semantic patch that finds this problem is as follows:
+(http://www.emn.fr/x-info/coccinelle/)
+
+// <smpl>
+@@
+expression l;
+expression E,E1,E2;
+@@
+
+local_irq_save(l);
+... when != local_irq_restore(l)
+    when != spin_unlock_irqrestore(E,l)
+    when any
+    when strict
+(
+if (...) { ... when != local_irq_restore(l)
+               when != spin_unlock_irqrestore(E1,l)
++   local_irq_restore(l);
+    return ...;
+}
+|
+if (...)
++   {local_irq_restore(l);
+    return ...;
++   }
+|
+spin_unlock_irqrestore(E2,l);
+|
+local_irq_restore(l);
+)
+// </smpl>
+
+Signed-off-by: Julia Lawall <julia@diku.dk>
+Signed-off-by: Avi Kivity <avi@qumranet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/ia64/kvm/kvm-ia64.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/ia64/kvm/kvm-ia64.c
++++ b/arch/ia64/kvm/kvm-ia64.c
+@@ -125,9 +125,9 @@ void kvm_arch_hardware_enable(void *garb
+                               PAGE_KERNEL));
+       local_irq_save(saved_psr);
+       slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
++      local_irq_restore(saved_psr);
+       if (slot < 0)
+               return;
+-      local_irq_restore(saved_psr);
+       spin_lock(&vp_lock);
+       status = ia64_pal_vp_init_env(kvm_vsa_base ?
+@@ -160,9 +160,9 @@ void kvm_arch_hardware_disable(void *gar
+       local_irq_save(saved_psr);
+       slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
++      local_irq_restore(saved_psr);
+       if (slot < 0)
+               return;
+-      local_irq_restore(saved_psr);
+       status = ia64_pal_vp_exit_env(host_iva);
+       if (status)
+@@ -1258,6 +1258,7 @@ static int vti_vcpu_setup(struct kvm_vcp
+ uninit:
+       kvm_vcpu_uninit(vcpu);
+ fail:
++      local_irq_restore(psr);
+       return r;
+ }
diff --git a/queue-2.6.26/kvm-task-switch-segment-base-is-linear-address.patch b/queue-2.6.26/kvm-task-switch-segment-base-is-linear-address.patch
new file mode 100644 (file)
index 0000000..ae854f2
--- /dev/null
@@ -0,0 +1,72 @@
+From stable-bounces@linux.kernel.org Wed Aug 13 08:00:51 2008
+From: Marcelo Tosatti <mtosatti@redhat.com>
+Date: Wed, 13 Aug 2008 18:00:26 +0300
+Subject: KVM: task switch: segment base is linear address
+To: stable@kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Message-ID: <1218639630-28692-2-git-send-email-avi@qumranet.com>
+
+
+From: Marcelo Tosatti <mtosatti@redhat.com>
+
+(cherry picked from commit 98899aa0e0bf5de05850082be0eb837058c09ea5)
+
+The segment base is always a linear address, so translate before
+accessing guest memory.
+
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Avi Kivity <avi@qumranet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kvm/x86.c |   12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -3207,6 +3207,7 @@ static void get_segment_descritptor_dtab
+ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
+                                        struct desc_struct *seg_desc)
+ {
++      gpa_t gpa;
+       struct descriptor_table dtable;
+       u16 index = selector >> 3;
+@@ -3216,13 +3217,16 @@ static int load_guest_segment_descriptor
+               kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
+               return 1;
+       }
+-      return kvm_read_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8);
++      gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
++      gpa += index * 8;
++      return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8);
+ }
+ /* allowed just for 8 bytes segments */
+ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
+                                        struct desc_struct *seg_desc)
+ {
++      gpa_t gpa;
+       struct descriptor_table dtable;
+       u16 index = selector >> 3;
+@@ -3230,7 +3234,9 @@ static int save_guest_segment_descriptor
+       if (dtable.limit < index * 8 + 7)
+               return 1;
+-      return kvm_write_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8);
++      gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
++      gpa += index * 8;
++      return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8);
+ }
+ static u32 get_tss_base_addr(struct kvm_vcpu *vcpu,
+@@ -3242,7 +3248,7 @@ static u32 get_tss_base_addr(struct kvm_
+       base_addr |= (seg_desc->base1 << 16);
+       base_addr |= (seg_desc->base2 << 24);
+-      return base_addr;
++      return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
+ }
+ static int load_tss_segment32(struct kvm_vcpu *vcpu,
diff --git a/queue-2.6.26/kvm-task-switch-translate-guest-segment-limit-to-virt-extension-byte-granular-field.patch b/queue-2.6.26/kvm-task-switch-translate-guest-segment-limit-to-virt-extension-byte-granular-field.patch
new file mode 100644 (file)
index 0000000..dfa31a2
--- /dev/null
@@ -0,0 +1,36 @@
+From stable-bounces@linux.kernel.org Wed Aug 13 08:00:47 2008
+From: Marcelo Tosatti <mtosatti@redhat.com>
+Date: Wed, 13 Aug 2008 18:00:29 +0300
+Subject: KVM: task switch: translate guest segment limit to virt-extension byte granular field
+To: stable@kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Message-ID: <1218639630-28692-5-git-send-email-avi@qumranet.com>
+
+
+From: Marcelo Tosatti <mtosatti@redhat.com>
+
+(cherry picked from commit c93cd3a58845012df2d658fecd0ac99f7008d753)
+
+If 'g' is one then limit is 4kb granular.
+
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Avi Kivity <avi@qumranet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kvm/x86.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -3168,6 +3168,10 @@ static void seg_desct_to_kvm_desct(struc
+       kvm_desct->base |= seg_desc->base2 << 24;
+       kvm_desct->limit = seg_desc->limit0;
+       kvm_desct->limit |= seg_desc->limit << 16;
++      if (seg_desc->g) {
++              kvm_desct->limit <<= 12;
++              kvm_desct->limit |= 0xfff;
++      }
+       kvm_desct->selector = selector;
+       kvm_desct->type = seg_desc->type;
+       kvm_desct->present = seg_desc->p;
diff --git a/queue-2.6.26/kvm-task-switch-use-seg-regs-provided-by-subarch-instead-of-reading-from-gdt.patch b/queue-2.6.26/kvm-task-switch-use-seg-regs-provided-by-subarch-instead-of-reading-from-gdt.patch
new file mode 100644 (file)
index 0000000..b3979cf
--- /dev/null
@@ -0,0 +1,193 @@
+From stable-bounces@linux.kernel.org Wed Aug 13 08:00:55 2008
+From: Marcelo Tosatti <mtosatti@redhat.com>
+Date: Wed, 13 Aug 2008 18:00:27 +0300
+Subject: KVM: task switch: use seg regs provided by subarch instead of reading from GDT
+To: stable@kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Message-ID: <1218639630-28692-3-git-send-email-avi@qumranet.com>
+
+
+From: Marcelo Tosatti <mtosatti@redhat.com>
+
+(cherry-picked from commit 34198bf8426276a2ce1e97056a0f02d43637e5ae)
+
+There is no guarantee that the old TSS descriptor in the GDT contains
+the proper base address. This is the case for Windows installation's
+reboot-via-triplefault.
+
+Use guest registers instead. Also translate the address properly.
+
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Avi Kivity <avi@qumranet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kvm/x86.c |   93 +++++++++++++++++------------------------------------
+ 1 file changed, 30 insertions(+), 63 deletions(-)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -3251,54 +3251,6 @@ static u32 get_tss_base_addr(struct kvm_
+       return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
+ }
+-static int load_tss_segment32(struct kvm_vcpu *vcpu,
+-                            struct desc_struct *seg_desc,
+-                            struct tss_segment_32 *tss)
+-{
+-      u32 base_addr;
+-
+-      base_addr = get_tss_base_addr(vcpu, seg_desc);
+-
+-      return kvm_read_guest(vcpu->kvm, base_addr, tss,
+-                            sizeof(struct tss_segment_32));
+-}
+-
+-static int save_tss_segment32(struct kvm_vcpu *vcpu,
+-                            struct desc_struct *seg_desc,
+-                            struct tss_segment_32 *tss)
+-{
+-      u32 base_addr;
+-
+-      base_addr = get_tss_base_addr(vcpu, seg_desc);
+-
+-      return kvm_write_guest(vcpu->kvm, base_addr, tss,
+-                             sizeof(struct tss_segment_32));
+-}
+-
+-static int load_tss_segment16(struct kvm_vcpu *vcpu,
+-                            struct desc_struct *seg_desc,
+-                            struct tss_segment_16 *tss)
+-{
+-      u32 base_addr;
+-
+-      base_addr = get_tss_base_addr(vcpu, seg_desc);
+-
+-      return kvm_read_guest(vcpu->kvm, base_addr, tss,
+-                            sizeof(struct tss_segment_16));
+-}
+-
+-static int save_tss_segment16(struct kvm_vcpu *vcpu,
+-                            struct desc_struct *seg_desc,
+-                            struct tss_segment_16 *tss)
+-{
+-      u32 base_addr;
+-
+-      base_addr = get_tss_base_addr(vcpu, seg_desc);
+-
+-      return kvm_write_guest(vcpu->kvm, base_addr, tss,
+-                             sizeof(struct tss_segment_16));
+-}
+-
+ static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg)
+ {
+       struct kvm_segment kvm_seg;
+@@ -3456,20 +3408,26 @@ static int load_state_from_tss16(struct 
+ }
+ int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
+-                     struct desc_struct *cseg_desc,
++                     u32 old_tss_base,
+                      struct desc_struct *nseg_desc)
+ {
+       struct tss_segment_16 tss_segment_16;
+       int ret = 0;
+-      if (load_tss_segment16(vcpu, cseg_desc, &tss_segment_16))
++      if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_16,
++                         sizeof tss_segment_16))
+               goto out;
+       save_state_to_tss16(vcpu, &tss_segment_16);
+-      save_tss_segment16(vcpu, cseg_desc, &tss_segment_16);
+-      if (load_tss_segment16(vcpu, nseg_desc, &tss_segment_16))
++      if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_16,
++                          sizeof tss_segment_16))
++              goto out;
++
++      if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
++                         &tss_segment_16, sizeof tss_segment_16))
+               goto out;
++
+       if (load_state_from_tss16(vcpu, &tss_segment_16))
+               goto out;
+@@ -3479,20 +3437,26 @@ out:
+ }
+ int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
+-                     struct desc_struct *cseg_desc,
++                     u32 old_tss_base,
+                      struct desc_struct *nseg_desc)
+ {
+       struct tss_segment_32 tss_segment_32;
+       int ret = 0;
+-      if (load_tss_segment32(vcpu, cseg_desc, &tss_segment_32))
++      if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_32,
++                         sizeof tss_segment_32))
+               goto out;
+       save_state_to_tss32(vcpu, &tss_segment_32);
+-      save_tss_segment32(vcpu, cseg_desc, &tss_segment_32);
+-      if (load_tss_segment32(vcpu, nseg_desc, &tss_segment_32))
++      if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_32,
++                          sizeof tss_segment_32))
++              goto out;
++
++      if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
++                         &tss_segment_32, sizeof tss_segment_32))
+               goto out;
++
+       if (load_state_from_tss32(vcpu, &tss_segment_32))
+               goto out;
+@@ -3507,16 +3471,20 @@ int kvm_task_switch(struct kvm_vcpu *vcp
+       struct desc_struct cseg_desc;
+       struct desc_struct nseg_desc;
+       int ret = 0;
++      u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR);
++      u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR);
+-      get_segment(vcpu, &tr_seg, VCPU_SREG_TR);
++      old_tss_base = vcpu->arch.mmu.gva_to_gpa(vcpu, old_tss_base);
++      /* FIXME: Handle errors. Failure to read either TSS or their
++       * descriptors should generate a pagefault.
++       */
+       if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc))
+               goto out;
+-      if (load_guest_segment_descriptor(vcpu, tr_seg.selector, &cseg_desc))
++      if (load_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc))
+               goto out;
+-
+       if (reason != TASK_SWITCH_IRET) {
+               int cpl;
+@@ -3534,8 +3502,7 @@ int kvm_task_switch(struct kvm_vcpu *vcp
+       if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) {
+               cseg_desc.type &= ~(1 << 1); //clear the B flag
+-              save_guest_segment_descriptor(vcpu, tr_seg.selector,
+-                                            &cseg_desc);
++              save_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc);
+       }
+       if (reason == TASK_SWITCH_IRET) {
+@@ -3547,10 +3514,10 @@ int kvm_task_switch(struct kvm_vcpu *vcp
+       kvm_x86_ops->cache_regs(vcpu);
+       if (nseg_desc.type & 8)
+-              ret = kvm_task_switch_32(vcpu, tss_selector, &cseg_desc,
++              ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_base,
+                                        &nseg_desc);
+       else
+-              ret = kvm_task_switch_16(vcpu, tss_selector, &cseg_desc,
++              ret = kvm_task_switch_16(vcpu, tss_selector, old_tss_base,
+                                        &nseg_desc);
+       if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) {
diff --git a/queue-2.6.26/r8169-avoid-thrashing-pci-conf-space-above-rtl_giga_mac_ver_06.patch b/queue-2.6.26/r8169-avoid-thrashing-pci-conf-space-above-rtl_giga_mac_ver_06.patch
new file mode 100644 (file)
index 0000000..b00203a
--- /dev/null
@@ -0,0 +1,63 @@
+From 77332894c21165404496c56763d7df6c15c4bb09 Mon Sep 17 00:00:00 2001
+From: Marcus Sundberg <marcus@ingate.com>
+Date: Thu, 10 Jul 2008 21:28:08 +0200
+Subject: r8169: avoid thrashing PCI conf space above RTL_GIGA_MAC_VER_06
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+
+From: Marcus Sundberg <marcus@ingate.com>
+
+commit 77332894c21165404496c56763d7df6c15c4bb09 upstream
+
+The magic write to register 0x82 will often cause PCI config space on
+my 8168 (PCI ID 10ec:8168, revision 2. mounted in an LG P300 laptop)
+to be filled with ones during driver load, and thus breaking NIC
+operation until reboot. If it does not happen on first driver load it
+can easily be reproduced by unloading and loading the driver a few
+times.
+
+The magic write was added long ago by this commit:
+
+Author: François Romieu <romieu@fr.zoreil.com>
+Date:   Sat Jan 10 06:00:46 2004 -0500
+
+     [netdrvr r8169] Merge of changes done by Realtek to rtl8169_init_one():
+     - phy capability settings allows lower or equal capability as suggested
+       in Realtek's changes;
+     - I/O voodoo;
+     - no need to s/mdio_write/RTL8169_WRITE_GMII_REG/;
+     - s/rtl8169_hw_PHY_config/rtl8169_hw_phy_config/;
+     - rtl8169_hw_phy_config(): ad-hoc struct "phy_magic" to limit duplication
+       of code (yep, the u16 -> int conversions should work as expected);
+     - variable renames and whitepace changes ignored.
+
+As the 8168 wasn't supported by that version this patch simply removes
+the bogus write from mac versions <= RTL_GIGA_MAC_VER_06.
+
+[The change above makes sense for the 8101/8102 too -- Ueimor]
+
+Signed-off-by: Marcus Sundberg <marcus@ingate.com>
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Cc: Karsten Keil <kkeil@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/r8169.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -1438,8 +1438,10 @@ static void rtl8169_init_phy(struct net_
+       rtl_hw_phy_config(dev);
+-      dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+-      RTL_W8(0x82, 0x01);
++      if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
++              dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
++              RTL_W8(0x82, 0x01);
++      }
+       pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
diff --git a/queue-2.6.26/radeon-misc-corrections.patch b/queue-2.6.26/radeon-misc-corrections.patch
new file mode 100644 (file)
index 0000000..428f8ed
--- /dev/null
@@ -0,0 +1,82 @@
+From stable-bounces@linux.kernel.org Wed Aug  6 15:28:59 2008
+From: David Miller <davem@davemloft.net>
+Date: Wed, 6 Aug 2008 15:28:12 -0700
+Subject: radeon: misc corrections
+To: stable@kernel.org
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>, "David S. Miller" <davem@davemloft.net>
+Message-ID: <20080806152812.51242c18.akpm@linux-foundation.org>
+
+From: David Miller <davem@davemloft.net>
+
+Commit efc491814308f89d5ef6c4fe19ae4552a67d4132 upstream
+
+radeon: misc corrections
+
+I have a new PCI-E radeon RV380 series card (PCI device ID 5b64) that
+hangs in my sparc64 boxes when the init scripts set the font.  The problem
+goes away if I disable acceleration.
+
+I haven't figured out that bug yet, but along the way I found some
+corrections to make based upon some auditing.
+
+1) The RB2D_DC_FLUSH_ALL value used by the kernel fb driver
+   and the XORG video driver differ.  I've made the kernel
+   match what XORG is using.
+
+2) In radeonfb_engine_reset() we have top-level code structure
+   that roughly looks like:
+
+       if (family is 300, 350, or V350)
+               do this;
+       else
+               do that;
+       ...
+       if (family is NOT 300, OR
+           family is NOT 350, OR
+           family is NOT V350)
+               do another thing;
+
+   this last conditional makes no sense, is always true,
+   and obviously was likely meant to be "family is NOT
+   300, 350, or V350".  So I've made the code match the
+   intent.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Tested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+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/video/aty/radeon_accel.c |    4 ++--
+ include/video/radeon.h           |    5 +++--
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/video/aty/radeon_accel.c
++++ b/drivers/video/aty/radeon_accel.c
+@@ -249,8 +249,8 @@ void radeonfb_engine_reset(struct radeon
+       INREG(HOST_PATH_CNTL);
+       OUTREG(HOST_PATH_CNTL, host_path_cntl);
+-      if (rinfo->family != CHIP_FAMILY_R300 ||
+-          rinfo->family != CHIP_FAMILY_R350 ||
++      if (rinfo->family != CHIP_FAMILY_R300 &&
++          rinfo->family != CHIP_FAMILY_R350 &&
+           rinfo->family != CHIP_FAMILY_RV350)
+               OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
+--- a/include/video/radeon.h
++++ b/include/video/radeon.h
+@@ -527,8 +527,9 @@
+ /* DSTCACHE_CTLSTAT bit constants */
+-#define RB2D_DC_FLUSH                            (3 << 0)
+-#define RB2D_DC_FLUSH_ALL                        0xf
++#define RB2D_DC_FLUSH_2D                         (1 << 0)
++#define RB2D_DC_FREE_2D                                  (1 << 2)
++#define RB2D_DC_FLUSH_ALL                        (RB2D_DC_FLUSH_2D | RB2D_DC_FREE_2D)
+ #define RB2D_DC_BUSY                             (1 << 31)
diff --git a/queue-2.6.26/rtl8187-fix-lockups-due-to-concurrent-access-to-config-routine.patch b/queue-2.6.26/rtl8187-fix-lockups-due-to-concurrent-access-to-config-routine.patch
new file mode 100644 (file)
index 0000000..a5656a1
--- /dev/null
@@ -0,0 +1,69 @@
+From stable-bounces@linux.kernel.org Tue Aug  5 21:22:47 2008
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Tue, 05 Aug 2008 23:20:56 -0500
+Subject: [stable] [PATCH] rtl8187: Fix lockups due to concurrent access to config routine
+To: stable@kernel.org
+Message-ID: <489926a8.Tmk8qWQZeTkY9DVD%Larry.Finger@lwfinger.net>
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+With the rtl8187 driver, the config routine is not protected against
+access before a previous call has completed. When this happens, the
+TX loopback that is needed to change channels may cause the chip to
+be locked with a reset needed to restore communications. This patch
+entered mainline as commit 7dcdd073bf78bb6958bbc12a1a47754a0f3c4721.
+
+The problem was found by Herton Ronaldo Krzesinski <herton@mandriva.com.br>,
+who also suggested this type of fix.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Acked-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
+Acked-by: Hin-Tak Leung <htl10@users.sourceforge.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/net/wireless/rtl8187.h     |    4 ++++
+ drivers/net/wireless/rtl8187_dev.c |    3 +++
+ 2 files changed, 7 insertions(+)
+
+--- a/drivers/net/wireless/rtl8187_dev.c
++++ b/drivers/net/wireless/rtl8187_dev.c
+@@ -580,6 +580,7 @@ static int rtl8187_config(struct ieee802
+       struct rtl8187_priv *priv = dev->priv;
+       u32 reg;
++      mutex_lock(&priv->conf_mutex);
+       reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+       /* Enable TX loopback on MAC level to avoid TX during channel
+        * changes, as this has be seen to causes problems and the
+@@ -610,6 +611,7 @@ static int rtl8187_config(struct ieee802
+       rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
+       rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
+       rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
++      mutex_unlock(&priv->conf_mutex);
+       return 0;
+ }
+@@ -814,6 +816,7 @@ static int __devinit rtl8187_probe(struc
+               printk(KERN_ERR "rtl8187: Cannot register device\n");
+               goto err_free_dev;
+       }
++      mutex_init(&priv->conf_mutex);
+       printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n",
+              wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
+--- a/drivers/net/wireless/rtl8187.h
++++ b/drivers/net/wireless/rtl8187.h
+@@ -67,6 +67,10 @@ struct rtl8187_priv {
+       const struct rtl818x_rf_ops *rf;
+       struct ieee80211_vif *vif;
+       int mode;
++      /* The mutex protects the TX loopback state.
++       * Any attempt to set channels concurrently locks the device.
++       */
++      struct mutex conf_mutex;
+       /* rtl8187 specific */
+       struct ieee80211_channel channels[14];
index 1ed9aae7e835b6a2340bb1ebac6f644eecfb96fd..5e7f161114d79abbdd189d3deacf6e04c1bd263c 100644 (file)
@@ -28,3 +28,19 @@ ipv6-fix-ip6_xmit-to-send-fragments-if-ipfragok-is-true.patch
 sparc64-futex_op_andn-fix.patch
 sparc64-fix-global-reg-snapshotting-on-self-cpu.patch
 sparc64-do-not-clobber-g7-in-setcontext-trap.patch
+kvm-task-switch-segment-base-is-linear-address.patch
+kvm-task-switch-use-seg-regs-provided-by-subarch-instead-of-reading-from-gdt.patch
+kvm-avoid-instruction-emulation-when-event-delivery-is-pending.patch
+kvm-task-switch-translate-guest-segment-limit-to-virt-extension-byte-granular-field.patch
+kvm-ia64-fix-irq-disabling-leak-in-error-handling-code.patch
+r8169-avoid-thrashing-pci-conf-space-above-rtl_giga_mac_ver_06.patch
+alsa-asoc-restrict-sample-rate-and-size-in-freescale-mpc8610-sound-drivers.patch
+i2c-fix-null-pointer-dereference-in-i2c_new_probed_device.patch
+i2c-let-users-select-algorithm-drivers-manually-again.patch
+alsa-asoc-fix-sndctl_dsp_sync-support-in-freescale-8610-sound-drivers.patch
+x86-amd-opteron-tom2-mask-val-fix.patch
+ide-it821x-in-pass-through-mode-segfaults-in-2.6.26-stable.patch
+cifs-fix-compiler-warning-on-64-bit.patch
+radeon-misc-corrections.patch
+cs5520-add-enablebits-checking.patch
+rtl8187-fix-lockups-due-to-concurrent-access-to-config-routine.patch
diff --git a/queue-2.6.26/x86-amd-opteron-tom2-mask-val-fix.patch b/queue-2.6.26/x86-amd-opteron-tom2-mask-val-fix.patch
new file mode 100644 (file)
index 0000000..310317e
--- /dev/null
@@ -0,0 +1,56 @@
+From 8004dd965b13b01a96def054d420f6df7ff22d53 Mon Sep 17 00:00:00 2001
+From: Yinghai Lu <yhlu.kernel@gmail.com>
+Date: Mon, 12 May 2008 17:40:39 -0700
+Subject: x86: amd opteron TOM2 mask val fix
+
+From: Yinghai Lu <yhlu.kernel@gmail.com>
+
+commit 8004dd965b13b01a96def054d420f6df7ff22d53 upstream.
+
+there is a typo in the mask value, need to remove that extra 0,
+to avoid 4bit clearing.
+
+Signed-off-by: Yinghal Lu <yhlu.kernel@gmail.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Cc: maximilian attems <max@stro.at>
+Cc: Peter Palfrader <weasel@debian.org>
+Cc: dann frazier <dannf@debian.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ arch/x86/kernel/cpu/mtrr/generic.c |    2 +-
+ arch/x86/pci/k8-bus_64.c           |    4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/kernel/cpu/mtrr/generic.c
++++ b/arch/x86/kernel/cpu/mtrr/generic.c
+@@ -219,7 +219,7 @@ void __init get_mtrr_state(void)
+               tom2 = hi;
+               tom2 <<= 32;
+               tom2 |= lo;
+-              tom2 &= 0xffffff8000000ULL;
++              tom2 &= 0xffffff800000ULL;
+       }
+       if (mtrr_show) {
+               int high_width;
+--- a/arch/x86/pci/k8-bus_64.c
++++ b/arch/x86/pci/k8-bus_64.c
+@@ -384,7 +384,7 @@ static int __init early_fill_mp_bus_info
+       /* need to take out [0, TOM) for RAM*/
+       address = MSR_K8_TOP_MEM1;
+       rdmsrl(address, val);
+-      end = (val & 0xffffff8000000ULL);
++      end = (val & 0xffffff800000ULL);
+       printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20);
+       if (end < (1ULL<<32))
+               update_range(range, 0, end - 1);
+@@ -478,7 +478,7 @@ static int __init early_fill_mp_bus_info
+               /* TOP_MEM2 */
+               address = MSR_K8_TOP_MEM2;
+               rdmsrl(address, val);
+-              end = (val & 0xffffff8000000ULL);
++              end = (val & 0xffffff800000ULL);
+               printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20);
+               update_range(range, 1ULL<<32, end - 1);
+       }