From: Greg Kroah-Hartman Date: Tue, 25 Mar 2014 21:18:28 +0000 (-0700) Subject: 3.13-stable patches X-Git-Tag: v3.4.85~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dfab63c4d1a2ec827e8bdfc464cf1631e514162c;p=thirdparty%2Fkernel%2Fstable-queue.git 3.13-stable patches 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 --- 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 index 00000000000..739e7e4626d --- /dev/null +++ b/queue-3.13/fs-proc-proc_devtree.c-remove-empty-proc-device-tree-when-no-openfirmware-exists.patch @@ -0,0 +1,45 @@ +From c1d867a54d426b45da017fbe8e585f8a3064ce8d Mon Sep 17 00:00:00 2001 +From: Dave Jones +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 + +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 +Cc: Al Viro +Cc: Paul Mackerras +Cc: Josh Boyer +Cc: Benjamin Herrenschmidt +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1487684f009 --- /dev/null +++ b/queue-3.13/input-elantech-improve-clickpad-detection.patch @@ -0,0 +1,111 @@ +From c15bdfd5b9831e4cab8cfc118243956e267dd30e Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 16 Dec 2013 07:09:25 -0800 +Subject: Input: elantech - improve clickpad detection + +From: Hans de Goede + +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 +Reviewed-by: Benjamin Tissoires +Signed-off-by: Dmitry Torokhov +Cc: Josh Boyer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c79472f6afb --- /dev/null +++ b/queue-3.13/input-wacom-add-reporting-of-sw_mute_device-events.patch @@ -0,0 +1,150 @@ +From 961794a00eab03f4344b7d5e825e8e789e55da87 Mon Sep 17 00:00:00 2001 +From: Ping Cheng +Date: Thu, 5 Dec 2013 12:54:53 -0800 +Subject: Input: wacom - add reporting of SW_MUTE_DEVICE events + +From: Ping Cheng + +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 +Acked-by: Peter Hutterer +Tested-by: Jason Gerecke +Signed-off-by: Ping Cheng +Signed-off-by: Dmitry Torokhov +Cc: Josh Boyer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b19edddf4ae --- /dev/null +++ b/queue-3.13/input-wacom-add-support-for-three-new-intuos-devices.patch @@ -0,0 +1,211 @@ +From b5fd2a3e92ca5c8c1f3c20d31ac5daed3ec4d604 Mon Sep 17 00:00:00 2001 +From: Ping Cheng +Date: Mon, 25 Nov 2013 18:44:55 -0800 +Subject: Input: wacom - add support for three new Intuos devices + +From: Ping Cheng + +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 +Reviewed-by: Chris Bagwell +Signed-off-by: Ping Cheng +Signed-off-by: Dmitry Torokhov +Cc: Josh Boyer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..42820578e2a --- /dev/null +++ b/queue-3.13/input-wacom-make-sure-touch_max-is-set-for-touch-devices.patch @@ -0,0 +1,55 @@ +From 1d0d6df02750b4a6f466768cbfbf860e24f4c8d4 Mon Sep 17 00:00:00 2001 +From: Ping Cheng +Date: Mon, 25 Nov 2013 18:43:45 -0800 +Subject: Input: wacom - make sure touch_max is set for touch devices + +From: Ping Cheng + +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 +Signed-off-by: Ping Cheng +Reviewed-by: Chris Bagwell +Signed-off-by: Dmitry Torokhov +Cc: Josh Boyer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..fc4ffc23fb4 --- /dev/null +++ b/queue-3.13/kvm-mmu-handle-invalid-root_hpa-at-__direct_map.patch @@ -0,0 +1,43 @@ +From 989c6b34f6a9480e397b170cc62237e89bf4fdb9 Mon Sep 17 00:00:00 2001 +From: Marcelo Tosatti +Date: Thu, 19 Dec 2013 15:28:51 -0200 +Subject: KVM: MMU: handle invalid root_hpa at __direct_map + +From: Marcelo Tosatti + +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 +Signed-off-by: Paolo Bonzini +Cc: Josh Boyer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..43d1240364a --- /dev/null +++ b/queue-3.13/kvm-vmx-fix-use-after-free-of-vmx-loaded_vmcs.patch @@ -0,0 +1,39 @@ +From 26a865f4aa8e66a6d94958de7656f7f1b03c6c56 Mon Sep 17 00:00:00 2001 +From: Marcelo Tosatti +Date: Fri, 3 Jan 2014 17:00:51 -0200 +Subject: KVM: VMX: fix use after free of vmx->loaded_vmcs + +From: Marcelo Tosatti + +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 +Signed-off-by: Marcelo Tosatti +Cc: Josh Boyer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..75829a868c7 --- /dev/null +++ b/queue-3.13/kvm-x86-handle-invalid-root_hpa-everywhere.patch @@ -0,0 +1,77 @@ +From 37f6a4e237303549c8676dfe1fd1991ceab512eb Mon Sep 17 00:00:00 2001 +From: Marcelo Tosatti +Date: Fri, 3 Jan 2014 17:09:32 -0200 +Subject: KVM: x86: handle invalid root_hpa everywhere + +From: Marcelo Tosatti + +commit 37f6a4e237303549c8676dfe1fd1991ceab512eb upstream. + +Rom Freiman notes other code paths vulnerable to +bug fixed by 989c6b34f6a9480e397b. + +Signed-off-by: Marcelo Tosatti +Cc: Josh Boyer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..cd15e6e1fdd --- /dev/null +++ b/queue-3.13/powerpc-eeh-handle-multiple-eeh-errors.patch @@ -0,0 +1,318 @@ +From 7e4e7867b1e551b7b8f326da3604c47332972bc6 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 15 Jan 2014 13:16:11 +0800 +Subject: powerpc/eeh: Handle multiple EEH errors + +From: Gavin Shan + +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 +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..929664d1bb8 --- /dev/null +++ b/queue-3.13/powerpc-powernv-dump-phb-diag-data-immediately.patch @@ -0,0 +1,184 @@ +From 947166043732b69878123bf31f51933ad0316080 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Tue, 25 Feb 2014 15:28:37 +0800 +Subject: powerpc/powernv: Dump PHB diag-data immediately + +From: Gavin Shan + +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 +CC: +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..04428c459f0 --- /dev/null +++ b/queue-3.13/powerpc-powernv-refactor-phb-diag-data-dump.patch @@ -0,0 +1,286 @@ +From af87d2fe95444d107e0c0cf0ba7e20e6716a7bfd Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Tue, 25 Feb 2014 15:28:38 +0800 +Subject: powerpc/powernv: Refactor PHB diag-data dump + +From: Gavin Shan + +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 +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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]); + } + } + diff --git a/queue-3.13/series b/queue-3.13/series index 6ac7257ada7..1625790efd2 100644 --- a/queue-3.13/series +++ b/queue-3.13/series @@ -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