]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.13-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Mar 2014 21:18:28 +0000 (14:18 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Mar 2014 21:18:28 +0000 (14:18 -0700)
added patches:
fs-proc-proc_devtree.c-remove-empty-proc-device-tree-when-no-openfirmware-exists.patch
input-elantech-improve-clickpad-detection.patch
input-wacom-add-reporting-of-sw_mute_device-events.patch
input-wacom-add-support-for-three-new-intuos-devices.patch
input-wacom-make-sure-touch_max-is-set-for-touch-devices.patch
kvm-mmu-handle-invalid-root_hpa-at-__direct_map.patch
kvm-vmx-fix-use-after-free-of-vmx-loaded_vmcs.patch
kvm-x86-handle-invalid-root_hpa-everywhere.patch
powerpc-eeh-handle-multiple-eeh-errors.patch
powerpc-powernv-dump-phb-diag-data-immediately.patch
powerpc-powernv-refactor-phb-diag-data-dump.patch

12 files changed:
queue-3.13/fs-proc-proc_devtree.c-remove-empty-proc-device-tree-when-no-openfirmware-exists.patch [new file with mode: 0644]
queue-3.13/input-elantech-improve-clickpad-detection.patch [new file with mode: 0644]
queue-3.13/input-wacom-add-reporting-of-sw_mute_device-events.patch [new file with mode: 0644]
queue-3.13/input-wacom-add-support-for-three-new-intuos-devices.patch [new file with mode: 0644]
queue-3.13/input-wacom-make-sure-touch_max-is-set-for-touch-devices.patch [new file with mode: 0644]
queue-3.13/kvm-mmu-handle-invalid-root_hpa-at-__direct_map.patch [new file with mode: 0644]
queue-3.13/kvm-vmx-fix-use-after-free-of-vmx-loaded_vmcs.patch [new file with mode: 0644]
queue-3.13/kvm-x86-handle-invalid-root_hpa-everywhere.patch [new file with mode: 0644]
queue-3.13/powerpc-eeh-handle-multiple-eeh-errors.patch [new file with mode: 0644]
queue-3.13/powerpc-powernv-dump-phb-diag-data-immediately.patch [new file with mode: 0644]
queue-3.13/powerpc-powernv-refactor-phb-diag-data-dump.patch [new file with mode: 0644]
queue-3.13/series

diff --git a/queue-3.13/fs-proc-proc_devtree.c-remove-empty-proc-device-tree-when-no-openfirmware-exists.patch b/queue-3.13/fs-proc-proc_devtree.c-remove-empty-proc-device-tree-when-no-openfirmware-exists.patch
new file mode 100644 (file)
index 0000000..739e7e4
--- /dev/null
@@ -0,0 +1,45 @@
+From c1d867a54d426b45da017fbe8e585f8a3064ce8d Mon Sep 17 00:00:00 2001
+From: Dave Jones <davej@redhat.com>
+Date: Thu, 23 Jan 2014 15:55:43 -0800
+Subject: fs/proc/proc_devtree.c: remove empty /proc/device-tree when no openfirmware exists.
+
+From: Dave Jones <davej@redhat.com>
+
+commit c1d867a54d426b45da017fbe8e585f8a3064ce8d upstream.
+
+Distribution kernels might want to build in support for /proc/device-tree
+for kernels that might end up running on hardware that doesn't support
+openfirmware.  This results in an empty /proc/device-tree existing.
+Remove it if the OFW root node doesn't exist.
+
+This situation actually confuses grub2, resulting in install failures.
+grub2 sees the /proc/device-tree and picks the wrong install target cf.
+http://bzr.savannah.gnu.org/lh/grub/trunk/grub/annotate/4300/util/grub-install.in#L311
+grub should be more robust, but still, leaving an empty proc dir seems
+pointless.
+
+Addresses https://bugzilla.redhat.com/show_bug.cgi?id=818378.
+
+Signed-off-by: Dave Jones <davej@redhat.com>
+Cc: Al Viro <viro@ZenIV.linux.org.uk>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Cc: 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@linuxfoundation.org>
+
+---
+ fs/proc/proc_devtree.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/proc/proc_devtree.c
++++ b/fs/proc/proc_devtree.c
+@@ -232,6 +232,7 @@ void __init proc_device_tree_init(void)
+               return;
+       root = of_find_node_by_path("/");
+       if (root == NULL) {
++              remove_proc_entry("device-tree", NULL);
+               pr_debug("/proc/device-tree: can't find root\n");
+               return;
+       }
diff --git a/queue-3.13/input-elantech-improve-clickpad-detection.patch b/queue-3.13/input-elantech-improve-clickpad-detection.patch
new file mode 100644 (file)
index 0000000..1487684
--- /dev/null
@@ -0,0 +1,111 @@
+From c15bdfd5b9831e4cab8cfc118243956e267dd30e Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Mon, 16 Dec 2013 07:09:25 -0800
+Subject: Input: elantech -  improve clickpad detection
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit c15bdfd5b9831e4cab8cfc118243956e267dd30e upstream.
+
+The current assumption in the elantech driver that hw version 3 touchpads
+are never clickpads and hw version 4 touchpads are always clickpads is
+wrong.
+
+There are several bug reports for this, ie:
+https://bugzilla.redhat.com/show_bug.cgi?id=1030802
+http://superuser.com/questions/619582/right-elantech-touchpad-button-not-working-in-linux
+
+I've spend a couple of hours wading through various bugzillas, launchpads
+and forum posts to create a list of fw-versions and capabilities for
+different laptop models to find a good method to differentiate between
+clickpads and versions with separate hardware buttons.
+
+Which shows that a device being a clickpad is reliable indicated by bit 12
+being set in the fw_version. I've included the gathered list inside the
+driver, so that we've this info at hand if we need to revisit this later.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/mouse/elantech.c |   45 ++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 42 insertions(+), 3 deletions(-)
+
+--- a/drivers/input/mouse/elantech.c
++++ b/drivers/input/mouse/elantech.c
+@@ -486,6 +486,7 @@ static void elantech_input_sync_v4(struc
+       unsigned char *packet = psmouse->packet;
+       input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
++      input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+       input_mt_report_pointer_emulation(dev, true);
+       input_sync(dev);
+ }
+@@ -984,6 +985,44 @@ static int elantech_get_resolution_v4(st
+ }
+ /*
++ * Advertise INPUT_PROP_BUTTONPAD for clickpads. The testing of bit 12 in
++ * fw_version for this is based on the following fw_version & caps table:
++ *
++ * Laptop-model:           fw_version:     caps:           buttons:
++ * Acer S3                 0x461f00        10, 13, 0e      clickpad
++ * Acer S7-392             0x581f01        50, 17, 0d      clickpad
++ * Acer V5-131             0x461f02        01, 16, 0c      clickpad
++ * Acer V5-551             0x461f00        ?               clickpad
++ * Asus K53SV              0x450f01        78, 15, 0c      2 hw buttons
++ * Asus G46VW              0x460f02        00, 18, 0c      2 hw buttons
++ * Asus G750JX             0x360f00        00, 16, 0c      2 hw buttons
++ * Asus UX31               0x361f00        20, 15, 0e      clickpad
++ * Asus UX32VD             0x361f02        00, 15, 0e      clickpad
++ * Avatar AVIU-145A2       0x361f00        ?               clickpad
++ * Gigabyte U2442          0x450f01        58, 17, 0c      2 hw buttons
++ * Lenovo L430             0x350f02        b9, 15, 0c      2 hw buttons (*)
++ * Samsung NF210           0x150b00        78, 14, 0a      2 hw buttons
++ * Samsung NP770Z5E        0x575f01        10, 15, 0f      clickpad
++ * Samsung NP700Z5B        0x361f06        21, 15, 0f      clickpad
++ * Samsung NP900X3E-A02    0x575f03        ?               clickpad
++ * Samsung NP-QX410        0x851b00        19, 14, 0c      clickpad
++ * Samsung RC512           0x450f00        08, 15, 0c      2 hw buttons
++ * Samsung RF710           0x450f00        ?               2 hw buttons
++ * System76 Pangolin       0x250f01        ?               2 hw buttons
++ * (*) + 3 trackpoint buttons
++ */
++static void elantech_set_buttonpad_prop(struct psmouse *psmouse)
++{
++      struct input_dev *dev = psmouse->dev;
++      struct elantech_data *etd = psmouse->private;
++
++      if (etd->fw_version & 0x001000) {
++              __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
++              __clear_bit(BTN_RIGHT, dev->keybit);
++      }
++}
++
++/*
+  * Set the appropriate event bits for the input subsystem
+  */
+ static int elantech_set_input_params(struct psmouse *psmouse)
+@@ -1026,6 +1065,8 @@ static int elantech_set_input_params(str
+               __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
+               /* fall through */
+       case 3:
++              if (etd->hw_version == 3)
++                      elantech_set_buttonpad_prop(psmouse);
+               input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
+               input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
+               if (etd->reports_pressure) {
+@@ -1047,9 +1088,7 @@ static int elantech_set_input_params(str
+                        */
+                       psmouse_warn(psmouse, "couldn't query resolution data.\n");
+               }
+-              /* v4 is clickpad, with only one button. */
+-              __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
+-              __clear_bit(BTN_RIGHT, dev->keybit);
++              elantech_set_buttonpad_prop(psmouse);
+               __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
+               /* For X to recognize me as touchpad. */
+               input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
diff --git a/queue-3.13/input-wacom-add-reporting-of-sw_mute_device-events.patch b/queue-3.13/input-wacom-add-reporting-of-sw_mute_device-events.patch
new file mode 100644 (file)
index 0000000..c79472f
--- /dev/null
@@ -0,0 +1,150 @@
+From 961794a00eab03f4344b7d5e825e8e789e55da87 Mon Sep 17 00:00:00 2001
+From: Ping Cheng <pinglinux@gmail.com>
+Date: Thu, 5 Dec 2013 12:54:53 -0800
+Subject: Input: wacom - add reporting of SW_MUTE_DEVICE events
+
+From: Ping Cheng <pinglinux@gmail.com>
+
+commit 961794a00eab03f4344b7d5e825e8e789e55da87 upstream.
+
+New Intuos series models added a hardware switch to turn touch
+data on/off. The state of the switch is reported periodically
+from the tablet. To report the state the driver will emit SW_MUTE_DEVICE
+events.
+
+Reviewed_by: Chris Bagwell <chris@cnpbagwell.com>
+Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
+Tested-by: Jason Gerecke <killertofu@gmail.com>
+Signed-off-by: Ping Cheng <pingc@wacom.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/tablet/wacom_sys.c |   12 ++++++++++++
+ drivers/input/tablet/wacom_wac.c |   30 +++++++++++++++++++++++++++---
+ drivers/input/tablet/wacom_wac.h |    5 +++++
+ 3 files changed, 44 insertions(+), 3 deletions(-)
+
+--- a/drivers/input/tablet/wacom_sys.c
++++ b/drivers/input/tablet/wacom_sys.c
+@@ -1197,6 +1197,8 @@ static void wacom_wireless_work(struct w
+               wacom_wac1->features.device_type = BTN_TOOL_PEN;
+               snprintf(wacom_wac1->name, WACOM_NAME_MAX, "%s (WL) Pen",
+                        wacom_wac1->features.name);
++              wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max;
++              wacom_wac1->shared->type = wacom_wac1->features.type;
+               error = wacom_register_input(wacom1);
+               if (error)
+                       goto fail;
+@@ -1218,6 +1220,10 @@ static void wacom_wireless_work(struct w
+                       error = wacom_register_input(wacom2);
+                       if (error)
+                               goto fail;
++
++                      if (wacom_wac1->features.type == INTUOSHT &&
++                          wacom_wac1->features.touch_max)
++                              wacom_wac->shared->touch_input = wacom_wac2->input;
+               }
+               error = wacom_initialize_battery(wacom);
+@@ -1396,6 +1402,12 @@ static int wacom_probe(struct usb_interf
+                       goto fail5;
+               }
+       }
++
++      if (wacom_wac->features.type == INTUOSHT && wacom_wac->features.touch_max) {
++              if (wacom_wac->features.device_type == BTN_TOOL_FINGER)
++                      wacom_wac->shared->touch_input = wacom_wac->input;
++      }
++
+       return 0;
+  fail5: wacom_destroy_leds(wacom);
+--- a/drivers/input/tablet/wacom_wac.c
++++ b/drivers/input/tablet/wacom_wac.c
+@@ -1219,13 +1219,23 @@ static int wacom_bpt3_touch(struct wacom
+ static int wacom_bpt_pen(struct wacom_wac *wacom)
+ {
++      struct wacom_features *features = &wacom->features;
+       struct input_dev *input = wacom->input;
+       unsigned char *data = wacom->data;
+       int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
+-      if (data[0] != WACOM_REPORT_PENABLED)
++      if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_USB)
+           return 0;
++      if (data[0] == WACOM_REPORT_USB) {
++              if (features->type == INTUOSHT && features->touch_max) {
++                      input_report_switch(wacom->shared->touch_input,
++                                          SW_MUTE_DEVICE, data[8] & 0x40);
++                      input_sync(wacom->shared->touch_input);
++              }
++              return 0;
++      }
++
+       prox = (data[1] & 0x20) == 0x20;
+       /*
+@@ -1258,8 +1268,8 @@ static int wacom_bpt_pen(struct wacom_wa
+                * touching and applying pressure; do not report negative
+                * distance.
+                */
+-              if (data[8] <= wacom->features.distance_max)
+-                      d = wacom->features.distance_max - data[8];
++              if (data[8] <= features->distance_max)
++                      d = features->distance_max - data[8];
+               pen = data[1] & 0x01;
+               btn1 = data[1] & 0x02;
+@@ -1310,6 +1320,13 @@ static int wacom_wireless_irq(struct wac
+       if (connected) {
+               int pid, battery;
++              if ((wacom->shared->type == INTUOSHT) &&
++                              wacom->shared->touch_max) {
++                      input_report_switch(wacom->shared->touch_input,
++                                      SW_MUTE_DEVICE, data[5] & 0x40);
++                      input_sync(wacom->shared->touch_input);
++              }
++
+               pid = get_unaligned_be16(&data[6]);
+               battery = data[5] & 0x3f;
+               if (wacom->pid != pid) {
+@@ -1779,6 +1796,13 @@ int wacom_setup_input_capabilities(struc
+               break;
+       case INTUOSHT:
++              if (features->touch_max &&
++                  features->device_type == BTN_TOOL_FINGER) {
++                      input_dev->evbit[0] |= BIT_MASK(EV_SW);
++                      __set_bit(SW_MUTE_DEVICE, input_dev->swbit);
++              }
++              /* fall through */
++
+       case BAMBOO_PT:
+               __clear_bit(ABS_MISC, input_dev->absbit);
+--- a/drivers/input/tablet/wacom_wac.h
++++ b/drivers/input/tablet/wacom_wac.h
+@@ -55,6 +55,7 @@
+ #define WACOM_REPORT_TPC1FGE          18
+ #define WACOM_REPORT_24HDT            1
+ #define WACOM_REPORT_WL                       128
++#define WACOM_REPORT_USB              192
+ /* device quirks */
+ #define WACOM_QUIRK_MULTI_INPUT               0x0001
+@@ -131,6 +132,10 @@ struct wacom_features {
+ struct wacom_shared {
+       bool stylus_in_proximity;
+       bool touch_down;
++      /* for wireless device to access USB interfaces */
++      unsigned touch_max;
++      int type;
++      struct input_dev *touch_input;
+ };
+ struct wacom_wac {
diff --git a/queue-3.13/input-wacom-add-support-for-three-new-intuos-devices.patch b/queue-3.13/input-wacom-add-support-for-three-new-intuos-devices.patch
new file mode 100644 (file)
index 0000000..b19eddd
--- /dev/null
@@ -0,0 +1,211 @@
+From b5fd2a3e92ca5c8c1f3c20d31ac5daed3ec4d604 Mon Sep 17 00:00:00 2001
+From: Ping Cheng <pinglinux@gmail.com>
+Date: Mon, 25 Nov 2013 18:44:55 -0800
+Subject: Input: wacom - add support for three new Intuos devices
+
+From: Ping Cheng <pinglinux@gmail.com>
+
+commit b5fd2a3e92ca5c8c1f3c20d31ac5daed3ec4d604 upstream.
+
+Two tablets in this series support both pen and touch. One (Intuos S)
+only supports pen. This patch also updates the driver to process wireless
+devices that do not support touch interface.
+
+Tested-by: Jason Gerecke <killertofu@gmail.com>
+Reviewed-by: Chris Bagwell <chris@cnpbagwell.com>
+Signed-off-by: Ping Cheng <pingc@wacom.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/tablet/wacom_sys.c |    6 +--
+ drivers/input/tablet/wacom_wac.c |   61 +++++++++++++++++++++++++++++----------
+ drivers/input/tablet/wacom_wac.h |    2 +
+ 3 files changed, 51 insertions(+), 18 deletions(-)
+
+--- a/drivers/input/tablet/wacom_sys.c
++++ b/drivers/input/tablet/wacom_sys.c
+@@ -1202,7 +1202,8 @@ static void wacom_wireless_work(struct w
+                       goto fail;
+               /* Touch interface */
+-              if (wacom_wac1->features.touch_max) {
++              if (wacom_wac1->features.touch_max ||
++                  wacom_wac1->features.type == INTUOSHT) {
+                       wacom_wac2->features =
+                               *((struct wacom_features *)id->driver_info);
+                       wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
+@@ -1325,7 +1326,7 @@ static int wacom_probe(struct usb_interf
+        * HID descriptor. If this is the touch interface (wMaxPacketSize
+        * of WACOM_PKGLEN_BBTOUCH3), override the table values.
+        */
+-      if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
++      if (features->type >= INTUOS5S && features->type <= INTUOSHT) {
+               if (endpoint->wMaxPacketSize == WACOM_PKGLEN_BBTOUCH3) {
+                       features->device_type = BTN_TOOL_FINGER;
+                       features->pktlen = WACOM_PKGLEN_BBTOUCH3;
+@@ -1395,7 +1396,6 @@ static int wacom_probe(struct usb_interf
+                       goto fail5;
+               }
+       }
+-
+       return 0;
+  fail5: wacom_destroy_leds(wacom);
+--- a/drivers/input/tablet/wacom_wac.c
++++ b/drivers/input/tablet/wacom_wac.c
+@@ -1176,10 +1176,16 @@ static void wacom_bpt3_touch_msg(struct
+ static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
+ {
+       struct input_dev *input = wacom->input;
++      struct wacom_features *features = &wacom->features;
+-      input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
++      if (features->type == INTUOSHT) {
++              input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0);
++              input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0);
++      } else {
++              input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
++              input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
++      }
+       input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
+-      input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
+       input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
+ }
+@@ -1217,7 +1223,7 @@ static int wacom_bpt_pen(struct wacom_wa
+       unsigned char *data = wacom->data;
+       int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
+-      if (data[0] != 0x02)
++      if (data[0] != WACOM_REPORT_PENABLED)
+           return 0;
+       prox = (data[1] & 0x20) == 0x20;
+@@ -1297,7 +1303,7 @@ static int wacom_wireless_irq(struct wac
+       unsigned char *data = wacom->data;
+       int connected;
+-      if (len != WACOM_PKGLEN_WIRELESS || data[0] != 0x80)
++      if (len != WACOM_PKGLEN_WIRELESS || data[0] != WACOM_REPORT_WL)
+               return 0;
+       connected = data[1] & 0x01;
+@@ -1391,6 +1397,7 @@ void wacom_wac_irq(struct wacom_wac *wac
+               break;
+       case BAMBOO_PT:
++      case INTUOSHT:
+               sync = wacom_bpt_irq(wacom_wac, len);
+               break;
+@@ -1459,7 +1466,7 @@ void wacom_setup_device_quirks(struct wa
+       /* these device have multiple inputs */
+       if (features->type >= WIRELESS ||
+-          (features->type >= INTUOS5S && features->type <= INTUOSPL) ||
++          (features->type >= INTUOS5S && features->type <= INTUOSHT) ||
+           (features->oVid && features->oPid))
+               features->quirks |= WACOM_QUIRK_MULTI_INPUT;
+@@ -1771,33 +1778,43 @@ int wacom_setup_input_capabilities(struc
+               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+               break;
++      case INTUOSHT:
+       case BAMBOO_PT:
+               __clear_bit(ABS_MISC, input_dev->absbit);
+-              __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+-
+               if (features->device_type == BTN_TOOL_FINGER) {
+-                      unsigned int flags = INPUT_MT_POINTER;
+                       __set_bit(BTN_LEFT, input_dev->keybit);
+                       __set_bit(BTN_FORWARD, input_dev->keybit);
+                       __set_bit(BTN_BACK, input_dev->keybit);
+                       __set_bit(BTN_RIGHT, input_dev->keybit);
+-                      if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
+-                              input_set_abs_params(input_dev,
++                      if (features->touch_max) {
++                              /* touch interface */
++                              unsigned int flags = INPUT_MT_POINTER;
++
++                              __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
++                              if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
++                                      input_set_abs_params(input_dev,
+                                                    ABS_MT_TOUCH_MAJOR,
+                                                    0, features->x_max, 0, 0);
+-                              input_set_abs_params(input_dev,
++                                      input_set_abs_params(input_dev,
+                                                    ABS_MT_TOUCH_MINOR,
+                                                    0, features->y_max, 0, 0);
++                              } else {
++                                      __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
++                                      __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
++                                      flags = 0;
++                              }
++                              input_mt_init_slots(input_dev, features->touch_max, flags);
+                       } else {
+-                              __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+-                              __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+-                              flags = 0;
++                              /* buttons/keys only interface */
++                              __clear_bit(ABS_X, input_dev->absbit);
++                              __clear_bit(ABS_Y, input_dev->absbit);
++                              __clear_bit(BTN_TOUCH, input_dev->keybit);
+                       }
+-                      input_mt_init_slots(input_dev, features->touch_max, flags);
+               } else if (features->device_type == BTN_TOOL_PEN) {
++                      __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+                       __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
+                       __set_bit(BTN_TOOL_PEN, input_dev->keybit);
+                       __set_bit(BTN_STYLUS, input_dev->keybit);
+@@ -2200,6 +2217,17 @@ static const struct wacom_features wacom
+ static const struct wacom_features wacom_features_0x301 =
+       { "Wacom Bamboo One M",    WACOM_PKGLEN_BBPEN,    21648, 13530, 1023,
+         31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
++static const struct wacom_features wacom_features_0x302 =
++      { "Wacom Intuos PT S",     WACOM_PKGLEN_BBPEN,    15200,  9500, 1023,
++        31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
++        .touch_max = 16 };
++static const struct wacom_features wacom_features_0x303 =
++      { "Wacom Intuos PT M",     WACOM_PKGLEN_BBPEN,    21600, 13500, 1023,
++        31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
++        .touch_max = 16 };
++static const struct wacom_features wacom_features_0x30E =
++      { "Wacom Intuos S",        WACOM_PKGLEN_BBPEN,    15200,  9500, 1023,
++        31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ static const struct wacom_features wacom_features_0x6004 =
+       { "ISD-V4",               WACOM_PKGLEN_GRAPHIRE,  12800,  8000,  255,
+         0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+@@ -2337,6 +2365,9 @@ const struct usb_device_id wacom_ids[] =
+       { USB_DEVICE_WACOM(0x10F) },
+       { USB_DEVICE_WACOM(0x300) },
+       { USB_DEVICE_WACOM(0x301) },
++      { USB_DEVICE_DETAILED(0x302, USB_CLASS_HID, 0, 0) },
++      { USB_DEVICE_DETAILED(0x303, USB_CLASS_HID, 0, 0) },
++      { USB_DEVICE_DETAILED(0x30E, USB_CLASS_HID, 0, 0) },
+       { USB_DEVICE_WACOM(0x304) },
+       { USB_DEVICE_DETAILED(0x314, USB_CLASS_HID, 0, 0) },
+       { USB_DEVICE_DETAILED(0x315, USB_CLASS_HID, 0, 0) },
+--- a/drivers/input/tablet/wacom_wac.h
++++ b/drivers/input/tablet/wacom_wac.h
+@@ -54,6 +54,7 @@
+ #define WACOM_REPORT_TPCST            16
+ #define WACOM_REPORT_TPC1FGE          18
+ #define WACOM_REPORT_24HDT            1
++#define WACOM_REPORT_WL                       128
+ /* device quirks */
+ #define WACOM_QUIRK_MULTI_INPUT               0x0001
+@@ -81,6 +82,7 @@ enum {
+       INTUOSPS,
+       INTUOSPM,
+       INTUOSPL,
++      INTUOSHT,
+       WACOM_21UX2,
+       WACOM_22HD,
+       DTK,
diff --git a/queue-3.13/input-wacom-make-sure-touch_max-is-set-for-touch-devices.patch b/queue-3.13/input-wacom-make-sure-touch_max-is-set-for-touch-devices.patch
new file mode 100644 (file)
index 0000000..4282057
--- /dev/null
@@ -0,0 +1,55 @@
+From 1d0d6df02750b4a6f466768cbfbf860e24f4c8d4 Mon Sep 17 00:00:00 2001
+From: Ping Cheng <pinglinux@gmail.com>
+Date: Mon, 25 Nov 2013 18:43:45 -0800
+Subject: Input: wacom - make sure touch_max is set for touch devices
+
+From: Ping Cheng <pinglinux@gmail.com>
+
+commit 1d0d6df02750b4a6f466768cbfbf860e24f4c8d4 upstream.
+
+Old single touch Tablet PCs do not have touch_max set at
+wacom_features. Since touch device at lease supports one
+finger, assign touch_max to 1 when touch usage is defined
+in its HID Descriptor and touch_max is not pre-defined.
+
+Tested-by: Jason Gerecke <killertofu@gmail.com>
+Signed-off-by: Ping Cheng <pingc@wacom.com>
+Reviewed-by: Chris Bagwell <chris@cnpbagwell.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/tablet/wacom_sys.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/input/tablet/wacom_sys.c
++++ b/drivers/input/tablet/wacom_sys.c
+@@ -304,7 +304,7 @@ static int wacom_parse_hid(struct usb_in
+       struct usb_device *dev = interface_to_usbdev(intf);
+       char limit = 0;
+       /* result has to be defined as int for some devices */
+-      int result = 0;
++      int result = 0, touch_max = 0;
+       int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
+       unsigned char *report;
+@@ -351,7 +351,8 @@ static int wacom_parse_hid(struct usb_in
+                               if (usage == WCM_DESKTOP) {
+                                       if (finger) {
+                                               features->device_type = BTN_TOOL_FINGER;
+-
++                                              /* touch device at least supports one touch point */
++                                              touch_max = 1;
+                                               switch (features->type) {
+                                               case TABLETPC2FG:
+                                                       features->pktlen = WACOM_PKGLEN_TPC2FG;
+@@ -504,6 +505,8 @@ static int wacom_parse_hid(struct usb_in
+       }
+  out:
++      if (!features->touch_max && touch_max)
++              features->touch_max = touch_max;
+       result = 0;
+       kfree(report);
+       return result;
diff --git a/queue-3.13/kvm-mmu-handle-invalid-root_hpa-at-__direct_map.patch b/queue-3.13/kvm-mmu-handle-invalid-root_hpa-at-__direct_map.patch
new file mode 100644 (file)
index 0000000..fc4ffc2
--- /dev/null
@@ -0,0 +1,43 @@
+From 989c6b34f6a9480e397b170cc62237e89bf4fdb9 Mon Sep 17 00:00:00 2001
+From: Marcelo Tosatti <mtosatti@redhat.com>
+Date: Thu, 19 Dec 2013 15:28:51 -0200
+Subject: KVM: MMU: handle invalid root_hpa at __direct_map
+
+From: Marcelo Tosatti <mtosatti@redhat.com>
+
+commit 989c6b34f6a9480e397b170cc62237e89bf4fdb9 upstream.
+
+It is possible for __direct_map to be called on invalid root_hpa
+(-1), two examples:
+
+1) try_async_pf -> can_do_async_pf
+    -> vmx_interrupt_allowed -> nested_vmx_vmexit
+2) vmx_handle_exit -> vmx_interrupt_allowed -> nested_vmx_vmexit
+
+Then to load_vmcs12_host_state and kvm_mmu_reset_context.
+
+Check for this possibility, let fault exception be regenerated.
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=924916
+
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/mmu.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/x86/kvm/mmu.c
++++ b/arch/x86/kvm/mmu.c
+@@ -2659,6 +2659,9 @@ static int __direct_map(struct kvm_vcpu
+       int emulate = 0;
+       gfn_t pseudo_gfn;
++      if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
++              return 0;
++
+       for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
+               if (iterator.level == level) {
+                       mmu_set_spte(vcpu, iterator.sptep, ACC_ALL,
diff --git a/queue-3.13/kvm-vmx-fix-use-after-free-of-vmx-loaded_vmcs.patch b/queue-3.13/kvm-vmx-fix-use-after-free-of-vmx-loaded_vmcs.patch
new file mode 100644 (file)
index 0000000..43d1240
--- /dev/null
@@ -0,0 +1,39 @@
+From 26a865f4aa8e66a6d94958de7656f7f1b03c6c56 Mon Sep 17 00:00:00 2001
+From: Marcelo Tosatti <mtosatti@redhat.com>
+Date: Fri, 3 Jan 2014 17:00:51 -0200
+Subject: KVM: VMX: fix use after free of vmx->loaded_vmcs
+
+From: Marcelo Tosatti <mtosatti@redhat.com>
+
+commit 26a865f4aa8e66a6d94958de7656f7f1b03c6c56 upstream.
+
+After free_loaded_vmcs executes, the "loaded_vmcs" structure
+is kfreed, and now vmx->loaded_vmcs points to a kfreed area.
+Subsequent free_loaded_vmcs then attempts to manipulate
+vmx->loaded_vmcs.
+
+Switch the order to avoid the problem.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1047892
+
+Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/vmx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -7332,8 +7332,8 @@ static void vmx_free_vcpu(struct kvm_vcp
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+       free_vpid(vmx);
+-      free_nested(vmx);
+       free_loaded_vmcs(vmx->loaded_vmcs);
++      free_nested(vmx);
+       kfree(vmx->guest_msrs);
+       kvm_vcpu_uninit(vcpu);
+       kmem_cache_free(kvm_vcpu_cache, vmx);
diff --git a/queue-3.13/kvm-x86-handle-invalid-root_hpa-everywhere.patch b/queue-3.13/kvm-x86-handle-invalid-root_hpa-everywhere.patch
new file mode 100644 (file)
index 0000000..75829a8
--- /dev/null
@@ -0,0 +1,77 @@
+From 37f6a4e237303549c8676dfe1fd1991ceab512eb Mon Sep 17 00:00:00 2001
+From: Marcelo Tosatti <mtosatti@redhat.com>
+Date: Fri, 3 Jan 2014 17:09:32 -0200
+Subject: KVM: x86: handle invalid root_hpa everywhere
+
+From: Marcelo Tosatti <mtosatti@redhat.com>
+
+commit 37f6a4e237303549c8676dfe1fd1991ceab512eb upstream.
+
+Rom Freiman <rom@stratoscale.com> notes other code paths vulnerable to
+bug fixed by 989c6b34f6a9480e397b.
+
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/mmu.c         |    9 +++++++++
+ arch/x86/kvm/paging_tmpl.h |    8 ++++++++
+ 2 files changed, 17 insertions(+)
+
+--- a/arch/x86/kvm/mmu.c
++++ b/arch/x86/kvm/mmu.c
+@@ -2832,6 +2832,9 @@ static bool fast_page_fault(struct kvm_v
+       bool ret = false;
+       u64 spte = 0ull;
++      if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
++              return false;
++
+       if (!page_fault_can_be_fast(error_code))
+               return false;
+@@ -3227,6 +3230,9 @@ static u64 walk_shadow_page_get_mmio_spt
+       struct kvm_shadow_walk_iterator iterator;
+       u64 spte = 0ull;
++      if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
++              return spte;
++
+       walk_shadow_page_lockless_begin(vcpu);
+       for_each_shadow_entry_lockless(vcpu, addr, iterator, spte)
+               if (!is_shadow_present_pte(spte))
+@@ -4513,6 +4519,9 @@ int kvm_mmu_get_spte_hierarchy(struct kv
+       u64 spte;
+       int nr_sptes = 0;
++      if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
++              return nr_sptes;
++
+       walk_shadow_page_lockless_begin(vcpu);
+       for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
+               sptes[iterator.level-1] = spte;
+--- a/arch/x86/kvm/paging_tmpl.h
++++ b/arch/x86/kvm/paging_tmpl.h
+@@ -569,6 +569,9 @@ static int FNAME(fetch)(struct kvm_vcpu
+       if (FNAME(gpte_changed)(vcpu, gw, top_level))
+               goto out_gpte_changed;
++      if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
++              goto out_gpte_changed;
++
+       for (shadow_walk_init(&it, vcpu, addr);
+            shadow_walk_okay(&it) && it.level > gw->level;
+            shadow_walk_next(&it)) {
+@@ -820,6 +823,11 @@ static void FNAME(invlpg)(struct kvm_vcp
+        */
+       mmu_topup_memory_caches(vcpu);
++      if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) {
++              WARN_ON(1);
++              return;
++      }
++
+       spin_lock(&vcpu->kvm->mmu_lock);
+       for_each_shadow_entry(vcpu, gva, iterator) {
+               level = iterator.level;
diff --git a/queue-3.13/powerpc-eeh-handle-multiple-eeh-errors.patch b/queue-3.13/powerpc-eeh-handle-multiple-eeh-errors.patch
new file mode 100644 (file)
index 0000000..cd15e6e
--- /dev/null
@@ -0,0 +1,318 @@
+From 7e4e7867b1e551b7b8f326da3604c47332972bc6 Mon Sep 17 00:00:00 2001
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+Date: Wed, 15 Jan 2014 13:16:11 +0800
+Subject: powerpc/eeh: Handle multiple EEH errors
+
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+
+commit 7e4e7867b1e551b7b8f326da3604c47332972bc6 upstream.
+
+For one PCI error relevant OPAL event, we possibly have multiple
+EEH errors for that. For example, multiple frozen PEs detected on
+different PHBs. Unfortunately, we didn't cover the case. The patch
+enumarates the return value from eeh_ops::next_error() and change
+eeh_handle_special_event() and eeh_ops::next_error() to handle all
+existing EEH errors.
+
+As Ben pointed out, we needn't list_for_each_entry_safe() since we
+are not deleting any PHB from the hose_list and the EEH serialized
+lock should be held while purging EEH events. The patch covers those
+suggestions as well.
+
+Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/include/asm/eeh.h            |   10 ++
+ arch/powerpc/kernel/eeh_driver.c          |  150 +++++++++++++++---------------
+ arch/powerpc/platforms/powernv/eeh-ioda.c |   39 ++++---
+ 3 files changed, 112 insertions(+), 87 deletions(-)
+
+--- a/arch/powerpc/include/asm/eeh.h
++++ b/arch/powerpc/include/asm/eeh.h
+@@ -117,6 +117,16 @@ static inline struct pci_dev *eeh_dev_to
+       return edev ? edev->pdev : NULL;
+ }
++/* Return values from eeh_ops::next_error */
++enum {
++      EEH_NEXT_ERR_NONE = 0,
++      EEH_NEXT_ERR_INF,
++      EEH_NEXT_ERR_FROZEN_PE,
++      EEH_NEXT_ERR_FENCED_PHB,
++      EEH_NEXT_ERR_DEAD_PHB,
++      EEH_NEXT_ERR_DEAD_IOC
++};
++
+ /*
+  * The struct is used to trace the registered EEH operation
+  * callback functions. Actually, those operation callback
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -626,84 +626,90 @@ static void eeh_handle_special_event(voi
+ {
+       struct eeh_pe *pe, *phb_pe;
+       struct pci_bus *bus;
+-      struct pci_controller *hose, *tmp;
++      struct pci_controller *hose;
+       unsigned long flags;
+-      int rc = 0;
++      int rc;
+-      /*
+-       * The return value from next_error() has been classified as follows.
+-       * It might be good to enumerate them. However, next_error() is only
+-       * supported by PowerNV platform for now. So it would be fine to use
+-       * integer directly:
+-       *
+-       * 4 - Dead IOC           3 - Dead PHB
+-       * 2 - Fenced PHB         1 - Frozen PE
+-       * 0 - No error found
+-       *
+-       */
+-      rc = eeh_ops->next_error(&pe);
+-      if (rc <= 0)
+-              return;
+-
+-      switch (rc) {
+-      case 4:
+-              /* Mark all PHBs in dead state */
+-              eeh_serialize_lock(&flags);
+-              list_for_each_entry_safe(hose, tmp,
+-                              &hose_list, list_node) {
+-                      phb_pe = eeh_phb_pe_get(hose);
+-                      if (!phb_pe) continue;
+-                      eeh_pe_state_mark(phb_pe,
+-                              EEH_PE_ISOLATED | EEH_PE_PHB_DEAD);
++      do {
++              rc = eeh_ops->next_error(&pe);
++
++              switch (rc) {
++              case EEH_NEXT_ERR_DEAD_IOC:
++                      /* Mark all PHBs in dead state */
++                      eeh_serialize_lock(&flags);
++
++                      /* Purge all events */
++                      eeh_remove_event(NULL);
++
++                      list_for_each_entry(hose, &hose_list, list_node) {
++                              phb_pe = eeh_phb_pe_get(hose);
++                              if (!phb_pe) continue;
++
++                              eeh_pe_state_mark(phb_pe,
++                                      EEH_PE_ISOLATED | EEH_PE_PHB_DEAD);
++                      }
++
++                      eeh_serialize_unlock(flags);
++
++                      break;
++              case EEH_NEXT_ERR_FROZEN_PE:
++              case EEH_NEXT_ERR_FENCED_PHB:
++              case EEH_NEXT_ERR_DEAD_PHB:
++                      /* Mark the PE in fenced state */
++                      eeh_serialize_lock(&flags);
++
++                      /* Purge all events of the PHB */
++                      eeh_remove_event(pe);
++
++                      if (rc == EEH_NEXT_ERR_DEAD_PHB)
++                              eeh_pe_state_mark(pe,
++                                      EEH_PE_ISOLATED | EEH_PE_PHB_DEAD);
++                      else
++                              eeh_pe_state_mark(pe,
++                                      EEH_PE_ISOLATED | EEH_PE_RECOVERING);
++
++                      eeh_serialize_unlock(flags);
++
++                      break;
++              case EEH_NEXT_ERR_NONE:
++                      return;
++              default:
++                      pr_warn("%s: Invalid value %d from next_error()\n",
++                              __func__, rc);
++                      return;
+               }
+-              eeh_serialize_unlock(flags);
+-              /* Purge all events */
+-              eeh_remove_event(NULL);
+-              break;
+-      case 3:
+-      case 2:
+-      case 1:
+-              /* Mark the PE in fenced state */
+-              eeh_serialize_lock(&flags);
+-              if (rc == 3)
+-                      eeh_pe_state_mark(pe,
+-                              EEH_PE_ISOLATED | EEH_PE_PHB_DEAD);
+-              else
+-                      eeh_pe_state_mark(pe,
+-                              EEH_PE_ISOLATED | EEH_PE_RECOVERING);
+-              eeh_serialize_unlock(flags);
+-
+-              /* Purge all events of the PHB */
+-              eeh_remove_event(pe);
+-              break;
+-      default:
+-              pr_err("%s: Invalid value %d from next_error()\n",
+-                     __func__, rc);
+-              return;
+-      }
+-
+-      /*
+-       * For fenced PHB and frozen PE, it's handled as normal
+-       * event. We have to remove the affected PHBs for dead
+-       * PHB and IOC
+-       */
+-      if (rc == 2 || rc == 1)
+-              eeh_handle_normal_event(pe);
+-      else {
+-              list_for_each_entry_safe(hose, tmp,
+-                      &hose_list, list_node) {
+-                      phb_pe = eeh_phb_pe_get(hose);
+-                      if (!phb_pe || !(phb_pe->state & EEH_PE_PHB_DEAD))
+-                              continue;
+-
+-                      bus = eeh_pe_bus_get(phb_pe);
+-                      /* Notify all devices that they're about to go down. */
+-                      eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
+-                      pcibios_remove_pci_devices(bus);
++              /*
++               * For fenced PHB and frozen PE, it's handled as normal
++               * event. We have to remove the affected PHBs for dead
++               * PHB and IOC
++               */
++              if (rc == EEH_NEXT_ERR_FROZEN_PE ||
++                  rc == EEH_NEXT_ERR_FENCED_PHB) {
++                      eeh_handle_normal_event(pe);
++              } else {
++                      list_for_each_entry(hose, &hose_list, list_node) {
++                              phb_pe = eeh_phb_pe_get(hose);
++                              if (!phb_pe ||
++                                  !(phb_pe->state & EEH_PE_PHB_DEAD))
++                                      continue;
++
++                              /* Notify all devices to be down */
++                              bus = eeh_pe_bus_get(phb_pe);
++                              eeh_pe_dev_traverse(pe,
++                                      eeh_report_failure, NULL);
++                              pcibios_remove_pci_devices(bus);
++                      }
+               }
+-      }
++
++              /*
++               * If we have detected dead IOC, we needn't proceed
++               * any more since all PHBs would have been removed
++               */
++              if (rc == EEH_NEXT_ERR_DEAD_IOC)
++                      break;
++      } while (rc != EEH_NEXT_ERR_NONE);
+ }
+ /**
+--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
++++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
+@@ -718,12 +718,12 @@ static int ioda_eeh_get_pe(struct pci_co
+  */
+ static int ioda_eeh_next_error(struct eeh_pe **pe)
+ {
+-      struct pci_controller *hose, *tmp;
++      struct pci_controller *hose;
+       struct pnv_phb *phb;
+       u64 frozen_pe_no;
+       u16 err_type, severity;
+       long rc;
+-      int ret = 1;
++      int ret = EEH_NEXT_ERR_NONE;
+       /*
+        * While running here, it's safe to purge the event queue.
+@@ -733,7 +733,7 @@ static int ioda_eeh_next_error(struct ee
+       eeh_remove_event(NULL);
+       opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
+-      list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
++      list_for_each_entry(hose, &hose_list, list_node) {
+               /*
+                * If the subordinate PCI buses of the PHB has been
+                * removed, we needn't take care of it any more.
+@@ -772,19 +772,19 @@ static int ioda_eeh_next_error(struct ee
+               switch (err_type) {
+               case OPAL_EEH_IOC_ERROR:
+                       if (severity == OPAL_EEH_SEV_IOC_DEAD) {
+-                              list_for_each_entry_safe(hose, tmp,
+-                                              &hose_list, list_node) {
++                              list_for_each_entry(hose, &hose_list,
++                                                  list_node) {
+                                       phb = hose->private_data;
+                                       phb->eeh_state |= PNV_EEH_STATE_REMOVED;
+                               }
+                               pr_err("EEH: dead IOC detected\n");
+-                              ret = 4;
+-                              goto out;
++                              ret = EEH_NEXT_ERR_DEAD_IOC;
+                       } else if (severity == OPAL_EEH_SEV_INF) {
+                               pr_info("EEH: IOC informative error "
+                                       "detected\n");
+                               ioda_eeh_hub_diag(hose);
++                              ret = EEH_NEXT_ERR_NONE;
+                       }
+                       break;
+@@ -796,21 +796,20 @@ static int ioda_eeh_next_error(struct ee
+                               pr_err("EEH: dead PHB#%x detected\n",
+                                       hose->global_number);
+                               phb->eeh_state |= PNV_EEH_STATE_REMOVED;
+-                              ret = 3;
+-                              goto out;
++                              ret = EEH_NEXT_ERR_DEAD_PHB;
+                       } else if (severity == OPAL_EEH_SEV_PHB_FENCED) {
+                               if (ioda_eeh_get_phb_pe(hose, pe))
+                                       break;
+                               pr_err("EEH: fenced PHB#%x detected\n",
+                                       hose->global_number);
+-                              ret = 2;
+-                              goto out;
++                              ret = EEH_NEXT_ERR_FENCED_PHB;
+                       } else if (severity == OPAL_EEH_SEV_INF) {
+                               pr_info("EEH: PHB#%x informative error "
+                                       "detected\n",
+                                       hose->global_number);
+                               ioda_eeh_phb_diag(hose);
++                              ret = EEH_NEXT_ERR_NONE;
+                       }
+                       break;
+@@ -820,13 +819,23 @@ static int ioda_eeh_next_error(struct ee
+                       pr_err("EEH: Frozen PE#%x on PHB#%x detected\n",
+                               (*pe)->addr, (*pe)->phb->global_number);
+-                      ret = 1;
+-                      goto out;
++                      ret = EEH_NEXT_ERR_FROZEN_PE;
++                      break;
++              default:
++                      pr_warn("%s: Unexpected error type %d\n",
++                              __func__, err_type);
+               }
++
++              /*
++               * If we have no errors on the specific PHB or only
++               * informative error there, we continue poking it.
++               * Otherwise, we need actions to be taken by upper
++               * layer.
++               */
++              if (ret > EEH_NEXT_ERR_INF)
++                      break;
+       }
+-      ret = 0;
+-out:
+       return ret;
+ }
diff --git a/queue-3.13/powerpc-powernv-dump-phb-diag-data-immediately.patch b/queue-3.13/powerpc-powernv-dump-phb-diag-data-immediately.patch
new file mode 100644 (file)
index 0000000..929664d
--- /dev/null
@@ -0,0 +1,184 @@
+From 947166043732b69878123bf31f51933ad0316080 Mon Sep 17 00:00:00 2001
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+Date: Tue, 25 Feb 2014 15:28:37 +0800
+Subject: powerpc/powernv: Dump PHB diag-data immediately
+
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+
+commit 947166043732b69878123bf31f51933ad0316080 upstream.
+
+The PHB diag-data is important to help locating the root cause for
+EEH errors such as frozen PE or fenced PHB. However, the EEH core
+enables IO path by clearing part of HW registers before collecting
+this data causing it to be corrupted.
+
+This patch fixes this by dumping the PHB diag-data immediately when
+frozen/fenced state on PE or PHB is detected for the first time in
+eeh_ops::get_state() or next_error() backend.
+
+Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
+CC: <stable@vger.kernel.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/eeh-ioda.c |   99 +++++++++++++-----------------
+ 1 file changed, 43 insertions(+), 56 deletions(-)
+
+--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
++++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
+@@ -114,6 +114,7 @@ DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbB_db
+                       ioda_eeh_inbB_dbgfs_set, "0x%llx\n");
+ #endif /* CONFIG_DEBUG_FS */
++
+ /**
+  * ioda_eeh_post_init - Chip dependent post initialization
+  * @hose: PCI controller
+@@ -221,6 +222,22 @@ static int ioda_eeh_set_option(struct ee
+       return ret;
+ }
++static void ioda_eeh_phb_diag(struct pci_controller *hose)
++{
++      struct pnv_phb *phb = hose->private_data;
++      long rc;
++
++      rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob,
++                                       PNV_PCI_DIAG_BUF_SIZE);
++      if (rc != OPAL_SUCCESS) {
++              pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n",
++                          __func__, hose->global_number, rc);
++              return;
++      }
++
++      pnv_pci_dump_phb_diag_data(hose, phb->diag.blob);
++}
++
+ /**
+  * ioda_eeh_get_state - Retrieve the state of PE
+  * @pe: EEH PE
+@@ -272,6 +289,9 @@ static int ioda_eeh_get_state(struct eeh
+                       result |= EEH_STATE_DMA_ACTIVE;
+                       result |= EEH_STATE_MMIO_ENABLED;
+                       result |= EEH_STATE_DMA_ENABLED;
++              } else if (!(pe->state & EEH_PE_ISOLATED)) {
++                      eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
++                      ioda_eeh_phb_diag(hose);
+               }
+               return result;
+@@ -315,6 +335,15 @@ static int ioda_eeh_get_state(struct eeh
+                          __func__, fstate, hose->global_number, pe_no);
+       }
++      /* Dump PHB diag-data for frozen PE */
++      if (result != EEH_STATE_NOT_SUPPORT &&
++          (result & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) !=
++          (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE) &&
++          !(pe->state & EEH_PE_ISOLATED)) {
++              eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
++              ioda_eeh_phb_diag(hose);
++      }
++
+       return result;
+ }
+@@ -530,45 +559,6 @@ static int ioda_eeh_reset(struct eeh_pe
+ }
+ /**
+- * ioda_eeh_get_log - Retrieve error log
+- * @pe: EEH PE
+- * @severity: Severity level of the log
+- * @drv_log: buffer to store the log
+- * @len: space of the log buffer
+- *
+- * The function is used to retrieve error log from P7IOC.
+- */
+-static int ioda_eeh_get_log(struct eeh_pe *pe, int severity,
+-                          char *drv_log, unsigned long len)
+-{
+-      s64 ret;
+-      unsigned long flags;
+-      struct pci_controller *hose = pe->phb;
+-      struct pnv_phb *phb = hose->private_data;
+-
+-      spin_lock_irqsave(&phb->lock, flags);
+-
+-      ret = opal_pci_get_phb_diag_data2(phb->opal_id,
+-                      phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE);
+-      if (ret) {
+-              spin_unlock_irqrestore(&phb->lock, flags);
+-              pr_warning("%s: Can't get log for PHB#%x-PE#%x (%lld)\n",
+-                         __func__, hose->global_number, pe->addr, ret);
+-              return -EIO;
+-      }
+-
+-      /*
+-       * FIXME: We probably need log the error in somewhere.
+-       * Lets make it up in future.
+-       */
+-      /* pr_info("%s", phb->diag.blob); */
+-
+-      spin_unlock_irqrestore(&phb->lock, flags);
+-
+-      return 0;
+-}
+-
+-/**
+  * ioda_eeh_configure_bridge - Configure the PCI bridges for the indicated PE
+  * @pe: EEH PE
+  *
+@@ -649,22 +639,6 @@ static void ioda_eeh_hub_diag(struct pci
+       }
+ }
+-static void ioda_eeh_phb_diag(struct pci_controller *hose)
+-{
+-      struct pnv_phb *phb = hose->private_data;
+-      long rc;
+-
+-      rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob,
+-                                       PNV_PCI_DIAG_BUF_SIZE);
+-      if (rc != OPAL_SUCCESS) {
+-              pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n",
+-                          __func__, hose->global_number, rc);
+-              return;
+-      }
+-
+-      pnv_pci_dump_phb_diag_data(hose, phb->diag.blob);
+-}
+-
+ static int ioda_eeh_get_phb_pe(struct pci_controller *hose,
+                              struct eeh_pe **pe)
+ {
+@@ -827,6 +801,20 @@ static int ioda_eeh_next_error(struct ee
+               }
+               /*
++               * EEH core will try recover from fenced PHB or
++               * frozen PE. In the time for frozen PE, EEH core
++               * enable IO path for that before collecting logs,
++               * but it ruins the site. So we have to dump the
++               * log in advance here.
++               */
++              if ((ret == EEH_NEXT_ERR_FROZEN_PE  ||
++                  ret == EEH_NEXT_ERR_FENCED_PHB) &&
++                  !((*pe)->state & EEH_PE_ISOLATED)) {
++                      eeh_pe_state_mark(*pe, EEH_PE_ISOLATED);
++                      ioda_eeh_phb_diag(hose);
++              }
++
++              /*
+                * If we have no errors on the specific PHB or only
+                * informative error there, we continue poking it.
+                * Otherwise, we need actions to be taken by upper
+@@ -844,7 +832,6 @@ struct pnv_eeh_ops ioda_eeh_ops = {
+       .set_option             = ioda_eeh_set_option,
+       .get_state              = ioda_eeh_get_state,
+       .reset                  = ioda_eeh_reset,
+-      .get_log                = ioda_eeh_get_log,
+       .configure_bridge       = ioda_eeh_configure_bridge,
+       .next_error             = ioda_eeh_next_error
+ };
diff --git a/queue-3.13/powerpc-powernv-refactor-phb-diag-data-dump.patch b/queue-3.13/powerpc-powernv-refactor-phb-diag-data-dump.patch
new file mode 100644 (file)
index 0000000..04428c4
--- /dev/null
@@ -0,0 +1,286 @@
+From af87d2fe95444d107e0c0cf0ba7e20e6716a7bfd Mon Sep 17 00:00:00 2001
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+Date: Tue, 25 Feb 2014 15:28:38 +0800
+Subject: powerpc/powernv: Refactor PHB diag-data dump
+
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+
+commit af87d2fe95444d107e0c0cf0ba7e20e6716a7bfd upstream.
+
+As Ben suggested, the patch prints PHB diag-data with multiple
+fields in one line and omits the line if the fields of that
+line are all zero.
+
+With the patch applied, the PHB3 diag-data dump looks like:
+
+PHB3 PHB#3 Diag-data (Version: 1)
+
+  brdgCtl:     00000002
+  RootSts:     0000000f 00400000 b0830008 00100147 00002000
+  nFir:        0000000000000000 0030006e00000000 0000000000000000
+  PhbSts:      0000001c00000000 0000000000000000
+  Lem:         0000000000100000 42498e327f502eae 0000000000000000
+  InAErr:      8000000000000000 8000000000000000 0402030000000000 0000000000000000
+  PE[  8] A/B: 8480002b00000000 8000000000000000
+
+[ The current diag data is so big that it overflows the printk
+  buffer pretty quickly in cases when we get a handful of errors
+  at once which can happen. --BenH
+]
+
+Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/pci.c |  220 +++++++++++++++++++----------------
+ 1 file changed, 125 insertions(+), 95 deletions(-)
+
+--- a/arch/powerpc/platforms/powernv/pci.c
++++ b/arch/powerpc/platforms/powernv/pci.c
+@@ -134,57 +134,72 @@ static void pnv_pci_dump_p7ioc_diag_data
+       pr_info("P7IOC PHB#%d Diag-data (Version: %d)\n\n",
+               hose->global_number, common->version);
+-      pr_info("  brdgCtl:              %08x\n", data->brdgCtl);
+-
+-      pr_info("  portStatusReg:        %08x\n", data->portStatusReg);
+-      pr_info("  rootCmplxStatus:      %08x\n", data->rootCmplxStatus);
+-      pr_info("  busAgentStatus:       %08x\n", data->busAgentStatus);
+-
+-      pr_info("  deviceStatus:         %08x\n", data->deviceStatus);
+-      pr_info("  slotStatus:           %08x\n", data->slotStatus);
+-      pr_info("  linkStatus:           %08x\n", data->linkStatus);
+-      pr_info("  devCmdStatus:         %08x\n", data->devCmdStatus);
+-      pr_info("  devSecStatus:         %08x\n", data->devSecStatus);
+-
+-      pr_info("  rootErrorStatus:      %08x\n", data->rootErrorStatus);
+-      pr_info("  uncorrErrorStatus:    %08x\n", data->uncorrErrorStatus);
+-      pr_info("  corrErrorStatus:      %08x\n", data->corrErrorStatus);
+-      pr_info("  tlpHdr1:              %08x\n", data->tlpHdr1);
+-      pr_info("  tlpHdr2:              %08x\n", data->tlpHdr2);
+-      pr_info("  tlpHdr3:              %08x\n", data->tlpHdr3);
+-      pr_info("  tlpHdr4:              %08x\n", data->tlpHdr4);
+-      pr_info("  sourceId:             %08x\n", data->sourceId);
+-      pr_info("  errorClass:           %016llx\n", data->errorClass);
+-      pr_info("  correlator:           %016llx\n", data->correlator);
+-      pr_info("  p7iocPlssr:           %016llx\n", data->p7iocPlssr);
+-      pr_info("  p7iocCsr:             %016llx\n", data->p7iocCsr);
+-      pr_info("  lemFir:               %016llx\n", data->lemFir);
+-      pr_info("  lemErrorMask:         %016llx\n", data->lemErrorMask);
+-      pr_info("  lemWOF:               %016llx\n", data->lemWOF);
+-      pr_info("  phbErrorStatus:       %016llx\n", data->phbErrorStatus);
+-      pr_info("  phbFirstErrorStatus:  %016llx\n", data->phbFirstErrorStatus);
+-      pr_info("  phbErrorLog0:         %016llx\n", data->phbErrorLog0);
+-      pr_info("  phbErrorLog1:         %016llx\n", data->phbErrorLog1);
+-      pr_info("  mmioErrorStatus:      %016llx\n", data->mmioErrorStatus);
+-      pr_info("  mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus);
+-      pr_info("  mmioErrorLog0:        %016llx\n", data->mmioErrorLog0);
+-      pr_info("  mmioErrorLog1:        %016llx\n", data->mmioErrorLog1);
+-      pr_info("  dma0ErrorStatus:      %016llx\n", data->dma0ErrorStatus);
+-      pr_info("  dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus);
+-      pr_info("  dma0ErrorLog0:        %016llx\n", data->dma0ErrorLog0);
+-      pr_info("  dma0ErrorLog1:        %016llx\n", data->dma0ErrorLog1);
+-      pr_info("  dma1ErrorStatus:      %016llx\n", data->dma1ErrorStatus);
+-      pr_info("  dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus);
+-      pr_info("  dma1ErrorLog0:        %016llx\n", data->dma1ErrorLog0);
+-      pr_info("  dma1ErrorLog1:        %016llx\n", data->dma1ErrorLog1);
++      if (data->brdgCtl)
++              pr_info("  brdgCtl:     %08x\n",
++                      data->brdgCtl);
++      if (data->portStatusReg || data->rootCmplxStatus ||
++          data->busAgentStatus)
++              pr_info("  UtlSts:      %08x %08x %08x\n",
++                      data->portStatusReg, data->rootCmplxStatus,
++                      data->busAgentStatus);
++      if (data->deviceStatus || data->slotStatus   ||
++          data->linkStatus   || data->devCmdStatus ||
++          data->devSecStatus)
++              pr_info("  RootSts:     %08x %08x %08x %08x %08x\n",
++                      data->deviceStatus, data->slotStatus,
++                      data->linkStatus, data->devCmdStatus,
++                      data->devSecStatus);
++      if (data->rootErrorStatus   || data->uncorrErrorStatus ||
++          data->corrErrorStatus)
++              pr_info("  RootErrSts:  %08x %08x %08x\n",
++                      data->rootErrorStatus, data->uncorrErrorStatus,
++                      data->corrErrorStatus);
++      if (data->tlpHdr1 || data->tlpHdr2 ||
++          data->tlpHdr3 || data->tlpHdr4)
++              pr_info("  RootErrLog:  %08x %08x %08x %08x\n",
++                      data->tlpHdr1, data->tlpHdr2,
++                      data->tlpHdr3, data->tlpHdr4);
++      if (data->sourceId || data->errorClass ||
++          data->correlator)
++              pr_info("  RootErrLog1: %08x %016llx %016llx\n",
++                      data->sourceId, data->errorClass,
++                      data->correlator);
++      if (data->p7iocPlssr || data->p7iocCsr)
++              pr_info("  PhbSts:      %016llx %016llx\n",
++                      data->p7iocPlssr, data->p7iocCsr);
++      if (data->lemFir || data->lemErrorMask ||
++          data->lemWOF)
++              pr_info("  Lem:         %016llx %016llx %016llx\n",
++                      data->lemFir, data->lemErrorMask,
++                      data->lemWOF);
++      if (data->phbErrorStatus || data->phbFirstErrorStatus ||
++          data->phbErrorLog0   || data->phbErrorLog1)
++              pr_info("  PhbErr:      %016llx %016llx %016llx %016llx\n",
++                      data->phbErrorStatus, data->phbFirstErrorStatus,
++                      data->phbErrorLog0, data->phbErrorLog1);
++      if (data->mmioErrorStatus || data->mmioFirstErrorStatus ||
++          data->mmioErrorLog0   || data->mmioErrorLog1)
++              pr_info("  OutErr:      %016llx %016llx %016llx %016llx\n",
++                      data->mmioErrorStatus, data->mmioFirstErrorStatus,
++                      data->mmioErrorLog0, data->mmioErrorLog1);
++      if (data->dma0ErrorStatus || data->dma0FirstErrorStatus ||
++          data->dma0ErrorLog0   || data->dma0ErrorLog1)
++              pr_info("  InAErr:      %016llx %016llx %016llx %016llx\n",
++                      data->dma0ErrorStatus, data->dma0FirstErrorStatus,
++                      data->dma0ErrorLog0, data->dma0ErrorLog1);
++      if (data->dma1ErrorStatus || data->dma1FirstErrorStatus ||
++          data->dma1ErrorLog0   || data->dma1ErrorLog1)
++              pr_info("  InBErr:      %016llx %016llx %016llx %016llx\n",
++                      data->dma1ErrorStatus, data->dma1FirstErrorStatus,
++                      data->dma1ErrorLog0, data->dma1ErrorLog1);
+       for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) {
+               if ((data->pestA[i] >> 63) == 0 &&
+                   (data->pestB[i] >> 63) == 0)
+                       continue;
+-              pr_info("  PE[%3d] PESTA:        %016llx\n", i, data->pestA[i]);
+-              pr_info("          PESTB:        %016llx\n", data->pestB[i]);
++              pr_info("  PE[%3d] A/B: %016llx %016llx\n",
++                      i, data->pestA[i], data->pestB[i]);
+       }
+ }
+@@ -197,62 +212,77 @@ static void pnv_pci_dump_phb3_diag_data(
+       data = (struct OpalIoPhb3ErrorData*)common;
+       pr_info("PHB3 PHB#%d Diag-data (Version: %d)\n\n",
+               hose->global_number, common->version);
+-
+-      pr_info("  brdgCtl:              %08x\n", data->brdgCtl);
+-
+-      pr_info("  portStatusReg:        %08x\n", data->portStatusReg);
+-      pr_info("  rootCmplxStatus:      %08x\n", data->rootCmplxStatus);
+-      pr_info("  busAgentStatus:       %08x\n", data->busAgentStatus);
+-
+-      pr_info("  deviceStatus:         %08x\n", data->deviceStatus);
+-      pr_info("  slotStatus:           %08x\n", data->slotStatus);
+-      pr_info("  linkStatus:           %08x\n", data->linkStatus);
+-      pr_info("  devCmdStatus:         %08x\n", data->devCmdStatus);
+-      pr_info("  devSecStatus:         %08x\n", data->devSecStatus);
+-
+-      pr_info("  rootErrorStatus:      %08x\n", data->rootErrorStatus);
+-      pr_info("  uncorrErrorStatus:    %08x\n", data->uncorrErrorStatus);
+-      pr_info("  corrErrorStatus:      %08x\n", data->corrErrorStatus);
+-      pr_info("  tlpHdr1:              %08x\n", data->tlpHdr1);
+-      pr_info("  tlpHdr2:              %08x\n", data->tlpHdr2);
+-      pr_info("  tlpHdr3:              %08x\n", data->tlpHdr3);
+-      pr_info("  tlpHdr4:              %08x\n", data->tlpHdr4);
+-      pr_info("  sourceId:             %08x\n", data->sourceId);
+-      pr_info("  errorClass:           %016llx\n", data->errorClass);
+-      pr_info("  correlator:           %016llx\n", data->correlator);
+-
+-      pr_info("  nFir:                 %016llx\n", data->nFir);
+-      pr_info("  nFirMask:             %016llx\n", data->nFirMask);
+-      pr_info("  nFirWOF:              %016llx\n", data->nFirWOF);
+-      pr_info("  PhbPlssr:             %016llx\n", data->phbPlssr);
+-      pr_info("  PhbCsr:               %016llx\n", data->phbCsr);
+-      pr_info("  lemFir:               %016llx\n", data->lemFir);
+-      pr_info("  lemErrorMask:         %016llx\n", data->lemErrorMask);
+-      pr_info("  lemWOF:               %016llx\n", data->lemWOF);
+-      pr_info("  phbErrorStatus:       %016llx\n", data->phbErrorStatus);
+-      pr_info("  phbFirstErrorStatus:  %016llx\n", data->phbFirstErrorStatus);
+-      pr_info("  phbErrorLog0:         %016llx\n", data->phbErrorLog0);
+-      pr_info("  phbErrorLog1:         %016llx\n", data->phbErrorLog1);
+-      pr_info("  mmioErrorStatus:      %016llx\n", data->mmioErrorStatus);
+-      pr_info("  mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus);
+-      pr_info("  mmioErrorLog0:        %016llx\n", data->mmioErrorLog0);
+-      pr_info("  mmioErrorLog1:        %016llx\n", data->mmioErrorLog1);
+-      pr_info("  dma0ErrorStatus:      %016llx\n", data->dma0ErrorStatus);
+-      pr_info("  dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus);
+-      pr_info("  dma0ErrorLog0:        %016llx\n", data->dma0ErrorLog0);
+-      pr_info("  dma0ErrorLog1:        %016llx\n", data->dma0ErrorLog1);
+-      pr_info("  dma1ErrorStatus:      %016llx\n", data->dma1ErrorStatus);
+-      pr_info("  dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus);
+-      pr_info("  dma1ErrorLog0:        %016llx\n", data->dma1ErrorLog0);
+-      pr_info("  dma1ErrorLog1:        %016llx\n", data->dma1ErrorLog1);
++      if (data->brdgCtl)
++              pr_info("  brdgCtl:     %08x\n",
++                      data->brdgCtl);
++      if (data->portStatusReg || data->rootCmplxStatus ||
++          data->busAgentStatus)
++              pr_info("  UtlSts:      %08x %08x %08x\n",
++                      data->portStatusReg, data->rootCmplxStatus,
++                      data->busAgentStatus);
++      if (data->deviceStatus || data->slotStatus   ||
++          data->linkStatus   || data->devCmdStatus ||
++          data->devSecStatus)
++              pr_info("  RootSts:     %08x %08x %08x %08x %08x\n",
++                      data->deviceStatus, data->slotStatus,
++                      data->linkStatus, data->devCmdStatus,
++                      data->devSecStatus);
++      if (data->rootErrorStatus || data->uncorrErrorStatus ||
++          data->corrErrorStatus)
++              pr_info("  RootErrSts:  %08x %08x %08x\n",
++                      data->rootErrorStatus, data->uncorrErrorStatus,
++                      data->corrErrorStatus);
++      if (data->tlpHdr1 || data->tlpHdr2 ||
++          data->tlpHdr3 || data->tlpHdr4)
++              pr_info("  RootErrLog:  %08x %08x %08x %08x\n",
++                      data->tlpHdr1, data->tlpHdr2,
++                      data->tlpHdr3, data->tlpHdr4);
++      if (data->sourceId || data->errorClass ||
++          data->correlator)
++              pr_info("  RootErrLog1: %08x %016llx %016llx\n",
++                      data->sourceId, data->errorClass,
++                      data->correlator);
++      if (data->nFir || data->nFirMask ||
++          data->nFirWOF)
++              pr_info("  nFir:        %016llx %016llx %016llx\n",
++                      data->nFir, data->nFirMask,
++                      data->nFirWOF);
++      if (data->phbPlssr || data->phbCsr)
++              pr_info("  PhbSts:      %016llx %016llx\n",
++                      data->phbPlssr, data->phbCsr);
++      if (data->lemFir || data->lemErrorMask ||
++          data->lemWOF)
++              pr_info("  Lem:         %016llx %016llx %016llx\n",
++                      data->lemFir, data->lemErrorMask,
++                      data->lemWOF);
++      if (data->phbErrorStatus || data->phbFirstErrorStatus ||
++          data->phbErrorLog0   || data->phbErrorLog1)
++              pr_info("  PhbErr:      %016llx %016llx %016llx %016llx\n",
++                      data->phbErrorStatus, data->phbFirstErrorStatus,
++                      data->phbErrorLog0, data->phbErrorLog1);
++      if (data->mmioErrorStatus || data->mmioFirstErrorStatus ||
++          data->mmioErrorLog0   || data->mmioErrorLog1)
++              pr_info("  OutErr:      %016llx %016llx %016llx %016llx\n",
++                      data->mmioErrorStatus, data->mmioFirstErrorStatus,
++                      data->mmioErrorLog0, data->mmioErrorLog1);
++      if (data->dma0ErrorStatus || data->dma0FirstErrorStatus ||
++          data->dma0ErrorLog0   || data->dma0ErrorLog1)
++              pr_info("  InAErr:      %016llx %016llx %016llx %016llx\n",
++                      data->dma0ErrorStatus, data->dma0FirstErrorStatus,
++                      data->dma0ErrorLog0, data->dma0ErrorLog1);
++      if (data->dma1ErrorStatus || data->dma1FirstErrorStatus ||
++          data->dma1ErrorLog0   || data->dma1ErrorLog1)
++              pr_info("  InBErr:      %016llx %016llx %016llx %016llx\n",
++                      data->dma1ErrorStatus, data->dma1FirstErrorStatus,
++                      data->dma1ErrorLog0, data->dma1ErrorLog1);
+       for (i = 0; i < OPAL_PHB3_NUM_PEST_REGS; i++) {
+               if ((data->pestA[i] >> 63) == 0 &&
+                   (data->pestB[i] >> 63) == 0)
+                       continue;
+-              pr_info("  PE[%3d] PESTA:        %016llx\n", i, data->pestA[i]);
+-              pr_info("          PESTB:        %016llx\n", data->pestB[i]);
++              pr_info("  PE[%3d] A/B: %016llx %016llx\n",
++                      i, data->pestA[i], data->pestB[i]);
+       }
+ }
index 6ac7257ada7add33e8ef824a2d30628fd80194cd..1625790efd2da8c25801b47c535f889b05bed560 100644 (file)
@@ -29,3 +29,14 @@ mips-fix-build-error-seen-in-some-configurations.patch
 p54-clamp-properly-instead-of-just-truncating.patch
 regulator-core-replace-direct-ops-disable-usage.patch
 powerpc-powernv-move-phb-diag-dump-functions-around.patch
+powerpc-eeh-handle-multiple-eeh-errors.patch
+powerpc-powernv-dump-phb-diag-data-immediately.patch
+powerpc-powernv-refactor-phb-diag-data-dump.patch
+fs-proc-proc_devtree.c-remove-empty-proc-device-tree-when-no-openfirmware-exists.patch
+input-elantech-improve-clickpad-detection.patch
+kvm-mmu-handle-invalid-root_hpa-at-__direct_map.patch
+kvm-x86-handle-invalid-root_hpa-everywhere.patch
+kvm-vmx-fix-use-after-free-of-vmx-loaded_vmcs.patch
+input-wacom-make-sure-touch_max-is-set-for-touch-devices.patch
+input-wacom-add-support-for-three-new-intuos-devices.patch
+input-wacom-add-reporting-of-sw_mute_device-events.patch