^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (c) 2016 Citrix Systems Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * modify it under the terms of the GNU General Public License version 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * as published by the Free Softare Foundation; or, when distributed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * separately from the Linux kernel or incorporated into other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * software packages, subject to the following license:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Permission is hereby granted, free of charge, to any person obtaining a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * of this source file (the "Software"), to deal in the Software without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * restriction, including without limitation the rights to use, copy, modify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * merge, publish, distribute, sublicense, and/or sell copies of the Software,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * and to permit persons to whom the Software is furnished to do so, subject to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * the following conditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * The above copyright notice and this permission notice shall be included in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * all copies or substantial portions of the Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * IN THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define XEN_NETIF_DEFINE_TOEPLITZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static void xenvif_add_hash(struct xenvif *vif, const u8 *tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned int len, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct xenvif_hash_cache_entry *new, *entry, *oldest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) bool found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) new = kmalloc(sizeof(*entry), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) memcpy(new->tag, tag, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) new->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) new->val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) spin_lock_irqsave(&vif->hash.cache.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) oldest = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) list_for_each_entry_rcu(entry, &vif->hash.cache.list, link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) lockdep_is_held(&vif->hash.cache.lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* Make sure we don't add duplicate entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (entry->len == len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) memcmp(entry->tag, tag, len) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (!oldest || entry->seq < oldest->seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) oldest = entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) new->seq = atomic_inc_return(&vif->hash.cache.seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) list_add_rcu(&new->link, &vif->hash.cache.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (++vif->hash.cache.count > xenvif_hash_cache_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) list_del_rcu(&oldest->link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) vif->hash.cache.count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) kfree_rcu(oldest, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) spin_unlock_irqrestore(&vif->hash.cache.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static u32 xenvif_new_hash(struct xenvif *vif, const u8 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) val = xen_netif_toeplitz_hash(vif->hash.key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) sizeof(vif->hash.key),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (xenvif_hash_cache_size != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) xenvif_add_hash(vif, data, len, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void xenvif_flush_hash(struct xenvif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct xenvif_hash_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (xenvif_hash_cache_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) spin_lock_irqsave(&vif->hash.cache.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) list_for_each_entry_rcu(entry, &vif->hash.cache.list, link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) lockdep_is_held(&vif->hash.cache.lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) list_del_rcu(&entry->link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) vif->hash.cache.count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) kfree_rcu(entry, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) spin_unlock_irqrestore(&vif->hash.cache.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static u32 xenvif_find_hash(struct xenvif *vif, const u8 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct xenvif_hash_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) bool found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (len >= XEN_NETBK_HASH_TAG_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (xenvif_hash_cache_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return xenvif_new_hash(vif, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) list_for_each_entry_rcu(entry, &vif->hash.cache.list, link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (entry->len == len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) memcmp(entry->tag, data, len) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) val = entry->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) entry->seq = atomic_inc_return(&vif->hash.cache.seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) val = xenvif_new_hash(vif, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) void xenvif_set_skb_hash(struct xenvif *vif, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct flow_keys flow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u32 hash = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) enum pkt_hash_types type = PKT_HASH_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u32 flags = vif->hash.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) bool has_tcp_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Quick rejection test: If the network protocol doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * correspond to any enabled hash type then there's no point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * in parsing the packet header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) switch (skb->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (flags & (XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) XEN_NETIF_CTRL_HASH_TYPE_IPV4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (flags & (XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) XEN_NETIF_CTRL_HASH_TYPE_IPV6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) memset(&flow, 0, sizeof(flow));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (!skb_flow_dissect_flow_keys(skb, &flow, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) has_tcp_hdr = (flow.basic.ip_proto == IPPROTO_TCP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) !(flow.control.flags & FLOW_DIS_IS_FRAGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) switch (skb->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (has_tcp_hdr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) (flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u8 data[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) memcpy(&data[0], &flow.addrs.v4addrs.src, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) memcpy(&data[4], &flow.addrs.v4addrs.dst, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) memcpy(&data[8], &flow.ports.src, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) memcpy(&data[10], &flow.ports.dst, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) hash = xenvif_find_hash(vif, data, sizeof(data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) type = PKT_HASH_TYPE_L4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) } else if (flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 data[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) memcpy(&data[0], &flow.addrs.v4addrs.src, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) memcpy(&data[4], &flow.addrs.v4addrs.dst, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) hash = xenvif_find_hash(vif, data, sizeof(data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) type = PKT_HASH_TYPE_L3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (has_tcp_hdr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) (flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) u8 data[36];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) memcpy(&data[0], &flow.addrs.v6addrs.src, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) memcpy(&data[16], &flow.addrs.v6addrs.dst, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) memcpy(&data[32], &flow.ports.src, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) memcpy(&data[34], &flow.ports.dst, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) hash = xenvif_find_hash(vif, data, sizeof(data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) type = PKT_HASH_TYPE_L4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) } else if (flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u8 data[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) memcpy(&data[0], &flow.addrs.v6addrs.src, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) memcpy(&data[16], &flow.addrs.v6addrs.dst, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) hash = xenvif_find_hash(vif, data, sizeof(data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) type = PKT_HASH_TYPE_L3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (type == PKT_HASH_TYPE_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) skb_clear_hash(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) __skb_set_sw_hash(skb, hash, type == PKT_HASH_TYPE_L4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u32 xenvif_set_hash_alg(struct xenvif *vif, u32 alg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) switch (alg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case XEN_NETIF_CTRL_HASH_ALGORITHM_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case XEN_NETIF_CTRL_HASH_ALGORITHM_TOEPLITZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) vif->hash.alg = alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return XEN_NETIF_CTRL_STATUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) u32 xenvif_get_hash_flags(struct xenvif *vif, u32 *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *flags = XEN_NETIF_CTRL_HASH_TYPE_IPV4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) XEN_NETIF_CTRL_HASH_TYPE_IPV6 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return XEN_NETIF_CTRL_STATUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) u32 xenvif_set_hash_flags(struct xenvif *vif, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (flags & ~(XEN_NETIF_CTRL_HASH_TYPE_IPV4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) XEN_NETIF_CTRL_HASH_TYPE_IPV6 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) vif->hash.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return XEN_NETIF_CTRL_STATUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) u32 xenvif_set_hash_key(struct xenvif *vif, u32 gref, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u8 *key = vif->hash.key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct gnttab_copy copy_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .source.u.ref = gref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .source.domid = vif->domid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .dest.u.gmfn = virt_to_gfn(key),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .dest.domid = DOMID_SELF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .dest.offset = xen_offset_in_page(key),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .len = len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .flags = GNTCOPY_source_gref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (len > XEN_NETBK_MAX_HASH_KEY_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (copy_op.len != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) gnttab_batch_copy(©_op, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (copy_op.status != GNTST_okay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* Clear any remaining key octets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (len < XEN_NETBK_MAX_HASH_KEY_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) memset(key + len, 0, XEN_NETBK_MAX_HASH_KEY_SIZE - len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) xenvif_flush_hash(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return XEN_NETIF_CTRL_STATUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) u32 xenvif_set_hash_mapping_size(struct xenvif *vif, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (size > XEN_NETBK_MAX_HASH_MAPPING_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) vif->hash.size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) memset(vif->hash.mapping[vif->hash.mapping_sel], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) sizeof(u32) * size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return XEN_NETIF_CTRL_STATUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) u32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) u32 off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) u32 *mapping = vif->hash.mapping[!vif->hash.mapping_sel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) unsigned int nr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct gnttab_copy copy_op[2] = {{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .source.u.ref = gref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .source.domid = vif->domid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) .dest.domid = DOMID_SELF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .len = len * sizeof(*mapping),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .flags = GNTCOPY_source_gref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if ((off + len < off) || (off + len > vif->hash.size) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) len > XEN_PAGE_SIZE / sizeof(*mapping))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) copy_op[0].dest.u.gmfn = virt_to_gfn(mapping + off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) copy_op[0].dest.offset = xen_offset_in_page(mapping + off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (copy_op[0].dest.offset + copy_op[0].len > XEN_PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) copy_op[1] = copy_op[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) copy_op[1].source.offset = XEN_PAGE_SIZE - copy_op[0].dest.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) copy_op[1].dest.u.gmfn = virt_to_gfn(mapping + off + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) copy_op[1].dest.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) copy_op[1].len = copy_op[0].len - copy_op[1].source.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) copy_op[0].len = copy_op[1].source.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) nr = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) memcpy(mapping, vif->hash.mapping[vif->hash.mapping_sel],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) vif->hash.size * sizeof(*mapping));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (copy_op[0].len != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) gnttab_batch_copy(copy_op, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (copy_op[0].status != GNTST_okay ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) copy_op[nr - 1].status != GNTST_okay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) while (len-- != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (mapping[off++] >= vif->num_queues)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) vif->hash.mapping_sel = !vif->hash.mapping_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return XEN_NETIF_CTRL_STATUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) void xenvif_dump_hash_info(struct xenvif *vif, struct seq_file *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) switch (vif->hash.alg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) case XEN_NETIF_CTRL_HASH_ALGORITHM_TOEPLITZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) seq_puts(m, "Hash Algorithm: TOEPLITZ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case XEN_NETIF_CTRL_HASH_ALGORITHM_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) seq_puts(m, "Hash Algorithm: NONE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (vif->hash.flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) seq_puts(m, "\nHash Flags:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) seq_puts(m, "- IPv4\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) seq_puts(m, "- IPv4 + TCP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) seq_puts(m, "- IPv6\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) seq_puts(m, "- IPv6 + TCP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) seq_puts(m, "\nHash Key:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) for (i = 0; i < XEN_NETBK_MAX_HASH_KEY_SIZE; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) unsigned int j, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) n = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (i + n >= XEN_NETBK_MAX_HASH_KEY_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) n = XEN_NETBK_MAX_HASH_KEY_SIZE - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) seq_printf(m, "[%2u - %2u]: ", i, i + n - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) for (j = 0; j < n; j++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) seq_printf(m, "%02x ", vif->hash.key[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) seq_puts(m, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (vif->hash.size != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) const u32 *mapping = vif->hash.mapping[vif->hash.mapping_sel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) seq_puts(m, "\nHash Mapping:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) for (i = 0; i < vif->hash.size; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) unsigned int j, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) n = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (i + n >= vif->hash.size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) n = vif->hash.size - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) seq_printf(m, "[%4u - %4u]: ", i, i + n - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) for (j = 0; j < n; j++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) seq_printf(m, "%4u ", mapping[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) seq_puts(m, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) #endif /* CONFIG_DEBUG_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) void xenvif_init_hash(struct xenvif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (xenvif_hash_cache_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) BUG_ON(vif->hash.cache.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) spin_lock_init(&vif->hash.cache.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) INIT_LIST_HEAD(&vif->hash.cache.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) void xenvif_deinit_hash(struct xenvif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) xenvif_flush_hash(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }