--- /dev/null
+From f62f3c20647ebd5fb6ecb8f0b477b9281c44c10a Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+Date: Tue, 20 Jul 2021 20:43:09 +1000
+Subject: KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+commit f62f3c20647ebd5fb6ecb8f0b477b9281c44c10a upstream.
+
+The kvmppc_rtas_hcall() sets the host rtas_args.rets pointer based on
+the rtas_args.nargs that was provided by the guest. That guest nargs
+value is not range checked, so the guest can cause the host rets pointer
+to be pointed outside the args array. The individual rtas function
+handlers check the nargs and nrets values to ensure they are correct,
+but if they are not, the handlers store a -3 (0xfffffffd) failure
+indication in rets[0] which corrupts host memory.
+
+Fix this by testing up front whether the guest supplied nargs and nret
+would exceed the array size, and fail the hcall directly without storing
+a failure indication to rets[0].
+
+Also expand on a comment about why we kill the guest and try not to
+return errors directly if we have a valid rets[0] pointer.
+
+Fixes: 8e591cb72047 ("KVM: PPC: Book3S: Add infrastructure to implement kernel-side RTAS calls")
+Cc: stable@vger.kernel.org # v3.10+
+Reported-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/kvm/book3s_rtas.c | 25 ++++++++++++++++++++++---
+ 1 file changed, 22 insertions(+), 3 deletions(-)
+
+--- a/arch/powerpc/kvm/book3s_rtas.c
++++ b/arch/powerpc/kvm/book3s_rtas.c
+@@ -242,6 +242,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *v
+ * value so we can restore it on the way out.
+ */
+ orig_rets = args.rets;
++ if (be32_to_cpu(args.nargs) >= ARRAY_SIZE(args.args)) {
++ /*
++ * Don't overflow our args array: ensure there is room for
++ * at least rets[0] (even if the call specifies 0 nret).
++ *
++ * Each handler must then check for the correct nargs and nret
++ * values, but they may always return failure in rets[0].
++ */
++ rc = -EINVAL;
++ goto fail;
++ }
+ args.rets = &args.args[be32_to_cpu(args.nargs)];
+
+ mutex_lock(&vcpu->kvm->arch.rtas_token_lock);
+@@ -269,9 +280,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *v
+ fail:
+ /*
+ * We only get here if the guest has called RTAS with a bogus
+- * args pointer. That means we can't get to the args, and so we
+- * can't fail the RTAS call. So fail right out to userspace,
+- * which should kill the guest.
++ * args pointer or nargs/nret values that would overflow the
++ * array. That means we can't get to the args, and so we can't
++ * fail the RTAS call. So fail right out to userspace, which
++ * should kill the guest.
++ *
++ * SLOF should actually pass the hcall return value from the
++ * rtas handler call in r3, so enter_rtas could be modified to
++ * return a failure indication in r3 and we could return such
++ * errors to the guest rather than failing to host userspace.
++ * However old guests that don't test for failure could then
++ * continue silently after errors, so for now we won't do this.
+ */
+ return rc;
+ }
--- /dev/null
+From d9c57d3ed52a92536f5fa59dc5ccdd58b4875076 Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+Date: Thu, 8 Jul 2021 21:26:22 +1000
+Subject: KVM: PPC: Book3S HV Nested: Sanitise H_ENTER_NESTED TM state
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+commit d9c57d3ed52a92536f5fa59dc5ccdd58b4875076 upstream.
+
+The H_ENTER_NESTED hypercall is handled by the L0, and it is a request
+by the L1 to switch the context of the vCPU over to that of its L2
+guest, and return with an interrupt indication. The L1 is responsible
+for switching some registers to guest context, and the L0 switches
+others (including all the hypervisor privileged state).
+
+If the L2 MSR has TM active, then the L1 is responsible for
+recheckpointing the L2 TM state. Then the L1 exits to L0 via the
+H_ENTER_NESTED hcall, and the L0 saves the TM state as part of the exit,
+and then it recheckpoints the TM state as part of the nested entry and
+finally HRFIDs into the L2 with TM active MSR. Not efficient, but about
+the simplest approach for something that's horrendously complicated.
+
+Problems arise if the L1 exits to the L0 with a TM state which does not
+match the L2 TM state being requested. For example if the L1 is
+transactional but the L2 MSR is non-transactional, or vice versa. The
+L0's HRFID can take a TM Bad Thing interrupt and crash.
+
+Fix this by disallowing H_ENTER_NESTED in TM[T] state entirely, and then
+ensuring that if the L1 is suspended then the L2 must have TM active,
+and if the L1 is not suspended then the L2 must not have TM active.
+
+Fixes: 360cae313702 ("KVM: PPC: Book3S HV: Nested guest entry via hypercall")
+Cc: stable@vger.kernel.org # v4.20+
+Reported-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Acked-by: Michael Neuling <mikey@neuling.org>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/kvm/book3s_hv_nested.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/arch/powerpc/kvm/book3s_hv_nested.c
++++ b/arch/powerpc/kvm/book3s_hv_nested.c
+@@ -301,6 +301,9 @@ long kvmhv_enter_nested_guest(struct kvm
+ if (vcpu->kvm->arch.l1_ptcr == 0)
+ return H_NOT_AVAILABLE;
+
++ if (MSR_TM_TRANSACTIONAL(vcpu->arch.shregs.msr))
++ return H_BAD_MODE;
++
+ /* copy parameters in */
+ hv_ptr = kvmppc_get_gpr(vcpu, 4);
+ regs_ptr = kvmppc_get_gpr(vcpu, 5);
+@@ -321,6 +324,23 @@ long kvmhv_enter_nested_guest(struct kvm
+ if (l2_hv.vcpu_token >= NR_CPUS)
+ return H_PARAMETER;
+
++ /*
++ * L1 must have set up a suspended state to enter the L2 in a
++ * transactional state, and only in that case. These have to be
++ * filtered out here to prevent causing a TM Bad Thing in the
++ * host HRFID. We could synthesize a TM Bad Thing back to the L1
++ * here but there doesn't seem like much point.
++ */
++ if (MSR_TM_SUSPENDED(vcpu->arch.shregs.msr)) {
++ if (!MSR_TM_ACTIVE(l2_regs.msr))
++ return H_BAD_MODE;
++ } else {
++ if (l2_regs.msr & MSR_TS_MASK)
++ return H_BAD_MODE;
++ if (WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_TS_MASK))
++ return H_BAD_MODE;
++ }
++
+ /* translate lpid */
+ l2 = kvmhv_get_nested(vcpu->kvm, l2_hv.lpid, true);
+ if (!l2)
usb-xhci-avoid-renesas_usb_fw.mem-when-it-s-unusable.patch
xhci-fix-lost-usb-2-remote-wake.patch
usb-ehci-prevent-missed-ehci-interrupts-with-edge-triggered-msi.patch
+kvm-ppc-book3s-fix-h_rtas-rets-buffer-overflow.patch
+kvm-ppc-book3s-hv-nested-sanitise-h_enter_nested-tm-state.patch
+usb-hub-disable-usb-3-device-initiated-lpm-if-exit-latency-is-too-high.patch
+usb-hub-fix-link-power-management-max-exit-latency-mel-calculations.patch
--- /dev/null
+From 1b7f56fbc7a1b66967b6114d1b5f5a257c3abae6 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 15 Jul 2021 18:01:22 +0300
+Subject: usb: hub: Disable USB 3 device initiated lpm if exit latency is too high
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 1b7f56fbc7a1b66967b6114d1b5f5a257c3abae6 upstream.
+
+The device initiated link power management U1/U2 states should not be
+enabled in case the system exit latency plus one bus interval (125us) is
+greater than the shortest service interval of any periodic endpoint.
+
+This is the case for both U1 and U2 sytstem exit latencies and link states.
+
+See USB 3.2 section 9.4.9 "Set Feature" for more details
+
+Note, before this patch the host and device initiated U1/U2 lpm states
+were both enabled with lpm. After this patch it's possible to end up with
+only host inititated U1/U2 lpm in case the exit latencies won't allow
+device initiated lpm.
+
+If this case we still want to set the udev->usb3_lpm_ux_enabled flag so
+that sysfs users can see the link may go to U1/U2.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210715150122.1995966-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c | 68 ++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 56 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -4091,6 +4091,47 @@ static int usb_set_lpm_timeout(struct us
+ }
+
+ /*
++ * Don't allow device intiated U1/U2 if the system exit latency + one bus
++ * interval is greater than the minimum service interval of any active
++ * periodic endpoint. See USB 3.2 section 9.4.9
++ */
++static bool usb_device_may_initiate_lpm(struct usb_device *udev,
++ enum usb3_link_state state)
++{
++ unsigned int sel; /* us */
++ int i, j;
++
++ if (state == USB3_LPM_U1)
++ sel = DIV_ROUND_UP(udev->u1_params.sel, 1000);
++ else if (state == USB3_LPM_U2)
++ sel = DIV_ROUND_UP(udev->u2_params.sel, 1000);
++ else
++ return false;
++
++ for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
++ struct usb_interface *intf;
++ struct usb_endpoint_descriptor *desc;
++ unsigned int interval;
++
++ intf = udev->actconfig->interface[i];
++ if (!intf)
++ continue;
++
++ for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++) {
++ desc = &intf->cur_altsetting->endpoint[j].desc;
++
++ if (usb_endpoint_xfer_int(desc) ||
++ usb_endpoint_xfer_isoc(desc)) {
++ interval = (1 << (desc->bInterval - 1)) * 125;
++ if (sel + 125 > interval)
++ return false;
++ }
++ }
++ }
++ return true;
++}
++
++/*
+ * Enable the hub-initiated U1/U2 idle timeouts, and enable device-initiated
+ * U1/U2 entry.
+ *
+@@ -4162,20 +4203,23 @@ static void usb_enable_link_state(struct
+ * U1/U2_ENABLE
+ */
+ if (udev->actconfig &&
+- usb_set_device_initiated_lpm(udev, state, true) == 0) {
+- if (state == USB3_LPM_U1)
+- udev->usb3_lpm_u1_enabled = 1;
+- else if (state == USB3_LPM_U2)
+- udev->usb3_lpm_u2_enabled = 1;
+- } else {
+- /* Don't request U1/U2 entry if the device
+- * cannot transition to U1/U2.
+- */
+- usb_set_lpm_timeout(udev, state, 0);
+- hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state);
++ usb_device_may_initiate_lpm(udev, state)) {
++ if (usb_set_device_initiated_lpm(udev, state, true)) {
++ /*
++ * Request to enable device initiated U1/U2 failed,
++ * better to turn off lpm in this case.
++ */
++ usb_set_lpm_timeout(udev, state, 0);
++ hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state);
++ return;
++ }
+ }
+-}
+
++ if (state == USB3_LPM_U1)
++ udev->usb3_lpm_u1_enabled = 1;
++ else if (state == USB3_LPM_U2)
++ udev->usb3_lpm_u2_enabled = 1;
++}
+ /*
+ * Disable the hub-initiated U1/U2 idle timeouts, and disable device-initiated
+ * U1/U2 entry.
--- /dev/null
+From 1bf2761c837571a66ec290fb66c90413821ffda2 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 15 Jul 2021 18:01:21 +0300
+Subject: usb: hub: Fix link power management max exit latency (MEL) calculations
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 1bf2761c837571a66ec290fb66c90413821ffda2 upstream.
+
+Maximum Exit Latency (MEL) value is used by host to know how much in
+advance it needs to start waking up a U1/U2 suspended link in order to
+service a periodic transfer in time.
+
+Current MEL calculation only includes the time to wake up the path from
+U1/U2 to U0. This is called tMEL1 in USB 3.1 section C 1.5.2
+
+Total MEL = tMEL1 + tMEL2 +tMEL3 + tMEL4 which should additinally include:
+- tMEL2 which is the time it takes for PING message to reach device
+- tMEL3 time for device to process the PING and submit a PING_RESPONSE
+- tMEL4 time for PING_RESPONSE to traverse back upstream to host.
+
+Add the missing tMEL2, tMEL3 and tMEL4 to MEL calculation.
+
+Cc: <stable@kernel.org> # v3.5
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20210715150122.1995966-1-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c | 52 ++++++++++++++++++++++++++-----------------------
+ 1 file changed, 28 insertions(+), 24 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -48,6 +48,7 @@
+
+ #define USB_TP_TRANSMISSION_DELAY 40 /* ns */
+ #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */
++#define USB_PING_RESPONSE_TIME 400 /* ns */
+
+ /* Protect struct usb_device->state and ->children members
+ * Note: Both are also protected by ->dev.sem, except that ->state can
+@@ -182,8 +183,9 @@ int usb_device_supports_lpm(struct usb_d
+ }
+
+ /*
+- * Set the Maximum Exit Latency (MEL) for the host to initiate a transition from
+- * either U1 or U2.
++ * Set the Maximum Exit Latency (MEL) for the host to wakup up the path from
++ * U1/U2, send a PING to the device and receive a PING_RESPONSE.
++ * See USB 3.1 section C.1.5.2
+ */
+ static void usb_set_lpm_mel(struct usb_device *udev,
+ struct usb3_lpm_parameters *udev_lpm_params,
+@@ -193,35 +195,37 @@ static void usb_set_lpm_mel(struct usb_d
+ unsigned int hub_exit_latency)
+ {
+ unsigned int total_mel;
+- unsigned int device_mel;
+- unsigned int hub_mel;
+
+ /*
+- * Calculate the time it takes to transition all links from the roothub
+- * to the parent hub into U0. The parent hub must then decode the
+- * packet (hub header decode latency) to figure out which port it was
+- * bound for.
+- *
+- * The Hub Header decode latency is expressed in 0.1us intervals (0x1
+- * means 0.1us). Multiply that by 100 to get nanoseconds.
++ * tMEL1. time to transition path from host to device into U0.
++ * MEL for parent already contains the delay up to parent, so only add
++ * the exit latency for the last link (pick the slower exit latency),
++ * and the hub header decode latency. See USB 3.1 section C 2.2.1
++ * Store MEL in nanoseconds
+ */
+ total_mel = hub_lpm_params->mel +
+- (hub->descriptor->u.ss.bHubHdrDecLat * 100);
++ max(udev_exit_latency, hub_exit_latency) * 1000 +
++ hub->descriptor->u.ss.bHubHdrDecLat * 100;
+
+ /*
+- * How long will it take to transition the downstream hub's port into
+- * U0? The greater of either the hub exit latency or the device exit
+- * latency.
+- *
+- * The BOS U1/U2 exit latencies are expressed in 1us intervals.
+- * Multiply that by 1000 to get nanoseconds.
++ * tMEL2. Time to submit PING packet. Sum of tTPTransmissionDelay for
++ * each link + wHubDelay for each hub. Add only for last link.
++ * tMEL4, the time for PING_RESPONSE to traverse upstream is similar.
++ * Multiply by 2 to include it as well.
+ */
+- device_mel = udev_exit_latency * 1000;
+- hub_mel = hub_exit_latency * 1000;
+- if (device_mel > hub_mel)
+- total_mel += device_mel;
+- else
+- total_mel += hub_mel;
++ total_mel += (__le16_to_cpu(hub->descriptor->u.ss.wHubDelay) +
++ USB_TP_TRANSMISSION_DELAY) * 2;
++
++ /*
++ * tMEL3, tPingResponse. Time taken by device to generate PING_RESPONSE
++ * after receiving PING. Also add 2100ns as stated in USB 3.1 C 1.5.2.4
++ * to cover the delay if the PING_RESPONSE is queued behind a Max Packet
++ * Size DP.
++ * Note these delays should be added only once for the entire path, so
++ * add them to the MEL of the device connected to the roothub.
++ */
++ if (!hub->hdev->parent)
++ total_mel += USB_PING_RESPONSE_TIME + 2100;
+
+ udev_lpm_params->mel = total_mel;
+ }