]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 23 Nov 2020 09:51:12 +0000 (10:51 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 23 Nov 2020 09:51:12 +0000 (10:51 +0100)
added patches:
mac80211-allow-driver-to-prevent-two-stations-w-same-address.patch
mac80211-free-sta-in-sta_info_insert_finish-on-errors.patch
mac80211-minstrel-fix-tx-status-processing-corner-case.patch
mac80211-minstrel-remove-deferred-sampling-code.patch
s390-cpum_sf.c-fix-file-permission-for-cpum_sfb_size.patch
xtensa-disable-preemption-around-cache-alias-management-calls.patch

queue-4.4/mac80211-allow-driver-to-prevent-two-stations-w-same-address.patch [new file with mode: 0644]
queue-4.4/mac80211-free-sta-in-sta_info_insert_finish-on-errors.patch [new file with mode: 0644]
queue-4.4/mac80211-minstrel-fix-tx-status-processing-corner-case.patch [new file with mode: 0644]
queue-4.4/mac80211-minstrel-remove-deferred-sampling-code.patch [new file with mode: 0644]
queue-4.4/s390-cpum_sf.c-fix-file-permission-for-cpum_sfb_size.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/xtensa-disable-preemption-around-cache-alias-management-calls.patch [new file with mode: 0644]

diff --git a/queue-4.4/mac80211-allow-driver-to-prevent-two-stations-w-same-address.patch b/queue-4.4/mac80211-allow-driver-to-prevent-two-stations-w-same-address.patch
new file mode 100644 (file)
index 0000000..f0d84d2
--- /dev/null
@@ -0,0 +1,95 @@
+From 3110489117581a980537b6d999a3724214ba772c Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 22 Oct 2015 17:35:19 +0200
+Subject: mac80211: allow driver to prevent two stations w/ same address
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 3110489117581a980537b6d999a3724214ba772c upstream.
+
+Some devices or drivers cannot deal with having the same station
+address for different virtual interfaces, say as a client to two
+virtual AP interfaces. Rather than requiring each driver with a
+limitation like that to enforce it, add a hardware flag for it.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/mac80211.h  |    6 ++++++
+ net/mac80211/debugfs.c  |    1 +
+ net/mac80211/sta_info.c |   18 ++++++++++++++++--
+ 3 files changed, 23 insertions(+), 2 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1915,6 +1915,11 @@ struct ieee80211_txq {
+  * @IEEE80211_HW_BEACON_TX_STATUS: The device/driver provides TX status
+  *    for sent beacons.
+  *
++ * @IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR: Hardware (or driver) requires that each
++ *    station has a unique address, i.e. each station entry can be identified
++ *    by just its MAC address; this prevents, for example, the same station
++ *    from connecting to two virtual AP interfaces at the same time.
++ *
+  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
+  */
+ enum ieee80211_hw_flags {
+@@ -1950,6 +1955,7 @@ enum ieee80211_hw_flags {
+       IEEE80211_HW_TDLS_WIDER_BW,
+       IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU,
+       IEEE80211_HW_BEACON_TX_STATUS,
++      IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,
+       /* keep last, obviously */
+       NUM_IEEE80211_HW_FLAGS
+--- a/net/mac80211/debugfs.c
++++ b/net/mac80211/debugfs.c
+@@ -125,6 +125,7 @@ static const char *hw_flag_names[] = {
+       FLAG(TDLS_WIDER_BW),
+       FLAG(SUPPORTS_AMSDU_IN_AMPDU),
+       FLAG(BEACON_TX_STATUS),
++      FLAG(NEEDS_UNIQUE_STA_ADDR),
+ #undef FLAG
+ };
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -457,6 +457,19 @@ static int sta_info_insert_check(struct
+                   is_multicast_ether_addr(sta->sta.addr)))
+               return -EINVAL;
++      /* Strictly speaking this isn't necessary as we hold the mutex, but
++       * the rhashtable code can't really deal with that distinction. We
++       * do require the mutex for correctness though.
++       */
++      rcu_read_lock();
++      lockdep_assert_held(&sdata->local->sta_mtx);
++      if (ieee80211_hw_check(&sdata->local->hw, NEEDS_UNIQUE_STA_ADDR) &&
++          ieee80211_find_sta_by_ifaddr(&sdata->local->hw, sta->addr, NULL)) {
++              rcu_read_unlock();
++              return -ENOTUNIQ;
++      }
++      rcu_read_unlock();
++
+       return 0;
+ }
+@@ -585,14 +598,15 @@ int sta_info_insert_rcu(struct sta_info
+       might_sleep();
++      mutex_lock(&local->sta_mtx);
++
+       err = sta_info_insert_check(sta);
+       if (err) {
++              mutex_unlock(&local->sta_mtx);
+               rcu_read_lock();
+               goto out_free;
+       }
+-      mutex_lock(&local->sta_mtx);
+-
+       err = sta_info_insert_finish(sta);
+       if (err)
+               goto out_free;
diff --git a/queue-4.4/mac80211-free-sta-in-sta_info_insert_finish-on-errors.patch b/queue-4.4/mac80211-free-sta-in-sta_info_insert_finish-on-errors.patch
new file mode 100644 (file)
index 0000000..3f5e8f1
--- /dev/null
@@ -0,0 +1,72 @@
+From 7bc40aedf24d31d8bea80e1161e996ef4299fb10 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 12 Nov 2020 11:22:04 +0100
+Subject: mac80211: free sta in sta_info_insert_finish() on errors
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 7bc40aedf24d31d8bea80e1161e996ef4299fb10 upstream.
+
+If sta_info_insert_finish() fails, we currently keep the station
+around and free it only in the caller, but there's only one such
+caller and it always frees it immediately.
+
+As syzbot found, another consequence of this split is that we can
+put things that sleep only into __cleanup_single_sta() and not in
+sta_info_free(), but this is the only place that requires such of
+sta_info_free() now.
+
+Change this to free the station in sta_info_insert_finish(), in
+which case we can still sleep. This will also let us unify the
+cleanup code later.
+
+Cc: stable@vger.kernel.org
+Fixes: dcd479e10a05 ("mac80211: always wind down STA state")
+Reported-by: syzbot+32c6c38c4812d22f2f0b@syzkaller.appspotmail.com
+Reported-by: syzbot+4c81fe92e372d26c4246@syzkaller.appspotmail.com
+Reported-by: syzbot+6a7fe9faf0d1d61bc24a@syzkaller.appspotmail.com
+Reported-by: syzbot+abed06851c5ffe010921@syzkaller.appspotmail.com
+Reported-by: syzbot+b7aeb9318541a1c709f1@syzkaller.appspotmail.com
+Reported-by: syzbot+d5a9416c6cafe53b5dd0@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/r/20201112112201.ee6b397b9453.I9c31d667a0ea2151441cc64ed6613d36c18a48e0@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/sta_info.c |   14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -583,7 +583,7 @@ static int sta_info_insert_finish(struct
+  out_drop_sta:
+       local->num_sta--;
+       synchronize_net();
+-      __cleanup_single_sta(sta);
++      cleanup_single_sta(sta);
+  out_err:
+       mutex_unlock(&local->sta_mtx);
+       kfree(sinfo);
+@@ -602,19 +602,13 @@ int sta_info_insert_rcu(struct sta_info
+       err = sta_info_insert_check(sta);
+       if (err) {
++              sta_info_free(local, sta);
+               mutex_unlock(&local->sta_mtx);
+               rcu_read_lock();
+-              goto out_free;
++              return err;
+       }
+-      err = sta_info_insert_finish(sta);
+-      if (err)
+-              goto out_free;
+-
+-      return 0;
+- out_free:
+-      sta_info_free(local, sta);
+-      return err;
++      return sta_info_insert_finish(sta);
+ }
+ int sta_info_insert(struct sta_info *sta)
diff --git a/queue-4.4/mac80211-minstrel-fix-tx-status-processing-corner-case.patch b/queue-4.4/mac80211-minstrel-fix-tx-status-processing-corner-case.patch
new file mode 100644 (file)
index 0000000..827e034
--- /dev/null
@@ -0,0 +1,37 @@
+From b2911a84396f72149dce310a3b64d8948212c1b3 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 11 Nov 2020 19:33:59 +0100
+Subject: mac80211: minstrel: fix tx status processing corner case
+
+From: Felix Fietkau <nbd@nbd.name>
+
+commit b2911a84396f72149dce310a3b64d8948212c1b3 upstream.
+
+Some drivers fill the status rate list without setting the rate index after
+the final rate to -1. minstrel_ht already deals with this, but minstrel
+doesn't, which causes it to get stuck at the lowest rate on these drivers.
+
+Fix this by checking the count as well.
+
+Cc: stable@vger.kernel.org
+Fixes: cccf129f820e ("mac80211: add the 'minstrel' rate control algorithm")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://lore.kernel.org/r/20201111183359.43528-3-nbd@nbd.name
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/rc80211_minstrel.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mac80211/rc80211_minstrel.c
++++ b/net/mac80211/rc80211_minstrel.c
+@@ -274,7 +274,7 @@ minstrel_tx_status(void *priv, struct ie
+       success = !!(info->flags & IEEE80211_TX_STAT_ACK);
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+-              if (ar[i].idx < 0)
++              if (ar[i].idx < 0 || !ar[i].count)
+                       break;
+               ndx = rix_to_ndx(mi, ar[i].idx);
diff --git a/queue-4.4/mac80211-minstrel-remove-deferred-sampling-code.patch b/queue-4.4/mac80211-minstrel-remove-deferred-sampling-code.patch
new file mode 100644 (file)
index 0000000..4873efd
--- /dev/null
@@ -0,0 +1,108 @@
+From 4fe40b8e1566dad04c87fbf299049a1d0d4bd58d Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 11 Nov 2020 19:33:58 +0100
+Subject: mac80211: minstrel: remove deferred sampling code
+
+From: Felix Fietkau <nbd@nbd.name>
+
+commit 4fe40b8e1566dad04c87fbf299049a1d0d4bd58d upstream.
+
+Deferring sampling attempts to the second stage has some bad interactions
+with drivers that process the rate table in hardware and use the probe flag
+to indicate probing packets (e.g. most mt76 drivers). On affected drivers
+it can lead to probing not working at all.
+
+If the link conditions turn worse, it might not be such a good idea to
+do a lot of sampling for lower rates in this case.
+
+Fix this by simply skipping the sample attempt instead of deferring it,
+but keep the checks that would allow it to be sampled if it was skipped
+too often, but only if it has less than 95% success probability.
+
+Also ensure that IEEE80211_TX_CTL_RATE_CTRL_PROBE is set for all probing
+packets.
+
+Cc: stable@vger.kernel.org
+Fixes: cccf129f820e ("mac80211: add the 'minstrel' rate control algorithm")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://lore.kernel.org/r/20201111183359.43528-2-nbd@nbd.name
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/rc80211_minstrel.c |   25 ++++---------------------
+ net/mac80211/rc80211_minstrel.h |    1 -
+ 2 files changed, 4 insertions(+), 22 deletions(-)
+
+--- a/net/mac80211/rc80211_minstrel.c
++++ b/net/mac80211/rc80211_minstrel.c
+@@ -287,12 +287,6 @@ minstrel_tx_status(void *priv, struct ie
+                       mi->r[ndx].stats.success += success;
+       }
+-      if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
+-              mi->sample_packets++;
+-
+-      if (mi->sample_deferred > 0)
+-              mi->sample_deferred--;
+-
+       if (time_after(jiffies, mi->last_stats_update +
+                               (mp->update_interval * HZ) / 1000))
+               minstrel_update_stats(mp, mi);
+@@ -366,7 +360,7 @@ minstrel_get_rate(void *priv, struct iee
+ #endif
+       delta = (mi->total_packets * sampling_ratio / 100) -
+-                      (mi->sample_packets + mi->sample_deferred / 2);
++                      mi->sample_packets;
+       /* delta < 0: no sampling required */
+       prev_sample = mi->prev_sample;
+@@ -375,7 +369,6 @@ minstrel_get_rate(void *priv, struct iee
+               return;
+       if (mi->total_packets >= 10000) {
+-              mi->sample_deferred = 0;
+               mi->sample_packets = 0;
+               mi->total_packets = 0;
+       } else if (delta > mi->n_rates * 2) {
+@@ -400,19 +393,8 @@ minstrel_get_rate(void *priv, struct iee
+        * rate sampling method should be used.
+        * Respect such rates that are not sampled for 20 interations.
+        */
+-      if (mrr_capable &&
+-          msr->perfect_tx_time > mr->perfect_tx_time &&
+-          msr->stats.sample_skipped < 20) {
+-              /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
+-               * packets that have the sampling rate deferred to the
+-               * second MRR stage. Increase the sample counter only
+-               * if the deferred sample rate was actually used.
+-               * Use the sample_deferred counter to make sure that
+-               * the sampling is not done in large bursts */
+-              info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
+-              rate++;
+-              mi->sample_deferred++;
+-      } else {
++      if (msr->perfect_tx_time < mr->perfect_tx_time ||
++          msr->stats.sample_skipped >= 20) {
+               if (!msr->sample_limit)
+                       return;
+@@ -432,6 +414,7 @@ minstrel_get_rate(void *priv, struct iee
+       rate->idx = mi->r[ndx].rix;
+       rate->count = minstrel_get_retry_count(&mi->r[ndx], info);
++      info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
+ }
+--- a/net/mac80211/rc80211_minstrel.h
++++ b/net/mac80211/rc80211_minstrel.h
+@@ -105,7 +105,6 @@ struct minstrel_sta_info {
+       u8 max_prob_rate;
+       unsigned int total_packets;
+       unsigned int sample_packets;
+-      int sample_deferred;
+       unsigned int sample_row;
+       unsigned int sample_column;
diff --git a/queue-4.4/s390-cpum_sf.c-fix-file-permission-for-cpum_sfb_size.patch b/queue-4.4/s390-cpum_sf.c-fix-file-permission-for-cpum_sfb_size.patch
new file mode 100644 (file)
index 0000000..9eda323
--- /dev/null
@@ -0,0 +1,43 @@
+From 78d732e1f326f74f240d416af9484928303d9951 Mon Sep 17 00:00:00 2001
+From: Thomas Richter <tmricht@linux.ibm.com>
+Date: Wed, 11 Nov 2020 16:26:25 +0100
+Subject: s390/cpum_sf.c: fix file permission for cpum_sfb_size
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+commit 78d732e1f326f74f240d416af9484928303d9951 upstream.
+
+This file is installed by the s390 CPU Measurement sampling
+facility device driver to export supported minimum and
+maximum sample buffer sizes.
+This file is read by lscpumf tool to display the details
+of the device driver capabilities. The lscpumf tool might
+be invoked by a non-root user. In this case it does not
+print anything because the file contents can not be read.
+
+Fix this by allowing read access for all users. Reading
+the file contents is ok, changing the file contents is
+left to the root user only.
+
+For further reference and details see:
+ [1] https://github.com/ibm-s390-tools/s390-tools/issues/97
+
+Fixes: 69f239ed335a ("s390/cpum_sf: Dynamically extend the sampling buffer if overflows occur")
+Cc: <stable@vger.kernel.org> # 3.14
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/kernel/perf_cpum_sf.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/s390/kernel/perf_cpum_sf.c
++++ b/arch/s390/kernel/perf_cpum_sf.c
+@@ -1666,4 +1666,4 @@ out:
+       return err;
+ }
+ arch_initcall(init_cpum_sampling_pmu);
+-core_param(cpum_sfb_size, CPUM_SF_MAX_SDB, sfb_size, 0640);
++core_param(cpum_sfb_size, CPUM_SF_MAX_SDB, sfb_size, 0644);
index cd77b93139ac56b81d5347c2d1704d5bfdca9f6b..fd3a34d7df239e156ec95eb4ff598f4d987fa71c 100644 (file)
@@ -29,3 +29,9 @@ alsa-mixart-fix-mutex-deadlock.patch
 tty-serial-imx-keep-console-clocks-always-on.patch
 efivarfs-fix-memory-leak-in-efivarfs_create.patch
 ext4-fix-bogus-warning-in-ext4_update_dx_flag.patch
+xtensa-disable-preemption-around-cache-alias-management-calls.patch
+mac80211-minstrel-remove-deferred-sampling-code.patch
+mac80211-minstrel-fix-tx-status-processing-corner-case.patch
+mac80211-allow-driver-to-prevent-two-stations-w-same-address.patch
+mac80211-free-sta-in-sta_info_insert_finish-on-errors.patch
+s390-cpum_sf.c-fix-file-permission-for-cpum_sfb_size.patch
diff --git a/queue-4.4/xtensa-disable-preemption-around-cache-alias-management-calls.patch b/queue-4.4/xtensa-disable-preemption-around-cache-alias-management-calls.patch
new file mode 100644 (file)
index 0000000..2026f55
--- /dev/null
@@ -0,0 +1,110 @@
+From 3a860d165eb5f4d7cf0bf81ef6a5b5c5e1754422 Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Mon, 16 Nov 2020 01:38:59 -0800
+Subject: xtensa: disable preemption around cache alias management calls
+
+From: Max Filippov <jcmvbkbc@gmail.com>
+
+commit 3a860d165eb5f4d7cf0bf81ef6a5b5c5e1754422 upstream.
+
+Although cache alias management calls set up and tear down TLB entries
+and fast_second_level_miss is able to restore TLB entry should it be
+evicted they absolutely cannot preempt each other because they use the
+same TLBTEMP area for different purposes.
+Disable preemption around all cache alias management calls to enforce
+that.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/xtensa/mm/cache.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/arch/xtensa/mm/cache.c
++++ b/arch/xtensa/mm/cache.c
+@@ -74,8 +74,10 @@ static inline void kmap_invalidate_coher
+                       kvaddr = TLBTEMP_BASE_1 +
+                               (page_to_phys(page) & DCACHE_ALIAS_MASK);
++                      preempt_disable();
+                       __invalidate_dcache_page_alias(kvaddr,
+                                                      page_to_phys(page));
++                      preempt_enable();
+               }
+       }
+ }
+@@ -162,6 +164,7 @@ void flush_dcache_page(struct page *page
+               if (!alias && !mapping)
+                       return;
++              preempt_disable();
+               virt = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
+               __flush_invalidate_dcache_page_alias(virt, phys);
+@@ -172,6 +175,7 @@ void flush_dcache_page(struct page *page
+               if (mapping)
+                       __invalidate_icache_page_alias(virt, phys);
++              preempt_enable();
+       }
+       /* There shouldn't be an entry in the cache for this page anymore. */
+@@ -204,8 +208,10 @@ void local_flush_cache_page(struct vm_ar
+       unsigned long phys = page_to_phys(pfn_to_page(pfn));
+       unsigned long virt = TLBTEMP_BASE_1 + (address & DCACHE_ALIAS_MASK);
++      preempt_disable();
+       __flush_invalidate_dcache_page_alias(virt, phys);
+       __invalidate_icache_page_alias(virt, phys);
++      preempt_enable();
+ }
+ #endif
+@@ -231,11 +237,13 @@ update_mmu_cache(struct vm_area_struct *
+               unsigned long phys = page_to_phys(page);
+               unsigned long tmp;
++              preempt_disable();
+               tmp = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
+               __flush_invalidate_dcache_page_alias(tmp, phys);
+               tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK);
+               __flush_invalidate_dcache_page_alias(tmp, phys);
+               __invalidate_icache_page_alias(tmp, phys);
++              preempt_enable();
+               clear_bit(PG_arch_1, &page->flags);
+       }
+@@ -269,7 +277,9 @@ void copy_to_user_page(struct vm_area_st
+       if (alias) {
+               unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
++              preempt_disable();
+               __flush_invalidate_dcache_page_alias(t, phys);
++              preempt_enable();
+       }
+       /* Copy data */
+@@ -284,9 +294,11 @@ void copy_to_user_page(struct vm_area_st
+       if (alias) {
+               unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
++              preempt_disable();
+               __flush_invalidate_dcache_range((unsigned long) dst, len);
+               if ((vma->vm_flags & VM_EXEC) != 0)
+                       __invalidate_icache_page_alias(t, phys);
++              preempt_enable();
+       } else if ((vma->vm_flags & VM_EXEC) != 0) {
+               __flush_dcache_range((unsigned long)dst,len);
+@@ -308,7 +320,9 @@ extern void copy_from_user_page(struct v
+       if (alias) {
+               unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
++              preempt_disable();
+               __flush_invalidate_dcache_page_alias(t, phys);
++              preempt_enable();
+       }
+       memcpy(dst, src, len);