From 9660ebc6a69be7f79d0a974bdf047b436bba84ca Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Oct 2014 13:01:18 -0700 Subject: [PATCH] 3.16-stable patches added patches: alarmtimer-do-not-signal-sigev_none-timers.patch alarmtimer-lock-k_itimer-during-timer-callback.patch alarmtimer-return-relative-times-in-timer_gettime.patch don-t-bugger-nd-seq-on-set_root_rcu-from-follow_dotdot_rcu.patch gfs2-fix-d_splice_alias-misuses.patch ib-core-when-marshaling-uverbs-path-clear-unused-fields.patch ib-mlx4-avoid-null-pointer-dereference-in-mlx4_ib_scan_netdevs.patch ib-mlx4-don-t-duplicate-the-default-roce-gid.patch ib-qib-correct-reference-counting-in-debugfs-qp_stats.patch parisc-implement-new-lws-cas-supporting-64-bit-operations.patch parisc-only-use-mfast-indirect-calls-option-for-32-bit-kernel-builds.patch revert-hwrng-virtio-ensure-reads-happen-after-successful-probe.patch virtio-rng-delay-hwrng_register-till-driver-is-ready.patch --- ...imer-do-not-signal-sigev_none-timers.patch | 52 ++++ ...-lock-k_itimer-during-timer-callback.patch | 59 ++++ ...turn-relative-times-in-timer_gettime.patch | 65 ++++ ...-set_root_rcu-from-follow_dotdot_rcu.patch | 103 +++++++ .../gfs2-fix-d_splice_alias-misuses.patch | 49 +++ ...ling-uverbs-path-clear-unused-fields.patch | 35 +++ ...-dereference-in-mlx4_ib_scan_netdevs.patch | 87 ++++++ ...don-t-duplicate-the-default-roce-gid.patch | 50 ++++ ...ference-counting-in-debugfs-qp_stats.patch | 71 +++++ ...lws-cas-supporting-64-bit-operations.patch | 283 ++++++++++++++++++ ...alls-option-for-32-bit-kernel-builds.patch | 49 +++ ...-reads-happen-after-successful-probe.patch | 73 +++++ queue-3.16/series | 13 + ...-hwrng_register-till-driver-is-ready.patch | 100 +++++++ 14 files changed, 1089 insertions(+) create mode 100644 queue-3.16/alarmtimer-do-not-signal-sigev_none-timers.patch create mode 100644 queue-3.16/alarmtimer-lock-k_itimer-during-timer-callback.patch create mode 100644 queue-3.16/alarmtimer-return-relative-times-in-timer_gettime.patch create mode 100644 queue-3.16/don-t-bugger-nd-seq-on-set_root_rcu-from-follow_dotdot_rcu.patch create mode 100644 queue-3.16/gfs2-fix-d_splice_alias-misuses.patch create mode 100644 queue-3.16/ib-core-when-marshaling-uverbs-path-clear-unused-fields.patch create mode 100644 queue-3.16/ib-mlx4-avoid-null-pointer-dereference-in-mlx4_ib_scan_netdevs.patch create mode 100644 queue-3.16/ib-mlx4-don-t-duplicate-the-default-roce-gid.patch create mode 100644 queue-3.16/ib-qib-correct-reference-counting-in-debugfs-qp_stats.patch create mode 100644 queue-3.16/parisc-implement-new-lws-cas-supporting-64-bit-operations.patch create mode 100644 queue-3.16/parisc-only-use-mfast-indirect-calls-option-for-32-bit-kernel-builds.patch create mode 100644 queue-3.16/revert-hwrng-virtio-ensure-reads-happen-after-successful-probe.patch create mode 100644 queue-3.16/virtio-rng-delay-hwrng_register-till-driver-is-ready.patch diff --git a/queue-3.16/alarmtimer-do-not-signal-sigev_none-timers.patch b/queue-3.16/alarmtimer-do-not-signal-sigev_none-timers.patch new file mode 100644 index 00000000000..b945c71335d --- /dev/null +++ b/queue-3.16/alarmtimer-do-not-signal-sigev_none-timers.patch @@ -0,0 +1,52 @@ +From 265b81d23a46c39df0a735a3af4238954b41a4c2 Mon Sep 17 00:00:00 2001 +From: Richard Larocque +Date: Tue, 9 Sep 2014 18:31:04 -0700 +Subject: alarmtimer: Do not signal SIGEV_NONE timers + +From: Richard Larocque + +commit 265b81d23a46c39df0a735a3af4238954b41a4c2 upstream. + +Avoids sending a signal to alarm timers created with sigev_notify set to +SIGEV_NONE by checking for that special case in the timeout callback. + +The regular posix timers avoid sending signals to SIGEV_NONE timers by +not scheduling any callbacks for them in the first place. Although it +would be possible to do something similar for alarm timers, it's simpler +to handle this as a special case in the timeout. + +Prior to this patch, the alarm timer would ignore the sigev_notify value +and try to deliver signals to the process anyway. Even worse, the +sanity check for the value of sigev_signo is skipped when SIGEV_NONE was +specified, so the signal number could be bogus. If sigev_signo was an +unitialized value (as it often would be if SIGEV_NONE is used), then +it's hard to predict which signal will be sent. + +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: Richard Cochran +Cc: Prarit Bhargava +Cc: Sharvil Nanavati +Signed-off-by: Richard Larocque +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/alarmtimer.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -466,8 +466,10 @@ static enum alarmtimer_restart alarm_han + { + struct k_itimer *ptr = container_of(alarm, struct k_itimer, + it.alarm.alarmtimer); +- if (posix_timer_event(ptr, 0) != 0) +- ptr->it_overrun++; ++ if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) { ++ if (posix_timer_event(ptr, 0) != 0) ++ ptr->it_overrun++; ++ } + + /* Re-add periodic timers */ + if (ptr->it.alarm.interval.tv64) { diff --git a/queue-3.16/alarmtimer-lock-k_itimer-during-timer-callback.patch b/queue-3.16/alarmtimer-lock-k_itimer-during-timer-callback.patch new file mode 100644 index 00000000000..b269759c3f1 --- /dev/null +++ b/queue-3.16/alarmtimer-lock-k_itimer-during-timer-callback.patch @@ -0,0 +1,59 @@ +From 474e941bed9262f5fa2394f9a4a67e24499e5926 Mon Sep 17 00:00:00 2001 +From: Richard Larocque +Date: Tue, 9 Sep 2014 18:31:05 -0700 +Subject: alarmtimer: Lock k_itimer during timer callback + +From: Richard Larocque + +commit 474e941bed9262f5fa2394f9a4a67e24499e5926 upstream. + +Locks the k_itimer's it_lock member when handling the alarm timer's +expiry callback. + +The regular posix timers defined in posix-timers.c have this lock held +during timout processing because their callbacks are routed through +posix_timer_fn(). The alarm timers follow a different path, so they +ought to grab the lock somewhere else. + +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: Richard Cochran +Cc: Prarit Bhargava +Cc: Sharvil Nanavati +Signed-off-by: Richard Larocque +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/alarmtimer.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -464,8 +464,12 @@ static enum alarmtimer_type clock2alarm( + static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, + ktime_t now) + { ++ unsigned long flags; + struct k_itimer *ptr = container_of(alarm, struct k_itimer, + it.alarm.alarmtimer); ++ enum alarmtimer_restart result = ALARMTIMER_NORESTART; ++ ++ spin_lock_irqsave(&ptr->it_lock, flags); + if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) { + if (posix_timer_event(ptr, 0) != 0) + ptr->it_overrun++; +@@ -475,9 +479,11 @@ static enum alarmtimer_restart alarm_han + if (ptr->it.alarm.interval.tv64) { + ptr->it_overrun += alarm_forward(alarm, now, + ptr->it.alarm.interval); +- return ALARMTIMER_RESTART; ++ result = ALARMTIMER_RESTART; + } +- return ALARMTIMER_NORESTART; ++ spin_unlock_irqrestore(&ptr->it_lock, flags); ++ ++ return result; + } + + /** diff --git a/queue-3.16/alarmtimer-return-relative-times-in-timer_gettime.patch b/queue-3.16/alarmtimer-return-relative-times-in-timer_gettime.patch new file mode 100644 index 00000000000..771ea2df1bd --- /dev/null +++ b/queue-3.16/alarmtimer-return-relative-times-in-timer_gettime.patch @@ -0,0 +1,65 @@ +From e86fea764991e00a03ff1e56409ec9cacdbda4c9 Mon Sep 17 00:00:00 2001 +From: Richard Larocque +Date: Tue, 9 Sep 2014 18:31:03 -0700 +Subject: alarmtimer: Return relative times in timer_gettime + +From: Richard Larocque + +commit e86fea764991e00a03ff1e56409ec9cacdbda4c9 upstream. + +Returns the time remaining for an alarm timer, rather than the time at +which it is scheduled to expire. If the timer has already expired or it +is not currently scheduled, the it_value's members are set to zero. + +This new behavior matches that of the other posix-timers and the POSIX +specifications. + +This is a change in user-visible behavior, and may break existing +applications. Hopefully, few users rely on the old incorrect behavior. + +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: Richard Cochran +Cc: Prarit Bhargava +Cc: Sharvil Nanavati +Signed-off-by: Richard Larocque +[jstultz: minor style tweak] +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/alarmtimer.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -541,18 +541,22 @@ static int alarm_timer_create(struct k_i + * @new_timer: k_itimer pointer + * @cur_setting: itimerspec data to fill + * +- * Copies the itimerspec data out from the k_itimer ++ * Copies out the current itimerspec data + */ + static void alarm_timer_get(struct k_itimer *timr, + struct itimerspec *cur_setting) + { +- memset(cur_setting, 0, sizeof(struct itimerspec)); ++ ktime_t relative_expiry_time = ++ alarm_expires_remaining(&(timr->it.alarm.alarmtimer)); + +- cur_setting->it_interval = +- ktime_to_timespec(timr->it.alarm.interval); +- cur_setting->it_value = +- ktime_to_timespec(timr->it.alarm.alarmtimer.node.expires); +- return; ++ if (ktime_to_ns(relative_expiry_time) > 0) { ++ cur_setting->it_value = ktime_to_timespec(relative_expiry_time); ++ } else { ++ cur_setting->it_value.tv_sec = 0; ++ cur_setting->it_value.tv_nsec = 0; ++ } ++ ++ cur_setting->it_interval = ktime_to_timespec(timr->it.alarm.interval); + } + + /** diff --git a/queue-3.16/don-t-bugger-nd-seq-on-set_root_rcu-from-follow_dotdot_rcu.patch b/queue-3.16/don-t-bugger-nd-seq-on-set_root_rcu-from-follow_dotdot_rcu.patch new file mode 100644 index 00000000000..9e9c5299a04 --- /dev/null +++ b/queue-3.16/don-t-bugger-nd-seq-on-set_root_rcu-from-follow_dotdot_rcu.patch @@ -0,0 +1,103 @@ +From 7bd88377d482e1eae3c5329b12e33cfd664fa6a9 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sat, 13 Sep 2014 21:55:46 -0400 +Subject: don't bugger nd->seq on set_root_rcu() from follow_dotdot_rcu() + +From: Al Viro + +commit 7bd88377d482e1eae3c5329b12e33cfd664fa6a9 upstream. + +return the value instead, and have path_init() do the assignment. Broken by +"vfs: Fix absolute RCU path walk failures due to uninitialized seq number", +which was Cc-stable with 2.6.38+ as destination. This one should go where +it went. + +To avoid dummy value returned in case when root is already set (it would do +no harm, actually, since the only caller that doesn't ignore the return value +is guaranteed to have nd->root *not* set, but it's more obvious that way), +lift the check into callers. And do the same to set_root(), to keep them +in sync. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namei.c | 33 +++++++++++++++++---------------- + 1 file changed, 17 insertions(+), 16 deletions(-) + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -644,24 +644,22 @@ static int complete_walk(struct nameidat + + static __always_inline void set_root(struct nameidata *nd) + { +- if (!nd->root.mnt) +- get_fs_root(current->fs, &nd->root); ++ get_fs_root(current->fs, &nd->root); + } + + static int link_path_walk(const char *, struct nameidata *); + +-static __always_inline void set_root_rcu(struct nameidata *nd) ++static __always_inline unsigned set_root_rcu(struct nameidata *nd) + { +- if (!nd->root.mnt) { +- struct fs_struct *fs = current->fs; +- unsigned seq; ++ struct fs_struct *fs = current->fs; ++ unsigned seq, res; + +- do { +- seq = read_seqcount_begin(&fs->seq); +- nd->root = fs->root; +- nd->seq = __read_seqcount_begin(&nd->root.dentry->d_seq); +- } while (read_seqcount_retry(&fs->seq, seq)); +- } ++ do { ++ seq = read_seqcount_begin(&fs->seq); ++ nd->root = fs->root; ++ res = __read_seqcount_begin(&nd->root.dentry->d_seq); ++ } while (read_seqcount_retry(&fs->seq, seq)); ++ return res; + } + + static void path_put_conditional(struct path *path, struct nameidata *nd) +@@ -861,7 +859,8 @@ follow_link(struct path *link, struct na + return PTR_ERR(s); + } + if (*s == '/') { +- set_root(nd); ++ if (!nd->root.mnt) ++ set_root(nd); + path_put(&nd->path); + nd->path = nd->root; + path_get(&nd->root); +@@ -1136,7 +1135,8 @@ static bool __follow_mount_rcu(struct na + + static int follow_dotdot_rcu(struct nameidata *nd) + { +- set_root_rcu(nd); ++ if (!nd->root.mnt) ++ set_root_rcu(nd); + + while (1) { + if (nd->path.dentry == nd->root.dentry && +@@ -1249,7 +1249,8 @@ static void follow_mount(struct path *pa + + static void follow_dotdot(struct nameidata *nd) + { +- set_root(nd); ++ if (!nd->root.mnt) ++ set_root(nd); + + while(1) { + struct dentry *old = nd->path.dentry; +@@ -1847,7 +1848,7 @@ static int path_init(int dfd, const char + if (*name=='/') { + if (flags & LOOKUP_RCU) { + rcu_read_lock(); +- set_root_rcu(nd); ++ nd->seq = set_root_rcu(nd); + } else { + set_root(nd); + path_get(&nd->root); diff --git a/queue-3.16/gfs2-fix-d_splice_alias-misuses.patch b/queue-3.16/gfs2-fix-d_splice_alias-misuses.patch new file mode 100644 index 00000000000..8935fe5326c --- /dev/null +++ b/queue-3.16/gfs2-fix-d_splice_alias-misuses.patch @@ -0,0 +1,49 @@ +From cfb2f9d5c921e38b0f12bb26fed10b877664444d Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 12 Sep 2014 20:56:04 +0100 +Subject: GFS2: fix d_splice_alias() misuses + +From: Al Viro + +commit cfb2f9d5c921e38b0f12bb26fed10b877664444d upstream. + +Callers of d_splice_alias(dentry, inode) don't need iput(), neither +on success nor on failure. Either the reference to inode is stored +in a previously negative dentry, or it's dropped. In either case +inode reference the caller used to hold is consumed. + +__gfs2_lookup() does iput() in case when d_splice_alias() has failed. +Double iput() if we ever hit that. And gfs2_create_inode() ends up +not only with double iput(), but with link count dropped to zero - on +an inode it has just found in directory. + +Signed-off-by: Al Viro +Signed-off-by: Steven Whitehouse +Signed-off-by: Greg Kroah-Hartman + +--- + fs/gfs2/inode.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -626,8 +626,10 @@ static int gfs2_create_inode(struct inod + if (!IS_ERR(inode)) { + d = d_splice_alias(inode, dentry); + error = PTR_ERR(d); +- if (IS_ERR(d)) ++ if (IS_ERR(d)) { ++ inode = ERR_CAST(d); + goto fail_gunlock; ++ } + error = 0; + if (file) { + if (S_ISREG(inode->i_mode)) { +@@ -854,7 +856,6 @@ static struct dentry *__gfs2_lookup(stru + + d = d_splice_alias(inode, dentry); + if (IS_ERR(d)) { +- iput(inode); + gfs2_glock_dq_uninit(&gh); + return d; + } diff --git a/queue-3.16/ib-core-when-marshaling-uverbs-path-clear-unused-fields.patch b/queue-3.16/ib-core-when-marshaling-uverbs-path-clear-unused-fields.patch new file mode 100644 index 00000000000..f226ae7c2e9 --- /dev/null +++ b/queue-3.16/ib-core-when-marshaling-uverbs-path-clear-unused-fields.patch @@ -0,0 +1,35 @@ +From a59c5850f09b4c2d6ad2fc47e5e1be8d654529d6 Mon Sep 17 00:00:00 2001 +From: Matan Barak +Date: Tue, 2 Sep 2014 15:32:34 +0300 +Subject: IB/core: When marshaling uverbs path, clear unused fields + +From: Matan Barak + +commit a59c5850f09b4c2d6ad2fc47e5e1be8d654529d6 upstream. + +When marsheling a user path to the kernel struct ib_sa_path, need +to zero smac, dmac and set the vlan id to the "no vlan" value. + +Fixes: dd5f03beb4f7 ("IB/core: Ethernet L2 attributes in verbs/cm structures") +Reported-by: Aleksey Senin +Signed-off-by: Matan Barak +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs_marshall.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/infiniband/core/uverbs_marshall.c ++++ b/drivers/infiniband/core/uverbs_marshall.c +@@ -140,5 +140,9 @@ void ib_copy_path_rec_from_user(struct i + dst->packet_life_time = src->packet_life_time; + dst->preference = src->preference; + dst->packet_life_time_selector = src->packet_life_time_selector; ++ ++ memset(dst->smac, 0, sizeof(dst->smac)); ++ memset(dst->dmac, 0, sizeof(dst->dmac)); ++ dst->vlan_id = 0xffff; + } + EXPORT_SYMBOL(ib_copy_path_rec_from_user); diff --git a/queue-3.16/ib-mlx4-avoid-null-pointer-dereference-in-mlx4_ib_scan_netdevs.patch b/queue-3.16/ib-mlx4-avoid-null-pointer-dereference-in-mlx4_ib_scan_netdevs.patch new file mode 100644 index 00000000000..4b7ff6044bd --- /dev/null +++ b/queue-3.16/ib-mlx4-avoid-null-pointer-dereference-in-mlx4_ib_scan_netdevs.patch @@ -0,0 +1,87 @@ +From e381835cf1b8e3b2857277dbc3b77d8c5350f70a Mon Sep 17 00:00:00 2001 +From: Moni Shoua +Date: Thu, 21 Aug 2014 14:28:37 +0300 +Subject: IB/mlx4: Avoid null pointer dereference in mlx4_ib_scan_netdevs() + +From: Moni Shoua + +commit e381835cf1b8e3b2857277dbc3b77d8c5350f70a upstream. + +When Ethernet netdev is not present for a port (e.g. when the link +layer type of the port is InfiniBand) it's possible to dereference a +null pointer when we do netdevice scanning. + +To fix that, we move a section of code that needs to run only when +netdev is present to a proper if () statement. + +Fixes: ad4885d279b6 ("IB/mlx4: Build the port IBoE GID table properly under bonding") +Reported-by: Dan Carpenter +Signed-off-by: Moni Shoua +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/main.c | 49 ++++++++++++++++++++------------------ + 1 file changed, 26 insertions(+), 23 deletions(-) + +--- a/drivers/infiniband/hw/mlx4/main.c ++++ b/drivers/infiniband/hw/mlx4/main.c +@@ -1788,31 +1788,34 @@ static void mlx4_ib_scan_netdevs(struct + port_state = (netif_running(curr_netdev) && netif_carrier_ok(curr_netdev)) ? + IB_PORT_ACTIVE : IB_PORT_DOWN; + mlx4_ib_set_default_gid(ibdev, curr_netdev, port); +- } else { +- reset_gid_table(ibdev, port); +- } +- /* if using bonding/team and a slave port is down, we don't the bond IP +- * based gids in the table since flows that select port by gid may get +- * the down port. +- */ +- if (curr_master && (port_state == IB_PORT_DOWN)) { +- reset_gid_table(ibdev, port); +- mlx4_ib_set_default_gid(ibdev, curr_netdev, port); +- } +- /* if bonding is used it is possible that we add it to masters +- * only after IP address is assigned to the net bonding +- * interface. +- */ +- if (curr_master && (old_master != curr_master)) { +- reset_gid_table(ibdev, port); +- mlx4_ib_set_default_gid(ibdev, curr_netdev, port); +- mlx4_ib_get_dev_addr(curr_master, ibdev, port); +- } ++ /* if using bonding/team and a slave port is down, we ++ * don't the bond IP based gids in the table since ++ * flows that select port by gid may get the down port. ++ */ ++ if (curr_master && (port_state == IB_PORT_DOWN)) { ++ reset_gid_table(ibdev, port); ++ mlx4_ib_set_default_gid(ibdev, ++ curr_netdev, port); ++ } ++ /* if bonding is used it is possible that we add it to ++ * masters only after IP address is assigned to the ++ * net bonding interface. ++ */ ++ if (curr_master && (old_master != curr_master)) { ++ reset_gid_table(ibdev, port); ++ mlx4_ib_set_default_gid(ibdev, ++ curr_netdev, port); ++ mlx4_ib_get_dev_addr(curr_master, ibdev, port); ++ } + +- if (!curr_master && (old_master != curr_master)) { ++ if (!curr_master && (old_master != curr_master)) { ++ reset_gid_table(ibdev, port); ++ mlx4_ib_set_default_gid(ibdev, ++ curr_netdev, port); ++ mlx4_ib_get_dev_addr(curr_netdev, ibdev, port); ++ } ++ } else { + reset_gid_table(ibdev, port); +- mlx4_ib_set_default_gid(ibdev, curr_netdev, port); +- mlx4_ib_get_dev_addr(curr_netdev, ibdev, port); + } + } + diff --git a/queue-3.16/ib-mlx4-don-t-duplicate-the-default-roce-gid.patch b/queue-3.16/ib-mlx4-don-t-duplicate-the-default-roce-gid.patch new file mode 100644 index 00000000000..3bc5ce3d7cd --- /dev/null +++ b/queue-3.16/ib-mlx4-don-t-duplicate-the-default-roce-gid.patch @@ -0,0 +1,50 @@ +From f5c4834d9328c4ed9fe5dcbec6128d6da16db69a Mon Sep 17 00:00:00 2001 +From: Moni Shoua +Date: Thu, 21 Aug 2014 14:28:38 +0300 +Subject: IB/mlx4: Don't duplicate the default RoCE GID + +From: Moni Shoua + +commit f5c4834d9328c4ed9fe5dcbec6128d6da16db69a upstream. + +When reading the IPv6 addresses from the net-device, make sure to +avoid adding a duplicate entry to the GID table because of equality +between the default GID we generate and the default IPv6 link-local +address of the device. + +Fixes: acc4fccf4eff ("IB/mlx4: Make sure GID index 0 is always occupied") +Signed-off-by: Moni Shoua +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/infiniband/hw/mlx4/main.c ++++ b/drivers/infiniband/hw/mlx4/main.c +@@ -1678,6 +1678,7 @@ static void mlx4_ib_get_dev_addr(struct + struct inet6_dev *in6_dev; + union ib_gid *pgid; + struct inet6_ifaddr *ifp; ++ union ib_gid default_gid; + #endif + union ib_gid gid; + +@@ -1698,12 +1699,15 @@ static void mlx4_ib_get_dev_addr(struct + in_dev_put(in_dev); + } + #if IS_ENABLED(CONFIG_IPV6) ++ mlx4_make_default_gid(dev, &default_gid); + /* IPv6 gids */ + in6_dev = in6_dev_get(dev); + if (in6_dev) { + read_lock_bh(&in6_dev->lock); + list_for_each_entry(ifp, &in6_dev->addr_list, if_list) { + pgid = (union ib_gid *)&ifp->addr; ++ if (!memcmp(pgid, &default_gid, sizeof(*pgid))) ++ continue; + update_gid_table(ibdev, port, pgid, 0, 0); + } + read_unlock_bh(&in6_dev->lock); diff --git a/queue-3.16/ib-qib-correct-reference-counting-in-debugfs-qp_stats.patch b/queue-3.16/ib-qib-correct-reference-counting-in-debugfs-qp_stats.patch new file mode 100644 index 00000000000..dd30c4bcc74 --- /dev/null +++ b/queue-3.16/ib-qib-correct-reference-counting-in-debugfs-qp_stats.patch @@ -0,0 +1,71 @@ +From 85cbb7c728bf39c45a9789b88c9471c0d7a58b0e Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Fri, 19 Sep 2014 08:32:19 -0400 +Subject: IB/qib: Correct reference counting in debugfs qp_stats + +From: Mike Marciniszyn + +commit 85cbb7c728bf39c45a9789b88c9471c0d7a58b0e upstream. + +This particular reference count is not needed with the rcu protection, +and the current code leaks a reference count, causing a hang in +qib_qp_destroy(). + +Reviewed-by: Dennis Dalessandro +Signed-off-by: Mike Marciniszyn +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/qib/qib_debugfs.c | 3 ++- + drivers/infiniband/hw/qib/qib_qp.c | 8 -------- + 2 files changed, 2 insertions(+), 9 deletions(-) + +--- a/drivers/infiniband/hw/qib/qib_debugfs.c ++++ b/drivers/infiniband/hw/qib/qib_debugfs.c +@@ -193,6 +193,7 @@ static void *_qp_stats_seq_start(struct + struct qib_qp_iter *iter; + loff_t n = *pos; + ++ rcu_read_lock(); + iter = qib_qp_iter_init(s->private); + if (!iter) + return NULL; +@@ -224,7 +225,7 @@ static void *_qp_stats_seq_next(struct s + + static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr) + { +- /* nothing for now */ ++ rcu_read_unlock(); + } + + static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr) +--- a/drivers/infiniband/hw/qib/qib_qp.c ++++ b/drivers/infiniband/hw/qib/qib_qp.c +@@ -1325,7 +1325,6 @@ int qib_qp_iter_next(struct qib_qp_iter + struct qib_qp *pqp = iter->qp; + struct qib_qp *qp; + +- rcu_read_lock(); + for (; n < dev->qp_table_size; n++) { + if (pqp) + qp = rcu_dereference(pqp->next); +@@ -1333,18 +1332,11 @@ int qib_qp_iter_next(struct qib_qp_iter + qp = rcu_dereference(dev->qp_table[n]); + pqp = qp; + if (qp) { +- if (iter->qp) +- atomic_dec(&iter->qp->refcount); +- atomic_inc(&qp->refcount); +- rcu_read_unlock(); + iter->qp = qp; + iter->n = n; + return 0; + } + } +- rcu_read_unlock(); +- if (iter->qp) +- atomic_dec(&iter->qp->refcount); + return ret; + } + diff --git a/queue-3.16/parisc-implement-new-lws-cas-supporting-64-bit-operations.patch b/queue-3.16/parisc-implement-new-lws-cas-supporting-64-bit-operations.patch new file mode 100644 index 00000000000..90306279174 --- /dev/null +++ b/queue-3.16/parisc-implement-new-lws-cas-supporting-64-bit-operations.patch @@ -0,0 +1,283 @@ +From 89206491201cbd1571009b36292af781cef74c1b Mon Sep 17 00:00:00 2001 +From: Guy Martin +Date: Fri, 12 Sep 2014 18:02:34 +0200 +Subject: parisc: Implement new LWS CAS supporting 64 bit operations. + +From: Guy Martin + +commit 89206491201cbd1571009b36292af781cef74c1b upstream. + +The current LWS cas only works correctly for 32bit. The new LWS allows +for CAS operations of variable size. + +Signed-off-by: Guy Martin +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/syscall.S | 233 ++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 229 insertions(+), 4 deletions(-) + +--- a/arch/parisc/kernel/syscall.S ++++ b/arch/parisc/kernel/syscall.S +@@ -74,7 +74,7 @@ ENTRY(linux_gateway_page) + /* ADDRESS 0xb0 to 0xb8, lws uses two insns for entry */ + /* Light-weight-syscall entry must always be located at 0xb0 */ + /* WARNING: Keep this number updated with table size changes */ +-#define __NR_lws_entries (2) ++#define __NR_lws_entries (3) + + lws_entry: + gate lws_start, %r0 /* increase privilege */ +@@ -502,7 +502,7 @@ lws_exit: + + + /*************************************************** +- Implementing CAS as an atomic operation: ++ Implementing 32bit CAS as an atomic operation: + + %r26 - Address to examine + %r25 - Old value to check (old) +@@ -659,6 +659,230 @@ cas_action: + ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page) + + ++ /*************************************************** ++ New CAS implementation which uses pointers and variable size ++ information. The value pointed by old and new MUST NOT change ++ while performing CAS. The lock only protect the value at %r26. ++ ++ %r26 - Address to examine ++ %r25 - Pointer to the value to check (old) ++ %r24 - Pointer to the value to set (new) ++ %r23 - Size of the variable (0/1/2/3 for 8/16/32/64 bit) ++ %r28 - Return non-zero on failure ++ %r21 - Kernel error code ++ ++ %r21 has the following meanings: ++ ++ EAGAIN - CAS is busy, ldcw failed, try again. ++ EFAULT - Read or write failed. ++ ++ Scratch: r20, r22, r28, r29, r1, fr4 (32bit for 64bit CAS only) ++ ++ ****************************************************/ ++ ++ /* ELF32 Process entry path */ ++lws_compare_and_swap_2: ++#ifdef CONFIG_64BIT ++ /* Clip the input registers */ ++ depdi 0, 31, 32, %r26 ++ depdi 0, 31, 32, %r25 ++ depdi 0, 31, 32, %r24 ++ depdi 0, 31, 32, %r23 ++#endif ++ ++ /* Check the validity of the size pointer */ ++ subi,>>= 4, %r23, %r0 ++ b,n lws_exit_nosys ++ ++ /* Jump to the functions which will load the old and new values into ++ registers depending on the their size */ ++ shlw %r23, 2, %r29 ++ blr %r29, %r0 ++ nop ++ ++ /* 8bit load */ ++4: ldb 0(%sr3,%r25), %r25 ++ b cas2_lock_start ++5: ldb 0(%sr3,%r24), %r24 ++ nop ++ nop ++ nop ++ nop ++ nop ++ ++ /* 16bit load */ ++6: ldh 0(%sr3,%r25), %r25 ++ b cas2_lock_start ++7: ldh 0(%sr3,%r24), %r24 ++ nop ++ nop ++ nop ++ nop ++ nop ++ ++ /* 32bit load */ ++8: ldw 0(%sr3,%r25), %r25 ++ b cas2_lock_start ++9: ldw 0(%sr3,%r24), %r24 ++ nop ++ nop ++ nop ++ nop ++ nop ++ ++ /* 64bit load */ ++#ifdef CONFIG_64BIT ++10: ldd 0(%sr3,%r25), %r25 ++11: ldd 0(%sr3,%r24), %r24 ++#else ++ /* Load new value into r22/r23 - high/low */ ++10: ldw 0(%sr3,%r25), %r22 ++11: ldw 4(%sr3,%r25), %r23 ++ /* Load new value into fr4 for atomic store later */ ++12: flddx 0(%sr3,%r24), %fr4 ++#endif ++ ++cas2_lock_start: ++ /* Load start of lock table */ ++ ldil L%lws_lock_start, %r20 ++ ldo R%lws_lock_start(%r20), %r28 ++ ++ /* Extract four bits from r26 and hash lock (Bits 4-7) */ ++ extru %r26, 27, 4, %r20 ++ ++ /* Find lock to use, the hash is either one of 0 to ++ 15, multiplied by 16 (keep it 16-byte aligned) ++ and add to the lock table offset. */ ++ shlw %r20, 4, %r20 ++ add %r20, %r28, %r20 ++ ++ rsm PSW_SM_I, %r0 /* Disable interrupts */ ++ /* COW breaks can cause contention on UP systems */ ++ LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ ++ cmpb,<>,n %r0, %r28, cas2_action /* Did we get it? */ ++cas2_wouldblock: ++ ldo 2(%r0), %r28 /* 2nd case */ ++ ssm PSW_SM_I, %r0 ++ b lws_exit /* Contended... */ ++ ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ ++ ++ /* ++ prev = *addr; ++ if ( prev == old ) ++ *addr = new; ++ return prev; ++ */ ++ ++ /* NOTES: ++ This all works becuse intr_do_signal ++ and schedule both check the return iasq ++ and see that we are on the kernel page ++ so this process is never scheduled off ++ or is ever sent any signal of any sort, ++ thus it is wholly atomic from usrspaces ++ perspective ++ */ ++cas2_action: ++ /* Jump to the correct function */ ++ blr %r29, %r0 ++ /* Set %r28 as non-zero for now */ ++ ldo 1(%r0),%r28 ++ ++ /* 8bit CAS */ ++13: ldb,ma 0(%sr3,%r26), %r29 ++ sub,= %r29, %r25, %r0 ++ b,n cas2_end ++14: stb,ma %r24, 0(%sr3,%r26) ++ b cas2_end ++ copy %r0, %r28 ++ nop ++ nop ++ ++ /* 16bit CAS */ ++15: ldh,ma 0(%sr3,%r26), %r29 ++ sub,= %r29, %r25, %r0 ++ b,n cas2_end ++16: sth,ma %r24, 0(%sr3,%r26) ++ b cas2_end ++ copy %r0, %r28 ++ nop ++ nop ++ ++ /* 32bit CAS */ ++17: ldw,ma 0(%sr3,%r26), %r29 ++ sub,= %r29, %r25, %r0 ++ b,n cas2_end ++18: stw,ma %r24, 0(%sr3,%r26) ++ b cas2_end ++ copy %r0, %r28 ++ nop ++ nop ++ ++ /* 64bit CAS */ ++#ifdef CONFIG_64BIT ++19: ldd,ma 0(%sr3,%r26), %r29 ++ sub,= %r29, %r25, %r0 ++ b,n cas2_end ++20: std,ma %r24, 0(%sr3,%r26) ++ copy %r0, %r28 ++#else ++ /* Compare first word */ ++19: ldw,ma 0(%sr3,%r26), %r29 ++ sub,= %r29, %r22, %r0 ++ b,n cas2_end ++ /* Compare second word */ ++20: ldw,ma 4(%sr3,%r26), %r29 ++ sub,= %r29, %r23, %r0 ++ b,n cas2_end ++ /* Perform the store */ ++21: fstdx %fr4, 0(%sr3,%r26) ++ copy %r0, %r28 ++#endif ++ ++cas2_end: ++ /* Free lock */ ++ stw,ma %r20, 0(%sr2,%r20) ++ /* Enable interrupts */ ++ ssm PSW_SM_I, %r0 ++ /* Return to userspace, set no error */ ++ b lws_exit ++ copy %r0, %r21 ++ ++22: ++ /* Error occurred on load or store */ ++ /* Free lock */ ++ stw %r20, 0(%sr2,%r20) ++ ssm PSW_SM_I, %r0 ++ ldo 1(%r0),%r28 ++ b lws_exit ++ ldo -EFAULT(%r0),%r21 /* set errno */ ++ nop ++ nop ++ nop ++ ++ /* Exception table entries, for the load and store, return EFAULT. ++ Each of the entries must be relocated. */ ++ ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(8b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(13b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(17b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(18b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(19b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(20b-linux_gateway_page, 22b-linux_gateway_page) ++#ifndef CONFIG_64BIT ++ ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 22b-linux_gateway_page) ++ ASM_EXCEPTIONTABLE_ENTRY(21b-linux_gateway_page, 22b-linux_gateway_page) ++#endif ++ + /* Make sure nothing else is placed on this page */ + .align PAGE_SIZE + END(linux_gateway_page) +@@ -675,8 +899,9 @@ ENTRY(end_linux_gateway_page) + /* Light-weight-syscall table */ + /* Start of lws table. */ + ENTRY(lws_table) +- LWS_ENTRY(compare_and_swap32) /* 0 - ELF32 Atomic compare and swap */ +- LWS_ENTRY(compare_and_swap64) /* 1 - ELF64 Atomic compare and swap */ ++ LWS_ENTRY(compare_and_swap32) /* 0 - ELF32 Atomic 32bit CAS */ ++ LWS_ENTRY(compare_and_swap64) /* 1 - ELF64 Atomic 32bit CAS */ ++ LWS_ENTRY(compare_and_swap_2) /* 2 - ELF32 Atomic 64bit CAS */ + END(lws_table) + /* End of lws table */ + diff --git a/queue-3.16/parisc-only-use-mfast-indirect-calls-option-for-32-bit-kernel-builds.patch b/queue-3.16/parisc-only-use-mfast-indirect-calls-option-for-32-bit-kernel-builds.patch new file mode 100644 index 00000000000..9effe5ac6fa --- /dev/null +++ b/queue-3.16/parisc-only-use-mfast-indirect-calls-option-for-32-bit-kernel-builds.patch @@ -0,0 +1,49 @@ +From d26a7730b5874a5fa6779c62f4ad7c5065a94723 Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Mon, 22 Sep 2014 20:54:50 -0400 +Subject: parisc: Only use -mfast-indirect-calls option for 32-bit kernel builds + +From: John David Anglin + +commit d26a7730b5874a5fa6779c62f4ad7c5065a94723 upstream. + +In spite of what the GCC manual says, the -mfast-indirect-calls has +never been supported in the 64-bit parisc compiler. Indirect calls have +always been done using function descriptors irrespective of the +-mfast-indirect-calls option. + +Recently, it was noticed that a function descriptor was always requested +when the -mfast-indirect-calls option was specified. This caused +problems when the option was used in application code and doesn't make +any sense because the whole point of the option is to avoid using a +function descriptor for indirect calls. + +Fixing this broke 64-bit kernel builds. + +I will fix GCC but for now we need the attached change. This results in +the same kernel code as before. + +Signed-off-by: John David Anglin +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/Makefile | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/parisc/Makefile ++++ b/arch/parisc/Makefile +@@ -48,7 +48,12 @@ cflags-y := -pipe + + # These flags should be implied by an hppa-linux configuration, but they + # are not in gcc 3.2. +-cflags-y += -mno-space-regs -mfast-indirect-calls ++cflags-y += -mno-space-regs ++ ++# -mfast-indirect-calls is only relevant for 32-bit kernels. ++ifndef CONFIG_64BIT ++cflags-y += -mfast-indirect-calls ++endif + + # Currently we save and restore fpregs on all kernel entry/interruption paths. + # If that gets optimized, we might need to disable the use of fpregs in the diff --git a/queue-3.16/revert-hwrng-virtio-ensure-reads-happen-after-successful-probe.patch b/queue-3.16/revert-hwrng-virtio-ensure-reads-happen-after-successful-probe.patch new file mode 100644 index 00000000000..d9e13e9be1c --- /dev/null +++ b/queue-3.16/revert-hwrng-virtio-ensure-reads-happen-after-successful-probe.patch @@ -0,0 +1,73 @@ +From eeec626366ffe558fc3d5685bd2b49a962acf57d Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Sun, 27 Jul 2014 07:35:01 +0930 +Subject: Revert "hwrng: virtio - ensure reads happen after successful probe" + +From: Amit Shah + +commit eeec626366ffe558fc3d5685bd2b49a962acf57d upstream. + +This reverts commit e052dbf554610e2104c5a7518c4d8374bed701bb. + +Now that we use the virtio ->scan() function to register with the hwrng +core, we will not get read requests till probe is successfully finished. + +So revert the workaround we had in place to refuse read requests while +we were not yet setup completely. + +Signed-off-by: Amit Shah +Signed-off-by: Rusty Russell +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/hw_random/core.c | 6 ------ + drivers/char/hw_random/virtio-rng.c | 9 --------- + 2 files changed, 15 deletions(-) + +--- a/drivers/char/hw_random/core.c ++++ b/drivers/char/hw_random/core.c +@@ -68,12 +68,6 @@ static void add_early_randomness(struct + unsigned char bytes[16]; + int bytes_read; + +- /* +- * Currently only virtio-rng cannot return data during device +- * probe, and that's handled in virtio-rng.c itself. If there +- * are more such devices, this call to rng_get_data can be +- * made conditional here instead of doing it per-device. +- */ + bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1); + if (bytes_read > 0) + add_device_randomness(bytes, bytes_read); +--- a/drivers/char/hw_random/virtio-rng.c ++++ b/drivers/char/hw_random/virtio-rng.c +@@ -39,7 +39,6 @@ struct virtrng_info { + bool hwrng_register_done; + }; + +-static bool probe_done; + + static void random_recv_done(struct virtqueue *vq) + { +@@ -70,13 +69,6 @@ static int virtio_read(struct hwrng *rng + int ret; + struct virtrng_info *vi = (struct virtrng_info *)rng->priv; + +- /* +- * Don't ask host for data till we're setup. This call can +- * happen during hwrng_register(), after commit d9e7972619. +- */ +- if (unlikely(!probe_done)) +- return 0; +- + if (!vi->busy) { + vi->busy = true; + init_completion(&vi->have_data); +@@ -138,7 +130,6 @@ static int probe_common(struct virtio_de + return err; + } + +- probe_done = true; + return 0; + } + diff --git a/queue-3.16/series b/queue-3.16/series index c53f8097ec2..9b21ae53edd 100644 --- a/queue-3.16/series +++ b/queue-3.16/series @@ -285,3 +285,16 @@ powerpc-perf-fix-abiv2-kernel-backtraces.patch powerpc-add-smp_mb-to-arch_spin_is_locked.patch powerpc-add-smp_mb-s-to-arch_spin_unlock_wait.patch tty-serial-at91-bug-disable-interrupts-when-uart_enable_ms.patch +don-t-bugger-nd-seq-on-set_root_rcu-from-follow_dotdot_rcu.patch +parisc-implement-new-lws-cas-supporting-64-bit-operations.patch +parisc-only-use-mfast-indirect-calls-option-for-32-bit-kernel-builds.patch +alarmtimer-return-relative-times-in-timer_gettime.patch +alarmtimer-do-not-signal-sigev_none-timers.patch +alarmtimer-lock-k_itimer-during-timer-callback.patch +virtio-rng-delay-hwrng_register-till-driver-is-ready.patch +revert-hwrng-virtio-ensure-reads-happen-after-successful-probe.patch +gfs2-fix-d_splice_alias-misuses.patch +ib-qib-correct-reference-counting-in-debugfs-qp_stats.patch +ib-mlx4-avoid-null-pointer-dereference-in-mlx4_ib_scan_netdevs.patch +ib-mlx4-don-t-duplicate-the-default-roce-gid.patch +ib-core-when-marshaling-uverbs-path-clear-unused-fields.patch diff --git a/queue-3.16/virtio-rng-delay-hwrng_register-till-driver-is-ready.patch b/queue-3.16/virtio-rng-delay-hwrng_register-till-driver-is-ready.patch new file mode 100644 index 00000000000..e0334fa1a12 --- /dev/null +++ b/queue-3.16/virtio-rng-delay-hwrng_register-till-driver-is-ready.patch @@ -0,0 +1,100 @@ +From 5c06273401f2eb7b290cadbae18ee00f8f65e893 Mon Sep 17 00:00:00 2001 +From: Amit Shah +Date: Sun, 27 Jul 2014 07:34:01 +0930 +Subject: virtio: rng: delay hwrng_register() till driver is ready + +From: Amit Shah + +commit 5c06273401f2eb7b290cadbae18ee00f8f65e893 upstream. + +Instead of calling hwrng_register() in the probe routing, call it in the +scan routine. This ensures that when hwrng_register() is successful, +and it requests a few random bytes to seed the kernel's pool at init, +we're ready to service that request. + +This will also enable us to remove the workaround added previously to +check whether probe was completed, and only then ask for data from the +host. The revert follows in the next commit. + +There's a slight behaviour change here on unsuccessful hwrng_register(). +Previously, when hwrng_register() failed, the probe() routine would +fail, and the vqs would be torn down, and driver would be marked not +initialized. Now, the vqs will remain initialized, driver would be +marked initialized as well, but won't be available in the list of RNGs +available to hwrng core. To fix the failures, the procedure remains the +same, i.e. unload and re-load the module, and hope things succeed the +next time around. + +Signed-off-by: Amit Shah +Signed-off-by: Rusty Russell +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/char/hw_random/virtio-rng.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/drivers/char/hw_random/virtio-rng.c ++++ b/drivers/char/hw_random/virtio-rng.c +@@ -36,6 +36,7 @@ struct virtrng_info { + bool busy; + char name[25]; + int index; ++ bool hwrng_register_done; + }; + + static bool probe_done; +@@ -137,15 +138,6 @@ static int probe_common(struct virtio_de + return err; + } + +- err = hwrng_register(&vi->hwrng); +- if (err) { +- vdev->config->del_vqs(vdev); +- vi->vq = NULL; +- kfree(vi); +- ida_simple_remove(&rng_index_ida, index); +- return err; +- } +- + probe_done = true; + return 0; + } +@@ -153,9 +145,11 @@ static int probe_common(struct virtio_de + static void remove_common(struct virtio_device *vdev) + { + struct virtrng_info *vi = vdev->priv; ++ + vdev->config->reset(vdev); + vi->busy = false; +- hwrng_unregister(&vi->hwrng); ++ if (vi->hwrng_register_done) ++ hwrng_unregister(&vi->hwrng); + vdev->config->del_vqs(vdev); + ida_simple_remove(&rng_index_ida, vi->index); + kfree(vi); +@@ -171,6 +165,16 @@ static void virtrng_remove(struct virtio + remove_common(vdev); + } + ++static void virtrng_scan(struct virtio_device *vdev) ++{ ++ struct virtrng_info *vi = vdev->priv; ++ int err; ++ ++ err = hwrng_register(&vi->hwrng); ++ if (!err) ++ vi->hwrng_register_done = true; ++} ++ + #ifdef CONFIG_PM_SLEEP + static int virtrng_freeze(struct virtio_device *vdev) + { +@@ -195,6 +199,7 @@ static struct virtio_driver virtio_rng_d + .id_table = id_table, + .probe = virtrng_probe, + .remove = virtrng_remove, ++ .scan = virtrng_scan, + #ifdef CONFIG_PM_SLEEP + .freeze = virtrng_freeze, + .restore = virtrng_restore, -- 2.47.3