From: Greg Kroah-Hartman Date: Tue, 13 May 2008 16:37:19 +0000 (-0700) Subject: more .25 patches added X-Git-Tag: v2.6.25.4~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3d177385463221db0c566ffb79a2feef0c35b8aa;p=thirdparty%2Fkernel%2Fstable-queue.git more .25 patches added --- diff --git a/queue-2.6.25/can-fix-can_send-handling-on-dev_queue_xmit-failures.patch b/queue-2.6.25/can-fix-can_send-handling-on-dev_queue_xmit-failures.patch new file mode 100644 index 00000000000..97032376795 --- /dev/null +++ b/queue-2.6.25/can-fix-can_send-handling-on-dev_queue_xmit-failures.patch @@ -0,0 +1,74 @@ +From 5b10ebf13d0cda519ac15382c33c178c945af99e Mon Sep 17 00:00:00 2001 +From: Oliver Hartkopp +Date: Thu, 8 May 2008 02:49:55 -0700 +Subject: can: Fix can_send() handling on dev_queue_xmit() failures + +From: Oliver Hartkopp + +[ Upstream commit: c2ab7ac225e29006b7117d6a9fe8f3be8d98b0c2 ] + +The tx packet counting and the local loopback of CAN frames should +only happen in the case that the CAN frame has been enqueued to the +netdevice tx queue successfully. + +Thanks to Andre Naujoks for reporting this issue. + +Signed-off-by: Oliver Hartkopp +Signed-off-by: Urs Thuermann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/can/af_can.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/net/can/af_can.c ++++ b/net/can/af_can.c +@@ -208,6 +208,7 @@ static int can_create(struct net *net, s + */ + int can_send(struct sk_buff *skb, int loop) + { ++ struct sk_buff *newskb = NULL; + int err; + + if (skb->dev->type != ARPHRD_CAN) { +@@ -244,8 +245,7 @@ int can_send(struct sk_buff *skb, int lo + * If the interface is not capable to do loopback + * itself, we do it here. + */ +- struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); +- ++ newskb = skb_clone(skb, GFP_ATOMIC); + if (!newskb) { + kfree_skb(skb); + return -ENOMEM; +@@ -254,7 +254,6 @@ int can_send(struct sk_buff *skb, int lo + newskb->sk = skb->sk; + newskb->ip_summed = CHECKSUM_UNNECESSARY; + newskb->pkt_type = PACKET_BROADCAST; +- netif_rx(newskb); + } + } else { + /* indication for the CAN driver: no loopback required */ +@@ -266,11 +265,20 @@ int can_send(struct sk_buff *skb, int lo + if (err > 0) + err = net_xmit_errno(err); + ++ if (err) { ++ if (newskb) ++ kfree_skb(newskb); ++ return err; ++ } ++ ++ if (newskb) ++ netif_rx(newskb); ++ + /* update statistics */ + can_stats.tx_frames++; + can_stats.tx_frames_delta++; + +- return err; ++ return 0; + } + EXPORT_SYMBOL(can_send); + diff --git a/queue-2.6.25/dccp-return-einval-on-invalid-feature-length.patch b/queue-2.6.25/dccp-return-einval-on-invalid-feature-length.patch new file mode 100644 index 00000000000..78ee4b21d8e --- /dev/null +++ b/queue-2.6.25/dccp-return-einval-on-invalid-feature-length.patch @@ -0,0 +1,33 @@ +From 96684accc660434524bb92f420b898ae4edf6a4f Mon Sep 17 00:00:00 2001 +From: Chris Wright +Date: Mon, 5 May 2008 13:50:24 -0700 +Subject: dccp: return -EINVAL on invalid feature length + +From: Chris Wright + +[ Upstream commit: 19443178fbfbf40db15c86012fc37df1a44ab857 ] + +dccp_feat_change() validates length and on error is returning 1. +This happens to work since call chain is checking for 0 == success, +but this is returned to userspace, so make it a real error value. + +Signed-off-by: Chris Wright +Acked-by: Arnaldo Carvalho de Melo +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/dccp/feat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/dccp/feat.c ++++ b/net/dccp/feat.c +@@ -32,7 +32,7 @@ int dccp_feat_change(struct dccp_minisoc + + if (len > 3) { + DCCP_WARN("invalid length %d\n", len); +- return 1; ++ return -EINVAL; + } + /* XXX add further sanity checks */ + diff --git a/queue-2.6.25/ipvs-fix-oops-in-backup-for-fwmark-conn-templates.patch b/queue-2.6.25/ipvs-fix-oops-in-backup-for-fwmark-conn-templates.patch new file mode 100644 index 00000000000..eb5b21a1c97 --- /dev/null +++ b/queue-2.6.25/ipvs-fix-oops-in-backup-for-fwmark-conn-templates.patch @@ -0,0 +1,219 @@ +From 7d44cdf1c9307bd9649a4025d12896984c59199d Mon Sep 17 00:00:00 2001 +From: Julian Anastasov +Date: Tue, 29 Apr 2008 03:21:23 -0700 +Subject: ipvs: fix oops in backup for fwmark conn templates + +From: Julian Anastasov + +[ Upstream commit: 2ad17defd596ca7e8ba782d5fc6950ee0e99513c ] + + Fixes bug http://bugzilla.kernel.org/show_bug.cgi?id=10556 +where conn templates with protocol=IPPROTO_IP can oops backup box. + + Result from ip_vs_proto_get() should be checked because +protocol value can be invalid or unsupported in backup. But +for valid message we should not fail for templates which use +IPPROTO_IP. Also, add checks to validate message limits and +connection state. Show state NONE for templates using IPPROTO_IP. + +Fix tested and confirmed by L0op8ack + +Signed-off-by: Julian Anastasov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/ip_vs.h | 3 + + net/ipv4/ipvs/ip_vs_proto.c | 2 - + net/ipv4/ipvs/ip_vs_proto_ah.c | 1 + net/ipv4/ipvs/ip_vs_proto_esp.c | 1 + net/ipv4/ipvs/ip_vs_proto_tcp.c | 1 + net/ipv4/ipvs/ip_vs_proto_udp.c | 1 + net/ipv4/ipvs/ip_vs_sync.c | 80 +++++++++++++++++++++++++++++----------- + 7 files changed, 66 insertions(+), 23 deletions(-) + +--- a/include/net/ip_vs.h ++++ b/include/net/ip_vs.h +@@ -405,7 +405,8 @@ struct sk_buff; + struct ip_vs_protocol { + struct ip_vs_protocol *next; + char *name; +- __u16 protocol; ++ u16 protocol; ++ u16 num_states; + int dont_defrag; + atomic_t appcnt; /* counter of proto app incs */ + int *timeout_table; /* protocol timeout table */ +--- a/net/ipv4/ipvs/ip_vs_proto_ah.c ++++ b/net/ipv4/ipvs/ip_vs_proto_ah.c +@@ -160,6 +160,7 @@ static void ah_exit(struct ip_vs_protoco + struct ip_vs_protocol ip_vs_protocol_ah = { + .name = "AH", + .protocol = IPPROTO_AH, ++ .num_states = 1, + .dont_defrag = 1, + .init = ah_init, + .exit = ah_exit, +--- a/net/ipv4/ipvs/ip_vs_proto.c ++++ b/net/ipv4/ipvs/ip_vs_proto.c +@@ -148,7 +148,7 @@ const char * ip_vs_state_name(__u16 prot + struct ip_vs_protocol *pp = ip_vs_proto_get(proto); + + if (pp == NULL || pp->state_name == NULL) +- return "ERR!"; ++ return (IPPROTO_IP == proto) ? "NONE" : "ERR!"; + return pp->state_name(state); + } + +--- a/net/ipv4/ipvs/ip_vs_proto_esp.c ++++ b/net/ipv4/ipvs/ip_vs_proto_esp.c +@@ -159,6 +159,7 @@ static void esp_exit(struct ip_vs_protoc + struct ip_vs_protocol ip_vs_protocol_esp = { + .name = "ESP", + .protocol = IPPROTO_ESP, ++ .num_states = 1, + .dont_defrag = 1, + .init = esp_init, + .exit = esp_exit, +--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c ++++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c +@@ -594,6 +594,7 @@ static void ip_vs_tcp_exit(struct ip_vs_ + struct ip_vs_protocol ip_vs_protocol_tcp = { + .name = "TCP", + .protocol = IPPROTO_TCP, ++ .num_states = IP_VS_TCP_S_LAST, + .dont_defrag = 0, + .appcnt = ATOMIC_INIT(0), + .init = ip_vs_tcp_init, +--- a/net/ipv4/ipvs/ip_vs_proto_udp.c ++++ b/net/ipv4/ipvs/ip_vs_proto_udp.c +@@ -409,6 +409,7 @@ static void udp_exit(struct ip_vs_protoc + struct ip_vs_protocol ip_vs_protocol_udp = { + .name = "UDP", + .protocol = IPPROTO_UDP, ++ .num_states = IP_VS_UDP_S_LAST, + .dont_defrag = 0, + .init = udp_init, + .exit = udp_exit, +--- a/net/ipv4/ipvs/ip_vs_sync.c ++++ b/net/ipv4/ipvs/ip_vs_sync.c +@@ -288,11 +288,16 @@ static void ip_vs_process_message(const + char *p; + int i; + ++ if (buflen < sizeof(struct ip_vs_sync_mesg)) { ++ IP_VS_ERR_RL("sync message header too short\n"); ++ return; ++ } ++ + /* Convert size back to host byte order */ + m->size = ntohs(m->size); + + if (buflen != m->size) { +- IP_VS_ERR("bogus message\n"); ++ IP_VS_ERR_RL("bogus sync message size\n"); + return; + } + +@@ -307,9 +312,48 @@ static void ip_vs_process_message(const + for (i=0; inr_conns; i++) { + unsigned flags, state; + +- s = (struct ip_vs_sync_conn *)p; ++ if (p + SIMPLE_CONN_SIZE > buffer+buflen) { ++ IP_VS_ERR_RL("bogus conn in sync message\n"); ++ return; ++ } ++ s = (struct ip_vs_sync_conn *) p; + flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC; ++ flags &= ~IP_VS_CONN_F_HASHED; ++ if (flags & IP_VS_CONN_F_SEQ_MASK) { ++ opt = (struct ip_vs_sync_conn_options *)&s[1]; ++ p += FULL_CONN_SIZE; ++ if (p > buffer+buflen) { ++ IP_VS_ERR_RL("bogus conn options in sync message\n"); ++ return; ++ } ++ } else { ++ opt = NULL; ++ p += SIMPLE_CONN_SIZE; ++ } ++ + state = ntohs(s->state); ++ if (!(flags & IP_VS_CONN_F_TEMPLATE)) { ++ pp = ip_vs_proto_get(s->protocol); ++ if (!pp) { ++ IP_VS_ERR_RL("Unsupported protocol %u in sync msg\n", ++ s->protocol); ++ continue; ++ } ++ if (state >= pp->num_states) { ++ IP_VS_DBG(2, "Invalid %s state %u in sync msg\n", ++ pp->name, state); ++ continue; ++ } ++ } else { ++ /* protocol in templates is not used for state/timeout */ ++ pp = NULL; ++ if (state > 0) { ++ IP_VS_DBG(2, "Invalid template state %u in sync msg\n", ++ state); ++ state = 0; ++ } ++ } ++ + if (!(flags & IP_VS_CONN_F_TEMPLATE)) + cp = ip_vs_conn_in_get(s->protocol, + s->caddr, s->cport, +@@ -345,14 +389,9 @@ static void ip_vs_process_message(const + IP_VS_ERR("ip_vs_conn_new failed\n"); + return; + } +- cp->state = state; + } else if (!cp->dest) { + dest = ip_vs_try_bind_dest(cp); +- if (!dest) { +- /* it is an unbound entry created by +- * synchronization */ +- cp->flags = flags | IP_VS_CONN_F_HASHED; +- } else ++ if (dest) + atomic_dec(&dest->refcnt); + } else if ((cp->dest) && (cp->protocol == IPPROTO_TCP) && + (cp->state != state)) { +@@ -371,23 +410,22 @@ static void ip_vs_process_message(const + } + } + +- if (flags & IP_VS_CONN_F_SEQ_MASK) { +- opt = (struct ip_vs_sync_conn_options *)&s[1]; ++ if (opt) + memcpy(&cp->in_seq, opt, sizeof(*opt)); +- p += FULL_CONN_SIZE; +- } else +- p += SIMPLE_CONN_SIZE; +- + atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]); + cp->state = state; +- pp = ip_vs_proto_get(s->protocol); +- cp->timeout = pp->timeout_table[cp->state]; ++ cp->old_state = cp->state; ++ /* ++ * We can not recover the right timeout for templates ++ * in all cases, we can not find the right fwmark ++ * virtual service. If needed, we can do it for ++ * non-fwmark persistent services. ++ */ ++ if (!(flags & IP_VS_CONN_F_TEMPLATE) && pp->timeout_table) ++ cp->timeout = pp->timeout_table[state]; ++ else ++ cp->timeout = (3*60*HZ); + ip_vs_conn_put(cp); +- +- if (p > buffer+buflen) { +- IP_VS_ERR("bogus message\n"); +- return; +- } + } + } + diff --git a/queue-2.6.25/macvlan-fix-memleak-on-device-removal-crash-on-module-removal.patch b/queue-2.6.25/macvlan-fix-memleak-on-device-removal-crash-on-module-removal.patch new file mode 100644 index 00000000000..dbc6ce42ef7 --- /dev/null +++ b/queue-2.6.25/macvlan-fix-memleak-on-device-removal-crash-on-module-removal.patch @@ -0,0 +1,38 @@ +From 10a5379f96fc4c302d12976160faa8d4fd8418fd Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Thu, 8 May 2008 01:13:31 -0700 +Subject: macvlan: Fix memleak on device removal/crash on module removal + +From: Patrick McHardy + +[ Upstream commit: 7312096454b6cd71267eaa3d0efb408e449e9ff3 ] + +As noticed by Ben Greear, macvlan crashes the kernel when unloading the +module. The reason is that it tries to clean up the macvlan_port pointer +on the macvlan device itself instead of the underlying device. A non-NULL +pointer is taken as indication that the macvlan_handle_frame_hook is +valid, when receiving the next packet on the underlying device it tries +to call the NULL hook and crashes. + +Clean up the macvlan_port on the correct device to fix this. + +Signed-off-by; Patrick McHardy +Tested-by: Ben Greear +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/macvlan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -450,7 +450,7 @@ static void macvlan_dellink(struct net_d + unregister_netdevice(dev); + + if (list_empty(&port->vlans)) +- macvlan_port_destroy(dev); ++ macvlan_port_destroy(port->dev); + } + + static struct rtnl_link_ops macvlan_link_ops __read_mostly = { diff --git a/queue-2.6.25/ohci-fix-regression-upon-awakening-from-hibernation.patch b/queue-2.6.25/ohci-fix-regression-upon-awakening-from-hibernation.patch new file mode 100644 index 00000000000..d1dad858114 --- /dev/null +++ b/queue-2.6.25/ohci-fix-regression-upon-awakening-from-hibernation.patch @@ -0,0 +1,224 @@ +From stern@rowland.harvard.edu Tue May 13 09:26:08 2008 +From: Alan Stern +Date: Thu, 8 May 2008 14:21:22 -0400 (EDT) +Subject: OHCI: fix regression upon awakening from hibernation +To: stable@kernel.org +Message-ID: + +From: Alan Stern + +commit 43bbb7e015c4380064796c5868b536437b165615 in upstream + +Drivers in the ohci-hcd family should perform certain tasks whenever +their controller device is resumed. These include checking for loss +of power during suspend, turning on port power, and enabling interrupt +requests. + +Until now these jobs have been carried out when the root hub is +resumed, not when the controller is. Many drivers work around the +resulting awkwardness by automatically resuming their root hub +whenever the controller is resumed. But this is wasteful and +unnecessary. + +In 2.6.25, ohci-pci doesn't even do that. After waking up from +hibernation, it simply leaves the controller in a RESET state, which +is useless. + +To simplify the situation, this patch (as1066b) adds a new core +routine, ohci_finish_controller_resume(), which can be used by all the +OHCI-variant drivers. They can call the new routine instead of +resuming their root hubs. And ohci-pci.c can call it instead of using +its own special-purpose handler. + +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ohci-at91.c | 1 + drivers/usb/host/ohci-ep93xx.c | 2 - + drivers/usb/host/ohci-hub.c | 43 +++++++++++++++++++++++++++++++++++++++++ + drivers/usb/host/ohci-omap.c | 2 - + drivers/usb/host/ohci-pci.c | 43 ----------------------------------------- + drivers/usb/host/ohci-pxa27x.c | 3 -- + drivers/usb/host/ohci-sm501.c | 2 - + drivers/usb/host/ohci-ssb.c | 1 + 8 files changed, 50 insertions(+), 47 deletions(-) + +--- a/drivers/usb/host/ohci-at91.c ++++ b/drivers/usb/host/ohci-at91.c +@@ -348,6 +348,7 @@ static int ohci_hcd_at91_drv_resume(stru + if (!clocked) + at91_start_clock(); + ++ ohci_finish_controller_resume(hcd); + return 0; + } + #else +--- a/drivers/usb/host/ohci-ep93xx.c ++++ b/drivers/usb/host/ohci-ep93xx.c +@@ -194,8 +194,8 @@ static int ohci_hcd_ep93xx_drv_resume(st + + ep93xx_start_hc(&pdev->dev); + pdev->dev.power.power_state = PMSG_ON; +- usb_hcd_resume_root_hub(hcd); + ++ ohci_finish_controller_resume(hcd); + return 0; + } + #endif +--- a/drivers/usb/host/ohci-hub.c ++++ b/drivers/usb/host/ohci-hub.c +@@ -326,6 +326,49 @@ static int ohci_bus_resume (struct usb_h + return rc; + } + ++/* Carry out the final steps of resuming the controller device */ ++static void ohci_finish_controller_resume(struct usb_hcd *hcd) ++{ ++ struct ohci_hcd *ohci = hcd_to_ohci(hcd); ++ int port; ++ bool need_reinit = false; ++ ++ /* See if the controller is already running or has been reset */ ++ ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); ++ if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { ++ need_reinit = true; ++ } else { ++ switch (ohci->hc_control & OHCI_CTRL_HCFS) { ++ case OHCI_USB_OPER: ++ case OHCI_USB_RESET: ++ need_reinit = true; ++ } ++ } ++ ++ /* If needed, reinitialize and suspend the root hub */ ++ if (need_reinit) { ++ spin_lock_irq(&ohci->lock); ++ hcd->state = HC_STATE_RESUMING; ++ ohci_rh_resume(ohci); ++ hcd->state = HC_STATE_QUIESCING; ++ ohci_rh_suspend(ohci, 0); ++ hcd->state = HC_STATE_SUSPENDED; ++ spin_unlock_irq(&ohci->lock); ++ } ++ ++ /* Normally just turn on port power and enable interrupts */ ++ else { ++ ohci_dbg(ohci, "powerup ports\n"); ++ for (port = 0; port < ohci->num_ports; port++) ++ ohci_writel(ohci, RH_PS_PPS, ++ &ohci->regs->roothub.portstatus[port]); ++ ++ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); ++ ohci_readl(ohci, &ohci->regs->intrenable); ++ msleep(20); ++ } ++} ++ + /* Carry out polling-, autostop-, and autoresume-related state changes */ + static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, + int any_connected) +--- a/drivers/usb/host/ohci-omap.c ++++ b/drivers/usb/host/ohci-omap.c +@@ -519,7 +519,7 @@ static int ohci_omap_resume(struct platf + + omap_ohci_clock_power(1); + dev->dev.power.power_state = PMSG_ON; +- usb_hcd_resume_root_hub(platform_get_drvdata(dev)); ++ ohci_finish_controller_resume(hcd); + return 0; + } + +--- a/drivers/usb/host/ohci-pci.c ++++ b/drivers/usb/host/ohci-pci.c +@@ -238,42 +238,6 @@ static int __devinit ohci_pci_start (str + return ret; + } + +-#if defined(CONFIG_USB_PERSIST) && (defined(CONFIG_USB_EHCI_HCD) || \ +- defined(CONFIG_USB_EHCI_HCD_MODULE)) +- +-/* Following a power loss, we must prepare to regain control of the ports +- * we used to own. This means turning on the port power before ehci-hcd +- * tries to switch ownership. +- * +- * This isn't a 100% perfect solution. On most systems the OHCI controllers +- * lie at lower PCI addresses than the EHCI controller, so they will be +- * discovered (and hence resumed) first. But there is no guarantee things +- * will always work this way. If the EHCI controller is resumed first and +- * the OHCI ports are unpowered, then the handover will fail. +- */ +-static void prepare_for_handover(struct usb_hcd *hcd) +-{ +- struct ohci_hcd *ohci = hcd_to_ohci(hcd); +- int port; +- +- /* Here we "know" root ports should always stay powered */ +- ohci_dbg(ohci, "powerup ports\n"); +- for (port = 0; port < ohci->num_ports; port++) +- ohci_writel(ohci, RH_PS_PPS, +- &ohci->regs->roothub.portstatus[port]); +- +- /* Flush those writes */ +- ohci_readl(ohci, &ohci->regs->control); +- msleep(20); +-} +- +-#else +- +-static inline void prepare_for_handover(struct usb_hcd *hcd) +-{ } +- +-#endif /* CONFIG_USB_PERSIST etc. */ +- + #ifdef CONFIG_PM + + static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) +@@ -312,13 +276,8 @@ static int ohci_pci_suspend (struct usb_ + + static int ohci_pci_resume (struct usb_hcd *hcd) + { +- struct ohci_hcd *ohci = hcd_to_ohci(hcd); +- + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); +- +- /* FIXME: we should try to detect loss of VBUS power here */ +- prepare_for_handover(hcd); +- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); ++ ohci_finish_controller_resume(hcd); + return 0; + } + +--- a/drivers/usb/host/ohci-pxa27x.c ++++ b/drivers/usb/host/ohci-pxa27x.c +@@ -358,8 +358,7 @@ static int ohci_hcd_pxa27x_drv_resume(st + return status; + + pdev->dev.power.power_state = PMSG_ON; +- usb_hcd_resume_root_hub(hcd); +- ++ ohci_finish_controller_resume(hcd); + return 0; + } + #endif +--- a/drivers/usb/host/ohci-sm501.c ++++ b/drivers/usb/host/ohci-sm501.c +@@ -239,7 +239,7 @@ static int ohci_sm501_resume(struct plat + + sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); + dev->power.power_state = PMSG_ON; +- usb_hcd_resume_root_hub(platform_get_drvdata(pdev)); ++ ohci_finish_controller_resume(hcd); + return 0; + } + #endif +--- a/drivers/usb/host/ohci-ssb.c ++++ b/drivers/usb/host/ohci-ssb.c +@@ -224,6 +224,7 @@ static int ssb_ohci_resume(struct ssb_de + + ssb_device_enable(dev, ohcidev->enable_flags); + ++ ohci_finish_controller_resume(hcd); + return 0; + } + diff --git a/queue-2.6.25/sch_htb-remove-from-event-queue-in-htb_parent_to_leaf.patch b/queue-2.6.25/sch_htb-remove-from-event-queue-in-htb_parent_to_leaf.patch new file mode 100644 index 00000000000..799fc717edf --- /dev/null +++ b/queue-2.6.25/sch_htb-remove-from-event-queue-in-htb_parent_to_leaf.patch @@ -0,0 +1,58 @@ +From 955a9630bd94f4f44632e7ffff77df81a19c9872 Mon Sep 17 00:00:00 2001 +From: Jarek Poplawski +Date: Sat, 3 May 2008 20:46:29 -0700 +Subject: sch_htb: remove from event queue in htb_parent_to_leaf() + +From: Jarek Poplawski + +[ Upstream commit: 3ba08b00e0d8413d79be9cab8ec085ceb6ae6fd6 ] + +There is lack of removing a class from the event queue while changing +from parent to leaf which can cause corruption of this rb tree. This +patch fixes a bug introduced by my patch: "sch_htb: turn intermediate +classes into leaves" commit: 160d5e10f87b1dc88fd9b84b31b1718e0fd76398. + +Many thanks to Jan 'yanek' Bortl for finding a way to reproduce this +rare bug and narrowing the test case, which made possible proper +diagnosing. + +This patch is recommended for all kernels starting from 2.6.20. + +Reported-and-tested-by: Jan 'yanek' Bortl +Signed-off-by: Jarek Poplawski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/sched/sch_htb.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/net/sched/sch_htb.c ++++ b/net/sched/sch_htb.c +@@ -1197,12 +1197,16 @@ static inline int htb_parent_last_child( + return 1; + } + +-static void htb_parent_to_leaf(struct htb_class *cl, struct Qdisc *new_q) ++static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl, ++ struct Qdisc *new_q) + { + struct htb_class *parent = cl->parent; + + BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity); + ++ if (parent->cmode != HTB_CAN_SEND) ++ htb_safe_rb_erase(&parent->pq_node, q->wait_pq + parent->level); ++ + parent->level = 0; + memset(&parent->un.inner, 0, sizeof(parent->un.inner)); + INIT_LIST_HEAD(&parent->un.leaf.drop_list); +@@ -1300,7 +1304,7 @@ static int htb_delete(struct Qdisc *sch, + htb_deactivate(q, cl); + + if (last_child) +- htb_parent_to_leaf(cl, new_q); ++ htb_parent_to_leaf(q, cl, new_q); + + if (--cl->refcnt == 0) + htb_destroy_class(sch, cl); diff --git a/queue-2.6.25/serial-access-after-null-check-in-uart_flush_buffer.patch b/queue-2.6.25/serial-access-after-null-check-in-uart_flush_buffer.patch new file mode 100644 index 00000000000..598f1f31e6c --- /dev/null +++ b/queue-2.6.25/serial-access-after-null-check-in-uart_flush_buffer.patch @@ -0,0 +1,58 @@ +From jejb@kernel.org Tue May 13 09:24:28 2008 +From: Tetsuo Handa +Date: Thu, 8 May 2008 21:06:17 GMT +Subject: serial: access after NULL check in uart_flush_buffer() +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200805082106.m48L6HA4022722@hera.kernel.org> + +From: Tetsuo Handa + +commit 55d7b68996a5064f011d681bca412b6281d2f711 upstream + +I noticed that + + static void uart_flush_buffer(struct tty_struct *tty) + { + struct uart_state *state = tty->driver_data; + struct uart_port *port = state->port; + unsigned long flags; + + /* + * This means you called this function _after_ the port was + * closed. No cookie for you. + */ + if (!state || !state->info) { + WARN_ON(1); + return; + } + +is too late for checking state != NULL. + +Signed-off-by: Tetsuo Handa +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/serial/serial_core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/serial/serial_core.c ++++ b/drivers/serial/serial_core.c +@@ -535,7 +535,7 @@ static int uart_chars_in_buffer(struct t + static void uart_flush_buffer(struct tty_struct *tty) + { + struct uart_state *state = tty->driver_data; +- struct uart_port *port = state->port; ++ struct uart_port *port; + unsigned long flags; + + /* +@@ -547,6 +547,7 @@ static void uart_flush_buffer(struct tty + return; + } + ++ port = state->port; + pr_debug("uart_flush_buffer(%d) called\n", tty->index); + + spin_lock_irqsave(&port->lock, flags); diff --git a/queue-2.6.25/serial-fix-sparc-driver-name-strings.patch b/queue-2.6.25/serial-fix-sparc-driver-name-strings.patch new file mode 100644 index 00000000000..ff67f6170ba --- /dev/null +++ b/queue-2.6.25/serial-fix-sparc-driver-name-strings.patch @@ -0,0 +1,78 @@ +From f81aa402a3aa978981d50c54a18b638dd9736eba Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Thu, 1 May 2008 01:14:27 -0700 +Subject: serial: Fix sparc driver name strings. + +From: David S. Miller + +[ Upstream commit: b53e5216e5f73330bffae93b42dceb94e361f4c0 ] + +They were all "serial" so if multiple of these drivers registered, +we'd trigger sysfs directory creation errors: + +[ 1.695793] proc_dir_entry 'serial' already registered +[ 1.695839] Call Trace: +[ 1.831891] [00000000004f2534] create_proc_entry+0x7c/0x98 +[ 1.833608] [00000000004f3a58] proc_tty_register_driver+0x40/0x70 +[ 1.833663] [0000000000594700] tty_register_driver+0x1fc/0x208 +[ 1.835371] [00000000005aade4] uart_register_driver+0x134/0x16c +[ 1.841762] [00000000005ac274] sunserial_register_minors+0x34/0x68 +[ 1.841818] [00000000007db2a4] sunsu_init+0xf8/0x150 +[ 1.867697] [00000000007c62a4] kernel_init+0x190/0x330 +[ 1.939147] [0000000000426cf8] kernel_thread+0x38/0x48 +[ 1.939198] [00000000006a0d90] rest_init+0x18/0x5c + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/serial/sunhv.c | 2 +- + drivers/serial/sunsab.c | 2 +- + drivers/serial/sunsu.c | 2 +- + drivers/serial/sunzilog.c | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/serial/sunhv.c ++++ b/drivers/serial/sunhv.c +@@ -392,7 +392,7 @@ static struct uart_ops sunhv_pops = { + + static struct uart_driver sunhv_reg = { + .owner = THIS_MODULE, +- .driver_name = "serial", ++ .driver_name = "sunhv", + .dev_name = "ttyS", + .major = TTY_MAJOR, + }; +--- a/drivers/serial/sunsab.c ++++ b/drivers/serial/sunsab.c +@@ -826,7 +826,7 @@ static struct uart_ops sunsab_pops = { + + static struct uart_driver sunsab_reg = { + .owner = THIS_MODULE, +- .driver_name = "serial", ++ .driver_name = "sunsab", + .dev_name = "ttyS", + .major = TTY_MAJOR, + }; +--- a/drivers/serial/sunsu.c ++++ b/drivers/serial/sunsu.c +@@ -1173,7 +1173,7 @@ out: + + static struct uart_driver sunsu_reg = { + .owner = THIS_MODULE, +- .driver_name = "serial", ++ .driver_name = "sunsu", + .dev_name = "ttyS", + .major = TTY_MAJOR, + }; +--- a/drivers/serial/sunzilog.c ++++ b/drivers/serial/sunzilog.c +@@ -1023,7 +1023,7 @@ static struct uart_sunzilog_port *sunzil + + static struct uart_driver sunzilog_reg = { + .owner = THIS_MODULE, +- .driver_name = "ttyS", ++ .driver_name = "sunzilog", + .dev_name = "ttyS", + .major = TTY_MAJOR, + }; diff --git a/queue-2.6.25/series b/queue-2.6.25/series index 3fab0580add..a70af292b02 100644 --- a/queue-2.6.25/series +++ b/queue-2.6.25/series @@ -1 +1,17 @@ v4l-dvb-patch-for-various-dibcom-based-devices.patch +vt-fix-canonical-input-in-utf-8-mode.patch +serial-access-after-null-check-in-uart_flush_buffer.patch +ohci-fix-regression-upon-awakening-from-hibernation.patch +xfrm-audit-fix-flowlabel-text-format-ambibuity.patch +sparc-sunzilog-uart-order.patch +sparc-fix-sa_onstack-signal-handling.patch +sparc-fix-fork-clone-vfork-system-call-restart.patch +sparc64-stop-creating-dummy-root-pci-host-controller-devices.patch +sparc64-fix-wedged-irq-regression.patch +sparc64-fix-args-to-64-bit-sys_semctl-via-sys_ipc.patch +serial-fix-sparc-driver-name-strings.patch +sch_htb-remove-from-event-queue-in-htb_parent_to_leaf.patch +macvlan-fix-memleak-on-device-removal-crash-on-module-removal.patch +ipvs-fix-oops-in-backup-for-fwmark-conn-templates.patch +dccp-return-einval-on-invalid-feature-length.patch +can-fix-can_send-handling-on-dev_queue_xmit-failures.patch diff --git a/queue-2.6.25/sparc-fix-fork-clone-vfork-system-call-restart.patch b/queue-2.6.25/sparc-fix-fork-clone-vfork-system-call-restart.patch new file mode 100644 index 00000000000..c22a9db60dc --- /dev/null +++ b/queue-2.6.25/sparc-fix-fork-clone-vfork-system-call-restart.patch @@ -0,0 +1,93 @@ +From 8ba0c6c8ae1e64600c8f15a42f55382b353cdea0 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Wed, 7 May 2008 16:21:28 -0700 +Subject: sparc: Fix fork/clone/vfork system call restart. + +From: David S. Miller + +[ Upstream commit: 1e38c126c9252b612697e34f43b1b3371c8ee31d ] + +We clobber %i1 as well as %i0 for these system calls, +because they give two return values. + +Therefore, on error, we have to restore %i1 properly +or else the restart explodes since it uses the wrong +arguments. + +This fixes glibc's nptl/tst-eintr1.c testcase. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sparc/kernel/process.c | 20 ++++++++++++++++---- + arch/sparc64/kernel/process.c | 18 +++++++++++++++--- + 2 files changed, 31 insertions(+), 7 deletions(-) + +--- a/arch/sparc64/kernel/process.c ++++ b/arch/sparc64/kernel/process.c +@@ -507,6 +507,8 @@ asmlinkage long sparc_do_fork(unsigned l + unsigned long stack_size) + { + int __user *parent_tid_ptr, *child_tid_ptr; ++ unsigned long orig_i1 = regs->u_regs[UREG_I1]; ++ long ret; + + #ifdef CONFIG_COMPAT + if (test_thread_flag(TIF_32BIT)) { +@@ -519,9 +521,19 @@ asmlinkage long sparc_do_fork(unsigned l + child_tid_ptr = (int __user *) regs->u_regs[UREG_I4]; + } + +- return do_fork(clone_flags, stack_start, +- regs, stack_size, +- parent_tid_ptr, child_tid_ptr); ++ ret = do_fork(clone_flags, stack_start, ++ regs, stack_size, ++ parent_tid_ptr, child_tid_ptr); ++ ++ /* If we get an error and potentially restart the system ++ * call, we're screwed because copy_thread() clobbered ++ * the parent's %o1. So detect that case and restore it ++ * here. ++ */ ++ if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) ++ regs->u_regs[UREG_I1] = orig_i1; ++ ++ return ret; + } + + /* Copy a Sparc thread. The fork() return value conventions +--- a/arch/sparc/kernel/process.c ++++ b/arch/sparc/kernel/process.c +@@ -421,14 +421,26 @@ asmlinkage int sparc_do_fork(unsigned lo + unsigned long stack_size) + { + unsigned long parent_tid_ptr, child_tid_ptr; ++ unsigned long orig_i1 = regs->u_regs[UREG_I1]; ++ long ret; + + parent_tid_ptr = regs->u_regs[UREG_I2]; + child_tid_ptr = regs->u_regs[UREG_I4]; + +- return do_fork(clone_flags, stack_start, +- regs, stack_size, +- (int __user *) parent_tid_ptr, +- (int __user *) child_tid_ptr); ++ ret = do_fork(clone_flags, stack_start, ++ regs, stack_size, ++ (int __user *) parent_tid_ptr, ++ (int __user *) child_tid_ptr); ++ ++ /* If we get an error and potentially restart the system ++ * call, we're screwed because copy_thread() clobbered ++ * the parent's %o1. So detect that case and restore it ++ * here. ++ */ ++ if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) ++ regs->u_regs[UREG_I1] = orig_i1; ++ ++ return ret; + } + + /* Copy a Sparc thread. The fork() return value conventions diff --git a/queue-2.6.25/sparc-fix-sa_onstack-signal-handling.patch b/queue-2.6.25/sparc-fix-sa_onstack-signal-handling.patch new file mode 100644 index 00000000000..328a7d7f263 --- /dev/null +++ b/queue-2.6.25/sparc-fix-sa_onstack-signal-handling.patch @@ -0,0 +1,136 @@ +From 246eeecf4124a7847ecd9c26cc45a1b192bd4fea Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Wed, 7 May 2008 18:54:05 -0700 +Subject: sparc: Fix SA_ONSTACK signal handling. + +From: David S. Miller + +[ Upstream commit: dc5dc7e6d71ca9fd1ea01a1418150af3b2937489 ] + +We need to be more liberal about the alignment of the buffer given to +us by sigaltstack(). The user should not need to be mindful of all of +the alignment constraints we have for the stack frame. + +This mirrors how we handle this situation in clone() as well. + +Also, we align the stack even in non-SA_ONSTACK cases so that signals +due to bad stack alignment can be delivered properly. This makes such +errors easier to debug and recover from. + +Finally, add the sanity check x86 has to make sure we won't overflow +the signal stack. + +This fixes glibc testcases nptl/tst-cancel20.c and +nptl/tst-cancelx20.c + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sparc/kernel/signal.c | 20 +++++++++++++++++--- + arch/sparc64/kernel/signal.c | 21 +++++++++++++++++---- + arch/sparc64/kernel/signal32.c | 18 +++++++++++++++++- + 3 files changed, 51 insertions(+), 8 deletions(-) + +--- a/arch/sparc64/kernel/signal32.c ++++ b/arch/sparc64/kernel/signal32.c +@@ -497,11 +497,27 @@ static void __user *get_sigframe(struct + regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; + sp = regs->u_regs[UREG_FP]; + ++ /* ++ * If we are on the alternate signal stack and would overflow it, don't. ++ * Return an always-bogus address instead so we will die with SIGSEGV. ++ */ ++ if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) ++ return (void __user *) -1L; ++ + /* This is the X/Open sanctioned signal stack switching. */ + if (sa->sa_flags & SA_ONSTACK) { +- if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) ++ if (sas_ss_flags(sp) == 0) + sp = current->sas_ss_sp + current->sas_ss_size; + } ++ ++ /* Always align the stack frame. This handles two cases. First, ++ * sigaltstack need not be mindful of platform specific stack ++ * alignment. Second, if we took this signal because the stack ++ * is not aligned properly, we'd like to take the signal cleanly ++ * and report that. ++ */ ++ sp &= ~7UL; ++ + return (void __user *)(sp - framesize); + } + +--- a/arch/sparc64/kernel/signal.c ++++ b/arch/sparc64/kernel/signal.c +@@ -377,16 +377,29 @@ save_fpu_state(struct pt_regs *regs, __s + + static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) + { +- unsigned long sp; ++ unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; + +- sp = regs->u_regs[UREG_FP] + STACK_BIAS; ++ /* ++ * If we are on the alternate signal stack and would overflow it, don't. ++ * Return an always-bogus address instead so we will die with SIGSEGV. ++ */ ++ if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) ++ return (void __user *) -1L; + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa.sa_flags & SA_ONSTACK) { +- if (!on_sig_stack(sp) && +- !((current->sas_ss_sp + current->sas_ss_size) & 7)) ++ if (sas_ss_flags(sp) == 0) + sp = current->sas_ss_sp + current->sas_ss_size; + } ++ ++ /* Always align the stack frame. This handles two cases. First, ++ * sigaltstack need not be mindful of platform specific stack ++ * alignment. Second, if we took this signal because the stack ++ * is not aligned properly, we'd like to take the signal cleanly ++ * and report that. ++ */ ++ sp &= ~7UL; ++ + return (void __user *)(sp - framesize); + } + +--- a/arch/sparc/kernel/signal.c ++++ b/arch/sparc/kernel/signal.c +@@ -345,15 +345,29 @@ static inline int invalid_frame_pointer( + + static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) + { +- unsigned long sp; ++ unsigned long sp = regs->u_regs[UREG_FP]; + +- sp = regs->u_regs[UREG_FP]; ++ /* ++ * If we are on the alternate signal stack and would overflow it, don't. ++ * Return an always-bogus address instead so we will die with SIGSEGV. ++ */ ++ if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) ++ return (void __user *) -1L; + + /* This is the X/Open sanctioned signal stack switching. */ + if (sa->sa_flags & SA_ONSTACK) { +- if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) ++ if (sas_ss_flags(sp) == 0) + sp = current->sas_ss_sp + current->sas_ss_size; + } ++ ++ /* Always align the stack frame. This handles two cases. First, ++ * sigaltstack need not be mindful of platform specific stack ++ * alignment. Second, if we took this signal because the stack ++ * is not aligned properly, we'd like to take the signal cleanly ++ * and report that. ++ */ ++ sp &= ~7UL; ++ + return (void __user *)(sp - framesize); + } + diff --git a/queue-2.6.25/sparc-sunzilog-uart-order.patch b/queue-2.6.25/sparc-sunzilog-uart-order.patch new file mode 100644 index 00000000000..95640f1fbec --- /dev/null +++ b/queue-2.6.25/sparc-sunzilog-uart-order.patch @@ -0,0 +1,128 @@ +From d696c0e9694ebd3ef13a0fbb44beac690dee6e6b Mon Sep 17 00:00:00 2001 +From: Robert Reif +Date: Thu, 24 Apr 2008 03:37:51 -0700 +Subject: sparc: sunzilog uart order + +From: Robert Reif + +[ Upstream commit: 227739bf4c110bbd02d0c0f13b272c32de406e4c ] + +I have a sparcstation 20 clone with a lot of on board serial ports. +The serial core code assumes that uarts are assigned contiguously +and that may not be the case when there are multiple zs devices +present. This patch insures that uart chips are placed in front of +keyboard/mouse chips in the port table. + +ffd37420: ttyS0 at MMIO 0xf1100000 (irq = 44) is a zs (ESCC) +Console: ttyS0 (SunZilog zs0) +console [ttyS0] enabled +ffd37420: ttyS1 at MMIO 0xf1100004 (irq = 44) is a zs (ESCC) +ffd37500: Keyboard at MMIO 0xf1000000 (irq = 44) is a zs +ffd37500: Mouse at MMIO 0xf1000004 (irq = 44) is a zs +ffd3c5c0: ttyS2 at MMIO 0xf1100008 (irq = 44) is a zs (ESCC) +ffd3c5c0: ttyS3 at MMIO 0xf110000c (irq = 44) is a zs (ESCC) +ffd3c6a0: ttyS4 at MMIO 0xf1100010 (irq = 44) is a zs (ESCC) +ffd3c6a0: ttyS5 at MMIO 0xf1100014 (irq = 44) is a zs (ESCC) +ffd3c780: ttyS6 at MMIO 0xf1100018 (irq = 44) is a zs (ESCC) +ffd3c780: ttyS7 at MMIO 0xf110001c (irq = 44) is a zs (ESCC) + +Signed-off-by: Robert Reif +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/serial/sunzilog.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +--- a/drivers/serial/sunzilog.c ++++ b/drivers/serial/sunzilog.c +@@ -1015,6 +1015,7 @@ static struct uart_ops sunzilog_pops = { + .verify_port = sunzilog_verify_port, + }; + ++static int uart_chip_count; + static struct uart_sunzilog_port *sunzilog_port_table; + static struct zilog_layout __iomem **sunzilog_chip_regs; + +@@ -1350,16 +1351,22 @@ static int zilog_irq = -1; + + static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match) + { +- static int inst; ++ static int kbm_inst, uart_inst; ++ int inst; + struct uart_sunzilog_port *up; + struct zilog_layout __iomem *rp; +- int keyboard_mouse; ++ int keyboard_mouse = 0; + int err; + +- keyboard_mouse = 0; + if (of_find_property(op->node, "keyboard", NULL)) + keyboard_mouse = 1; + ++ /* uarts must come before keyboards/mice */ ++ if (keyboard_mouse) ++ inst = uart_chip_count + kbm_inst; ++ else ++ inst = uart_inst; ++ + sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0, + sizeof(struct zilog_layout), + "zs"); +@@ -1427,6 +1434,7 @@ static int __devinit zs_probe(struct of_ + rp, sizeof(struct zilog_layout)); + return err; + } ++ uart_inst++; + } else { + printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) " + "is a %s\n", +@@ -1438,12 +1446,11 @@ static int __devinit zs_probe(struct of_ + op->dev.bus_id, + (unsigned long long) up[1].port.mapbase, + op->irqs[0], sunzilog_type(&up[1].port)); ++ kbm_inst++; + } + + dev_set_drvdata(&op->dev, &up[0]); + +- inst++; +- + return 0; + } + +@@ -1491,28 +1498,25 @@ static struct of_platform_driver zs_driv + static int __init sunzilog_init(void) + { + struct device_node *dp; +- int err, uart_count; +- int num_keybms; ++ int err; ++ int num_keybms = 0; + int num_sunzilog = 0; + +- num_keybms = 0; + for_each_node_by_name(dp, "zs") { + num_sunzilog++; + if (of_find_property(dp, "keyboard", NULL)) + num_keybms++; + } + +- uart_count = 0; + if (num_sunzilog) { +- int uart_count; +- + err = sunzilog_alloc_tables(num_sunzilog); + if (err) + goto out; + +- uart_count = (num_sunzilog * 2) - (2 * num_keybms); ++ uart_chip_count = num_sunzilog - num_keybms; + +- err = sunserial_register_minors(&sunzilog_reg, uart_count); ++ err = sunserial_register_minors(&sunzilog_reg, ++ uart_chip_count * 2); + if (err) + goto out_free_tables; + } diff --git a/queue-2.6.25/sparc64-fix-args-to-64-bit-sys_semctl-via-sys_ipc.patch b/queue-2.6.25/sparc64-fix-args-to-64-bit-sys_semctl-via-sys_ipc.patch new file mode 100644 index 00000000000..5feacdf4062 --- /dev/null +++ b/queue-2.6.25/sparc64-fix-args-to-64-bit-sys_semctl-via-sys_ipc.patch @@ -0,0 +1,33 @@ +From d43464b9acc18dfaacca54343d0aa43a1d931e21 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Fri, 25 Apr 2008 02:12:05 -0700 +Subject: SPARC64: Fix args to 64-bit sys_semctl() via sys_ipc(). + +From: David S. Miller + +[ Upstream commit: 020cfb05f2c594c778537159bd45ea5efb0c5e0d ] + +Second and third arguments were swapped for whatever reason. + +Reported by Tom Callaway. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sparc64/kernel/sys_sparc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/sparc64/kernel/sys_sparc.c ++++ b/arch/sparc64/kernel/sys_sparc.c +@@ -454,8 +454,8 @@ asmlinkage long sys_ipc(unsigned int cal + err = sys_semget(first, (int)second, (int)third); + goto out; + case SEMCTL: { +- err = sys_semctl(first, third, +- (int)second | IPC_64, ++ err = sys_semctl(first, second, ++ (int)third | IPC_64, + (union semun) ptr); + goto out; + } diff --git a/queue-2.6.25/sparc64-fix-wedged-irq-regression.patch b/queue-2.6.25/sparc64-fix-wedged-irq-regression.patch new file mode 100644 index 00000000000..82910ddd048 --- /dev/null +++ b/queue-2.6.25/sparc64-fix-wedged-irq-regression.patch @@ -0,0 +1,62 @@ +From 4fcace47b9645557ce57bd9f0481ffbd5b72df1f Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Sat, 26 Apr 2008 02:19:18 -0700 +Subject: sparc64: Fix wedged irq regression. + +From: David S. Miller + +[ Upstream commit: 92aa3573c9cd58fe0bcd1c52c9fd8f5708785917 ] + +Kernel bugzilla 10273 + +As reported by Jos van der Ende, ever since commit +5a606b72a4309a656cd1a19ad137dc5557c4b8ea ("[SPARC64]: Do not ACK an +INO if it is disabled or inprogress.") sun4u interrupts +can get stuck. + +What this changset did was add the following conditional to +the various IRQ chip ->enable() handlers on sparc64: + + if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) + return; + +which is correct, however it means that special care is needed +in the ->enable() method. + +Specifically we must put the interrupt into IDLE state during +an enable, or else it might never be sent out again. + +Setting the INO interrupt state to IDLE resets the state machine, +the interrupt input to the INO is retested by the hardware, and +if an interrupt is being signalled by the device, the INO +moves back into TRANSMIT state, and an interrupt vector is sent +to the cpu. + +The two sun4v IRQ chip handlers were already doing this properly, +only sun4u got it wrong. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sparc64/kernel/irq.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/sparc64/kernel/irq.c ++++ b/arch/sparc64/kernel/irq.c +@@ -1,6 +1,6 @@ + /* irq.c: UltraSparc IRQ handling/init/registry. + * +- * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net) ++ * Copyright (C) 1997, 2007, 2008 David S. Miller (davem@davemloft.net) + * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) + * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) + */ +@@ -308,6 +308,7 @@ static void sun4u_irq_enable(unsigned in + IMAP_AID_SAFARI | IMAP_NID_SAFARI); + val |= tid | IMAP_VALID; + upa_writeq(val, imap); ++ upa_writeq(ICLR_IDLE, data->iclr); + } + } + diff --git a/queue-2.6.25/sparc64-stop-creating-dummy-root-pci-host-controller-devices.patch b/queue-2.6.25/sparc64-stop-creating-dummy-root-pci-host-controller-devices.patch new file mode 100644 index 00000000000..e72ec3d2793 --- /dev/null +++ b/queue-2.6.25/sparc64-stop-creating-dummy-root-pci-host-controller-devices.patch @@ -0,0 +1,255 @@ +From d6ce8cc0aff551c419b9a0318b4f4530bdf23772 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Thu, 1 May 2008 01:12:40 -0700 +Subject: sparc64: Stop creating dummy root PCI host controller devices. + +From: David S. Miller + +[ Upstream commit: 86d8337618e69573b5ccd3553f800944e843cae7 ] + +It just creates confusion, errors, and bugs. + +For one thing, this can cause dup sysfs or procfs nodes to get +created: + +[ 1.198015] proc_dir_entry '00.0' already registered +[ 1.198036] Call Trace: +[ 1.198052] [00000000004f2534] create_proc_entry+0x7c/0x98 +[ 1.198092] [00000000005719e4] pci_proc_attach_device+0xa4/0xd4 +[ 1.198126] [00000000007d991c] pci_proc_init+0x64/0x88 +[ 1.198158] [00000000007c62a4] kernel_init+0x190/0x330 +[ 1.198183] [0000000000426cf8] kernel_thread+0x38/0x48 +[ 1.198210] [00000000006a0d90] rest_init+0x18/0x5c + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sparc64/kernel/pci.c | 130 +++++++++------------------------------ + arch/sparc64/kernel/pci_common.c | 6 - + arch/sparc64/kernel/pci_impl.h | 9 -- + 3 files changed, 33 insertions(+), 112 deletions(-) + +--- a/arch/sparc64/kernel/pci.c ++++ b/arch/sparc64/kernel/pci.c +@@ -351,8 +351,7 @@ static void pci_parse_of_addrs(struct of + + struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, + struct device_node *node, +- struct pci_bus *bus, int devfn, +- int host_controller) ++ struct pci_bus *bus, int devfn) + { + struct dev_archdata *sd; + struct pci_dev *dev; +@@ -389,43 +388,28 @@ struct pci_dev *of_create_pci_dev(struct + dev->devfn = devfn; + dev->multifunction = 0; /* maybe a lie? */ + +- if (host_controller) { +- if (tlb_type != hypervisor) { +- pci_read_config_word(dev, PCI_VENDOR_ID, +- &dev->vendor); +- pci_read_config_word(dev, PCI_DEVICE_ID, +- &dev->device); +- } else { +- dev->vendor = PCI_VENDOR_ID_SUN; +- dev->device = 0x80f0; +- } +- dev->cfg_size = 256; +- dev->class = PCI_CLASS_BRIDGE_HOST << 8; +- sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), +- 0x00, PCI_SLOT(devfn), PCI_FUNC(devfn)); +- } else { +- dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); +- dev->device = of_getintprop_default(node, "device-id", 0xffff); +- dev->subsystem_vendor = +- of_getintprop_default(node, "subsystem-vendor-id", 0); +- dev->subsystem_device = +- of_getintprop_default(node, "subsystem-id", 0); +- +- dev->cfg_size = pci_cfg_space_size(dev); +- +- /* We can't actually use the firmware value, we have +- * to read what is in the register right now. One +- * reason is that in the case of IDE interfaces the +- * firmware can sample the value before the the IDE +- * interface is programmed into native mode. +- */ +- pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); +- dev->class = class >> 8; +- dev->revision = class & 0xff; ++ dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); ++ dev->device = of_getintprop_default(node, "device-id", 0xffff); ++ dev->subsystem_vendor = ++ of_getintprop_default(node, "subsystem-vendor-id", 0); ++ dev->subsystem_device = ++ of_getintprop_default(node, "subsystem-id", 0); ++ ++ dev->cfg_size = pci_cfg_space_size(dev); ++ ++ /* We can't actually use the firmware value, we have ++ * to read what is in the register right now. One ++ * reason is that in the case of IDE interfaces the ++ * firmware can sample the value before the the IDE ++ * interface is programmed into native mode. ++ */ ++ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); ++ dev->class = class >> 8; ++ dev->revision = class & 0xff; ++ ++ sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), ++ dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); + +- sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), +- dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); +- } + if (ofpci_verbose) + printk(" class: 0x%x device name: %s\n", + dev->class, pci_name(dev)); +@@ -440,26 +424,21 @@ struct pci_dev *of_create_pci_dev(struct + dev->current_state = 4; /* unknown power state */ + dev->error_state = pci_channel_io_normal; + +- if (host_controller) { ++ if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { ++ /* a PCI-PCI bridge */ + dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; + dev->rom_base_reg = PCI_ROM_ADDRESS1; +- dev->irq = PCI_IRQ_NONE; ++ } else if (!strcmp(type, "cardbus")) { ++ dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; + } else { +- if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { +- /* a PCI-PCI bridge */ +- dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; +- dev->rom_base_reg = PCI_ROM_ADDRESS1; +- } else if (!strcmp(type, "cardbus")) { +- dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; +- } else { +- dev->hdr_type = PCI_HEADER_TYPE_NORMAL; +- dev->rom_base_reg = PCI_ROM_ADDRESS; ++ dev->hdr_type = PCI_HEADER_TYPE_NORMAL; ++ dev->rom_base_reg = PCI_ROM_ADDRESS; + +- dev->irq = sd->op->irqs[0]; +- if (dev->irq == 0xffffffff) +- dev->irq = PCI_IRQ_NONE; +- } ++ dev->irq = sd->op->irqs[0]; ++ if (dev->irq == 0xffffffff) ++ dev->irq = PCI_IRQ_NONE; + } ++ + pci_parse_of_addrs(sd->op, node, dev); + + if (ofpci_verbose) +@@ -748,7 +727,7 @@ static void __devinit pci_of_scan_bus(st + prev_devfn = devfn; + + /* create a new pci_dev for this device */ +- dev = of_create_pci_dev(pbm, child, bus, devfn, 0); ++ dev = of_create_pci_dev(pbm, child, bus, devfn); + if (!dev) + continue; + if (ofpci_verbose) +@@ -795,48 +774,9 @@ static void __devinit pci_bus_register_o + pci_bus_register_of_sysfs(child_bus); + } + +-int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, +- unsigned int devfn, +- int where, int size, +- u32 *value) +-{ +- static u8 fake_pci_config[] = { +- 0x8e, 0x10, /* Vendor: 0x108e (Sun) */ +- 0xf0, 0x80, /* Device: 0x80f0 (Fire) */ +- 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */ +- 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */ +- 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */ +- 0x00, /* Cacheline: 0x00 */ +- 0x40, /* Latency: 0x40 */ +- 0x00, /* Header-Type: 0x00 normal */ +- }; +- +- *value = 0; +- if (where >= 0 && where < sizeof(fake_pci_config) && +- (where + size) >= 0 && +- (where + size) < sizeof(fake_pci_config) && +- size <= sizeof(u32)) { +- while (size--) { +- *value <<= 8; +- *value |= fake_pci_config[where + size]; +- } +- } +- +- return PCIBIOS_SUCCESSFUL; +-} +- +-int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, +- unsigned int devfn, +- int where, int size, +- u32 value) +-{ +- return PCIBIOS_SUCCESSFUL; +-} +- + struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) + { + struct device_node *node = pbm->prom_node; +- struct pci_dev *host_pdev; + struct pci_bus *bus; + + printk("PCI: Scanning PBM %s\n", node->full_name); +@@ -854,10 +794,6 @@ struct pci_bus * __devinit pci_scan_one_ + bus->resource[0] = &pbm->io_space; + bus->resource[1] = &pbm->mem_space; + +- /* Create the dummy host bridge and link it in. */ +- host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1); +- bus->self = host_pdev; +- + pci_of_scan_bus(pbm, node, bus); + pci_bus_add_devices(bus); + pci_bus_register_of_sysfs(bus); +--- a/arch/sparc64/kernel/pci_common.c ++++ b/arch/sparc64/kernel/pci_common.c +@@ -264,9 +264,6 @@ static int sun4v_read_pci_cfg(struct pci + unsigned int func = PCI_FUNC(devfn); + unsigned long ret; + +- if (!bus && devfn == 0x00) +- return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, +- size, value); + if (config_out_of_range(pbm, bus, devfn, where)) { + ret = ~0UL; + } else { +@@ -300,9 +297,6 @@ static int sun4v_write_pci_cfg(struct pc + unsigned int func = PCI_FUNC(devfn); + unsigned long ret; + +- if (!bus && devfn == 0x00) +- return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, +- size, value); + if (config_out_of_range(pbm, bus, devfn, where)) { + /* Do nothing. */ + } else { +--- a/arch/sparc64/kernel/pci_impl.h ++++ b/arch/sparc64/kernel/pci_impl.h +@@ -167,15 +167,6 @@ extern void pci_get_pbm_props(struct pci + extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); + extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); + +-extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, +- unsigned int devfn, +- int where, int size, +- u32 *value); +-extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, +- unsigned int devfn, +- int where, int size, +- u32 value); +- + /* Error reporting support. */ + extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); + extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); diff --git a/queue-2.6.25/vt-fix-canonical-input-in-utf-8-mode.patch b/queue-2.6.25/vt-fix-canonical-input-in-utf-8-mode.patch new file mode 100644 index 00000000000..4961c105c84 --- /dev/null +++ b/queue-2.6.25/vt-fix-canonical-input-in-utf-8-mode.patch @@ -0,0 +1,49 @@ +From jejb@kernel.org Tue May 13 09:23:33 2008 +From: Samuel Thibault +Date: Thu, 8 May 2008 21:06:15 GMT +Subject: vt: fix canonical input in UTF-8 mode +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200805082106.m48L6Fa2022639@hera.kernel.org> + +From: Samuel Thibault + +commit c1236d31a1b9fc018b85e15a3e58e3601ddc90ae upstream + +For e.g. proper TTY canonical support, IUTF8 termios flag has to be set as +appropriate. Linux used to not care about setting that flag for VT TTYs. + +This patch fixes that by activating it according to the current mode of the +VT, and sets the default value according to the vt.default_utf8 parameter. + +Signed-off-by: Samuel Thibault +Cc: Willy Tarreau +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/vt.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/char/vt.c ++++ b/drivers/char/vt.c +@@ -2723,6 +2723,10 @@ static int con_open(struct tty_struct *t + tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; + tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; + } ++ if (vc->vc_utf) ++ tty->termios->c_iflag |= IUTF8; ++ else ++ tty->termios->c_iflag &= ~IUTF8; + release_console_sem(); + vcs_make_sysfs(tty); + return ret; +@@ -2899,6 +2903,8 @@ int __init vty_init(void) + console_driver->minor_start = 1; + console_driver->type = TTY_DRIVER_TYPE_CONSOLE; + console_driver->init_termios = tty_std_termios; ++ if (default_utf8) ++ console_driver->init_termios.c_iflag |= IUTF8; + console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; + tty_set_operations(console_driver, &con_ops); + if (tty_register_driver(console_driver)) diff --git a/queue-2.6.25/xfrm-audit-fix-flowlabel-text-format-ambibuity.patch b/queue-2.6.25/xfrm-audit-fix-flowlabel-text-format-ambibuity.patch new file mode 100644 index 00000000000..39a5e903c99 --- /dev/null +++ b/queue-2.6.25/xfrm-audit-fix-flowlabel-text-format-ambibuity.patch @@ -0,0 +1,32 @@ +From 02cc35e8e6451be4bfc8aa7dd764186aa238dc96 Mon Sep 17 00:00:00 2001 +From: YOSHIFUJI Hideaki +Date: Sat, 26 Apr 2008 22:24:10 -0700 +Subject: XFRM: AUDIT: Fix flowlabel text format ambibuity. + +From: YOSHIFUJI Hideaki + +[ Upstream commit: 27a27a2158f4fe56a29458449e880a52ddee3dc4 ] + +Flowlabel text format was not correct and thus ambiguous. +For example, 0x00123 or 0x01203 are formatted as 0x123. +This is not what audit tools want. + +Signed-off-by: YOSHIFUJI Hideaki +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/xfrm/xfrm_state.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -2093,7 +2093,7 @@ static void xfrm_audit_helper_pktinfo(st + iph6 = ipv6_hdr(skb); + audit_log_format(audit_buf, + " src=" NIP6_FMT " dst=" NIP6_FMT +- " flowlbl=0x%x%x%x", ++ " flowlbl=0x%x%02x%02x", + NIP6(iph6->saddr), + NIP6(iph6->daddr), + iph6->flow_lbl[0] & 0x0f,