cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

spapr_llan.c (27367B)


      1/*
      2 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
      3 *
      4 * PAPR Inter-VM Logical Lan, aka ibmveth
      5 *
      6 * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
      7 *
      8 * Permission is hereby granted, free of charge, to any person obtaining a copy
      9 * of this software and associated documentation files (the "Software"), to deal
     10 * in the Software without restriction, including without limitation the rights
     11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     12 * copies of the Software, and to permit persons to whom the Software is
     13 * furnished to do so, subject to the following conditions:
     14 *
     15 * The above copyright notice and this permission notice shall be included in
     16 * all copies or substantial portions of the Software.
     17 *
     18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     24 * THE SOFTWARE.
     25 *
     26 */
     27
     28#include "qemu/osdep.h"
     29#include "qemu/log.h"
     30#include "qemu/module.h"
     31#include "net/net.h"
     32#include "migration/vmstate.h"
     33#include "hw/ppc/spapr.h"
     34#include "hw/ppc/spapr_vio.h"
     35#include "hw/qdev-properties.h"
     36#include "sysemu/sysemu.h"
     37#include "trace.h"
     38
     39#include <libfdt.h>
     40#include "qom/object.h"
     41
     42#define ETH_ALEN        6
     43#define MAX_PACKET_SIZE 65536
     44
     45/* Compatibility flags for migration */
     46#define SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT  0
     47#define SPAPRVLAN_FLAG_RX_BUF_POOLS      (1 << SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT)
     48
     49/*
     50 * Virtual LAN device
     51 */
     52
     53typedef uint64_t vlan_bd_t;
     54
     55#define VLAN_BD_VALID        0x8000000000000000ULL
     56#define VLAN_BD_TOGGLE       0x4000000000000000ULL
     57#define VLAN_BD_NO_CSUM      0x0200000000000000ULL
     58#define VLAN_BD_CSUM_GOOD    0x0100000000000000ULL
     59#define VLAN_BD_LEN_MASK     0x00ffffff00000000ULL
     60#define VLAN_BD_LEN(bd)      (((bd) & VLAN_BD_LEN_MASK) >> 32)
     61#define VLAN_BD_ADDR_MASK    0x00000000ffffffffULL
     62#define VLAN_BD_ADDR(bd)     ((bd) & VLAN_BD_ADDR_MASK)
     63
     64#define VLAN_VALID_BD(addr, len) (VLAN_BD_VALID | \
     65                                  (((len) << 32) & VLAN_BD_LEN_MASK) |  \
     66                                  (addr & VLAN_BD_ADDR_MASK))
     67
     68#define VLAN_RXQC_TOGGLE     0x80
     69#define VLAN_RXQC_VALID      0x40
     70#define VLAN_RXQC_NO_CSUM    0x02
     71#define VLAN_RXQC_CSUM_GOOD  0x01
     72
     73#define VLAN_RQ_ALIGNMENT    16
     74#define VLAN_RXQ_BD_OFF      0
     75#define VLAN_FILTER_BD_OFF   8
     76#define VLAN_RX_BDS_OFF      16
     77/*
     78 * The final 8 bytes of the buffer list is a counter of frames dropped
     79 * because there was not a buffer in the buffer list capable of holding
     80 * the frame. We must avoid it, or the operating system will report garbage
     81 * for this statistic.
     82 */
     83#define VLAN_RX_BDS_LEN      (SPAPR_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF - 8)
     84#define VLAN_MAX_BUFS        (VLAN_RX_BDS_LEN / 8)
     85
     86#define TYPE_VIO_SPAPR_VLAN_DEVICE "spapr-vlan"
     87OBJECT_DECLARE_SIMPLE_TYPE(SpaprVioVlan, VIO_SPAPR_VLAN_DEVICE)
     88
     89#define RX_POOL_MAX_BDS 4096
     90#define RX_MAX_POOLS 5
     91
     92typedef struct {
     93    int32_t bufsize;
     94    int32_t count;
     95    vlan_bd_t bds[RX_POOL_MAX_BDS];
     96} RxBufPool;
     97
     98struct SpaprVioVlan {
     99    SpaprVioDevice sdev;
    100    NICConf nicconf;
    101    NICState *nic;
    102    MACAddr perm_mac;
    103    bool isopen;
    104    hwaddr buf_list;
    105    uint32_t add_buf_ptr, use_buf_ptr, rx_bufs;
    106    hwaddr rxq_ptr;
    107    QEMUTimer *rxp_timer;
    108    uint32_t compat_flags;             /* Compatibility flags for migration */
    109    RxBufPool *rx_pool[RX_MAX_POOLS];  /* Receive buffer descriptor pools */
    110};
    111
    112static bool spapr_vlan_can_receive(NetClientState *nc)
    113{
    114    SpaprVioVlan *dev = qemu_get_nic_opaque(nc);
    115
    116    return dev->isopen && dev->rx_bufs > 0;
    117}
    118
    119/**
    120 * The last 8 bytes of the receive buffer list page (that has been
    121 * supplied by the guest with the H_REGISTER_LOGICAL_LAN call) contain
    122 * a counter for frames that have been dropped because there was no
    123 * suitable receive buffer available. This function is used to increase
    124 * this counter by one.
    125 */
    126static void spapr_vlan_record_dropped_rx_frame(SpaprVioVlan *dev)
    127{
    128    uint64_t cnt;
    129
    130    cnt = vio_ldq(&dev->sdev, dev->buf_list + 4096 - 8);
    131    vio_stq(&dev->sdev, dev->buf_list + 4096 - 8, cnt + 1);
    132}
    133
    134/**
    135 * Get buffer descriptor from one of our receive buffer pools
    136 */
    137static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(SpaprVioVlan *dev,
    138                                                size_t size)
    139{
    140    vlan_bd_t bd;
    141    int pool;
    142
    143    for (pool = 0; pool < RX_MAX_POOLS; pool++) {
    144        if (dev->rx_pool[pool]->count > 0 &&
    145            dev->rx_pool[pool]->bufsize >= size + 8) {
    146            break;
    147        }
    148    }
    149    if (pool == RX_MAX_POOLS) {
    150        /* Failed to find a suitable buffer */
    151        return 0;
    152    }
    153
    154
    155    trace_spapr_vlan_get_rx_bd_from_pool_found(pool,
    156                                               dev->rx_pool[pool]->count,
    157                                               dev->rx_bufs);
    158
    159    /* Remove the buffer from the pool */
    160    dev->rx_pool[pool]->count--;
    161    bd = dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count];
    162    dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count] = 0;
    163
    164    return bd;
    165}
    166
    167/**
    168 * Get buffer descriptor from the receive buffer list page that has been
    169 * supplied by the guest with the H_REGISTER_LOGICAL_LAN call
    170 */
    171static vlan_bd_t spapr_vlan_get_rx_bd_from_page(SpaprVioVlan *dev,
    172                                                size_t size)
    173{
    174    int buf_ptr = dev->use_buf_ptr;
    175    vlan_bd_t bd;
    176
    177    do {
    178        buf_ptr += 8;
    179        if (buf_ptr >= VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF) {
    180            buf_ptr = VLAN_RX_BDS_OFF;
    181        }
    182
    183        bd = vio_ldq(&dev->sdev, dev->buf_list + buf_ptr);
    184
    185        trace_spapr_vlan_get_rx_bd_from_page(buf_ptr, (uint64_t)bd);
    186    } while ((!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8)
    187             && buf_ptr != dev->use_buf_ptr);
    188
    189    if (!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8) {
    190        /* Failed to find a suitable buffer */
    191        return 0;
    192    }
    193
    194    /* Remove the buffer from the pool */
    195    dev->use_buf_ptr = buf_ptr;
    196    vio_stq(&dev->sdev, dev->buf_list + dev->use_buf_ptr, 0);
    197
    198    trace_spapr_vlan_get_rx_bd_from_page_found(dev->use_buf_ptr, dev->rx_bufs);
    199
    200    return bd;
    201}
    202
    203static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
    204                                  size_t size)
    205{
    206    SpaprVioVlan *dev = qemu_get_nic_opaque(nc);
    207    SpaprVioDevice *sdev = VIO_SPAPR_DEVICE(dev);
    208    vlan_bd_t rxq_bd = vio_ldq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF);
    209    vlan_bd_t bd;
    210    uint64_t handle;
    211    uint8_t control;
    212
    213    trace_spapr_vlan_receive(sdev->qdev.id, dev->rx_bufs);
    214
    215    if (!dev->isopen) {
    216        return -1;
    217    }
    218
    219    if (!dev->rx_bufs) {
    220        spapr_vlan_record_dropped_rx_frame(dev);
    221        return 0;
    222    }
    223
    224    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
    225        bd = spapr_vlan_get_rx_bd_from_pool(dev, size);
    226    } else {
    227        bd = spapr_vlan_get_rx_bd_from_page(dev, size);
    228    }
    229    if (!bd) {
    230        spapr_vlan_record_dropped_rx_frame(dev);
    231        return 0;
    232    }
    233
    234    dev->rx_bufs--;
    235
    236    /* Transfer the packet data */
    237    if (spapr_vio_dma_write(sdev, VLAN_BD_ADDR(bd) + 8, buf, size) < 0) {
    238        return -1;
    239    }
    240
    241    trace_spapr_vlan_receive_dma_completed();
    242
    243    /* Update the receive queue */
    244    control = VLAN_RXQC_TOGGLE | VLAN_RXQC_VALID;
    245    if (rxq_bd & VLAN_BD_TOGGLE) {
    246        control ^= VLAN_RXQC_TOGGLE;
    247    }
    248
    249    handle = vio_ldq(sdev, VLAN_BD_ADDR(bd));
    250    vio_stq(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 8, handle);
    251    vio_stl(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 4, size);
    252    vio_sth(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 2, 8);
    253    vio_stb(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr, control);
    254
    255    trace_spapr_vlan_receive_wrote(dev->rxq_ptr,
    256                                   vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
    257                                                 dev->rxq_ptr),
    258                                   vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
    259                                                 dev->rxq_ptr + 8));
    260
    261    dev->rxq_ptr += 16;
    262    if (dev->rxq_ptr >= VLAN_BD_LEN(rxq_bd)) {
    263        dev->rxq_ptr = 0;
    264        vio_stq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF, rxq_bd ^ VLAN_BD_TOGGLE);
    265    }
    266
    267    if (sdev->signal_state & 1) {
    268        spapr_vio_irq_pulse(sdev);
    269    }
    270
    271    return size;
    272}
    273
    274static NetClientInfo net_spapr_vlan_info = {
    275    .type = NET_CLIENT_DRIVER_NIC,
    276    .size = sizeof(NICState),
    277    .can_receive = spapr_vlan_can_receive,
    278    .receive = spapr_vlan_receive,
    279};
    280
    281static void spapr_vlan_flush_rx_queue(void *opaque)
    282{
    283    SpaprVioVlan *dev = opaque;
    284
    285    qemu_flush_queued_packets(qemu_get_queue(dev->nic));
    286}
    287
    288static void spapr_vlan_reset_rx_pool(RxBufPool *rxp)
    289{
    290    /*
    291     * Use INT_MAX as bufsize so that unused buffers are moved to the end
    292     * of the list during the qsort in spapr_vlan_add_rxbuf_to_pool() later.
    293     */
    294    rxp->bufsize = INT_MAX;
    295    rxp->count = 0;
    296    memset(rxp->bds, 0, sizeof(rxp->bds));
    297}
    298
    299static void spapr_vlan_reset(SpaprVioDevice *sdev)
    300{
    301    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    302    int i;
    303
    304    dev->buf_list = 0;
    305    dev->rx_bufs = 0;
    306    dev->isopen = 0;
    307
    308    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
    309        for (i = 0; i < RX_MAX_POOLS; i++) {
    310            spapr_vlan_reset_rx_pool(dev->rx_pool[i]);
    311        }
    312    }
    313
    314    memcpy(&dev->nicconf.macaddr.a, &dev->perm_mac.a,
    315           sizeof(dev->nicconf.macaddr.a));
    316    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
    317}
    318
    319static void spapr_vlan_realize(SpaprVioDevice *sdev, Error **errp)
    320{
    321    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    322
    323    qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);
    324
    325    memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, sizeof(dev->perm_mac.a));
    326
    327    dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
    328                            object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
    329    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
    330
    331    dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue,
    332                                  dev);
    333}
    334
    335static void spapr_vlan_instance_init(Object *obj)
    336{
    337    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(obj);
    338    int i;
    339
    340    device_add_bootindex_property(obj, &dev->nicconf.bootindex,
    341                                  "bootindex", "",
    342                                  DEVICE(dev));
    343
    344    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
    345        for (i = 0; i < RX_MAX_POOLS; i++) {
    346            dev->rx_pool[i] = g_new(RxBufPool, 1);
    347            spapr_vlan_reset_rx_pool(dev->rx_pool[i]);
    348        }
    349    }
    350}
    351
    352static void spapr_vlan_instance_finalize(Object *obj)
    353{
    354    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(obj);
    355    int i;
    356
    357    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
    358        for (i = 0; i < RX_MAX_POOLS; i++) {
    359            g_free(dev->rx_pool[i]);
    360            dev->rx_pool[i] = NULL;
    361        }
    362    }
    363
    364    if (dev->rxp_timer) {
    365        timer_free(dev->rxp_timer);
    366    }
    367}
    368
    369void spapr_vlan_create(SpaprVioBus *bus, NICInfo *nd)
    370{
    371    DeviceState *dev;
    372
    373    dev = qdev_new("spapr-vlan");
    374
    375    qdev_set_nic_properties(dev, nd);
    376
    377    qdev_realize_and_unref(dev, &bus->bus, &error_fatal);
    378}
    379
    380static int spapr_vlan_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
    381{
    382    SpaprVioVlan *vdev = VIO_SPAPR_VLAN_DEVICE(dev);
    383    uint8_t padded_mac[8] = {0, 0};
    384    int ret;
    385
    386    /* Some old phyp versions give the mac address in an 8-byte
    387     * property.  The kernel driver (before 3.10) has an insane workaround;
    388     * rather than doing the obvious thing and checking the property
    389     * length, it checks whether the first byte has 0b10 in the low
    390     * bits.  If a correct 6-byte property has a different first byte
    391     * the kernel will get the wrong mac address, overrunning its
    392     * buffer in the process (read only, thank goodness).
    393     *
    394     * Here we return a 6-byte address unless that would break a pre-3.10
    395     * driver.  In that case we return a padded 8-byte address to allow the old
    396     * workaround to succeed. */
    397    if ((vdev->nicconf.macaddr.a[0] & 0x3) == 0x2) {
    398        ret = fdt_setprop(fdt, node_off, "local-mac-address",
    399                          &vdev->nicconf.macaddr, ETH_ALEN);
    400    } else {
    401        memcpy(&padded_mac[2], &vdev->nicconf.macaddr, ETH_ALEN);
    402        ret = fdt_setprop(fdt, node_off, "local-mac-address",
    403                          padded_mac, sizeof(padded_mac));
    404    }
    405    if (ret < 0) {
    406        return ret;
    407    }
    408
    409    ret = fdt_setprop_cell(fdt, node_off, "ibm,mac-address-filters", 0);
    410    if (ret < 0) {
    411        return ret;
    412    }
    413
    414    return 0;
    415}
    416
    417static int check_bd(SpaprVioVlan *dev, vlan_bd_t bd,
    418                    target_ulong alignment)
    419{
    420    if ((VLAN_BD_ADDR(bd) % alignment)
    421        || (VLAN_BD_LEN(bd) % alignment)) {
    422        return -1;
    423    }
    424
    425    if (!spapr_vio_dma_valid(&dev->sdev, VLAN_BD_ADDR(bd),
    426                             VLAN_BD_LEN(bd), DMA_DIRECTION_FROM_DEVICE)
    427        || !spapr_vio_dma_valid(&dev->sdev, VLAN_BD_ADDR(bd),
    428                                VLAN_BD_LEN(bd), DMA_DIRECTION_TO_DEVICE)) {
    429        return -1;
    430    }
    431
    432    return 0;
    433}
    434
    435static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
    436                                           SpaprMachineState *spapr,
    437                                           target_ulong opcode,
    438                                           target_ulong *args)
    439{
    440    target_ulong reg = args[0];
    441    target_ulong buf_list = args[1];
    442    target_ulong rec_queue = args[2];
    443    target_ulong filter_list = args[3];
    444    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    445    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    446    vlan_bd_t filter_list_bd;
    447
    448    if (!dev) {
    449        return H_PARAMETER;
    450    }
    451
    452    if (dev->isopen) {
    453        hcall_dprintf("H_REGISTER_LOGICAL_LAN called twice without "
    454                      "H_FREE_LOGICAL_LAN\n");
    455        return H_RESOURCE;
    456    }
    457
    458    if (check_bd(dev, VLAN_VALID_BD(buf_list, SPAPR_TCE_PAGE_SIZE),
    459                 SPAPR_TCE_PAGE_SIZE) < 0) {
    460        hcall_dprintf("Bad buf_list 0x" TARGET_FMT_lx "\n", buf_list);
    461        return H_PARAMETER;
    462    }
    463
    464    filter_list_bd = VLAN_VALID_BD(filter_list, SPAPR_TCE_PAGE_SIZE);
    465    if (check_bd(dev, filter_list_bd, SPAPR_TCE_PAGE_SIZE) < 0) {
    466        hcall_dprintf("Bad filter_list 0x" TARGET_FMT_lx "\n", filter_list);
    467        return H_PARAMETER;
    468    }
    469
    470    if (!(rec_queue & VLAN_BD_VALID)
    471        || (check_bd(dev, rec_queue, VLAN_RQ_ALIGNMENT) < 0)) {
    472        hcall_dprintf("Bad receive queue\n");
    473        return H_PARAMETER;
    474    }
    475
    476    dev->buf_list = buf_list;
    477    sdev->signal_state = 0;
    478
    479    rec_queue &= ~VLAN_BD_TOGGLE;
    480
    481    /* Initialize the buffer list */
    482    vio_stq(sdev, buf_list, rec_queue);
    483    vio_stq(sdev, buf_list + 8, filter_list_bd);
    484    spapr_vio_dma_set(sdev, buf_list + VLAN_RX_BDS_OFF, 0,
    485                      SPAPR_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF);
    486    dev->add_buf_ptr = VLAN_RX_BDS_OFF - 8;
    487    dev->use_buf_ptr = VLAN_RX_BDS_OFF - 8;
    488    dev->rx_bufs = 0;
    489    dev->rxq_ptr = 0;
    490
    491    /* Initialize the receive queue */
    492    spapr_vio_dma_set(sdev, VLAN_BD_ADDR(rec_queue), 0, VLAN_BD_LEN(rec_queue));
    493
    494    dev->isopen = 1;
    495    qemu_flush_queued_packets(qemu_get_queue(dev->nic));
    496
    497    return H_SUCCESS;
    498}
    499
    500
    501static target_ulong h_free_logical_lan(PowerPCCPU *cpu,
    502                                       SpaprMachineState *spapr,
    503                                       target_ulong opcode, target_ulong *args)
    504{
    505    target_ulong reg = args[0];
    506    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    507    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    508
    509    if (!dev) {
    510        return H_PARAMETER;
    511    }
    512
    513    if (!dev->isopen) {
    514        hcall_dprintf("H_FREE_LOGICAL_LAN called without "
    515                      "H_REGISTER_LOGICAL_LAN\n");
    516        return H_RESOURCE;
    517    }
    518
    519    spapr_vlan_reset(sdev);
    520    return H_SUCCESS;
    521}
    522
    523/**
    524 * Used for qsort, this function compares two RxBufPools by size.
    525 */
    526static int rx_pool_size_compare(const void *p1, const void *p2)
    527{
    528    const RxBufPool *pool1 = *(RxBufPool **)p1;
    529    const RxBufPool *pool2 = *(RxBufPool **)p2;
    530
    531    if (pool1->bufsize < pool2->bufsize) {
    532        return -1;
    533    }
    534    return pool1->bufsize > pool2->bufsize;
    535}
    536
    537/**
    538 * Search for a matching buffer pool with exact matching size,
    539 * or return -1 if no matching pool has been found.
    540 */
    541static int spapr_vlan_get_rx_pool_id(SpaprVioVlan *dev, int size)
    542{
    543    int pool;
    544
    545    for (pool = 0; pool < RX_MAX_POOLS; pool++) {
    546        if (dev->rx_pool[pool]->bufsize == size) {
    547            return pool;
    548        }
    549    }
    550
    551    return -1;
    552}
    553
    554/**
    555 * Enqueuing receive buffer by adding it to one of our receive buffer pools
    556 */
    557static target_long spapr_vlan_add_rxbuf_to_pool(SpaprVioVlan *dev,
    558                                                target_ulong buf)
    559{
    560    int size = VLAN_BD_LEN(buf);
    561    int pool;
    562
    563    pool = spapr_vlan_get_rx_pool_id(dev, size);
    564    if (pool < 0) {
    565        /*
    566         * No matching pool found? Try to use a new one. If the guest used all
    567         * pools before, but changed the size of one pool in the meantime, we might
    568         * need to recycle that pool here (if it's empty already). Thus scan
    569         * all buffer pools now, starting with the last (likely empty) one.
    570         */
    571        for (pool = RX_MAX_POOLS - 1; pool >= 0 ; pool--) {
    572            if (dev->rx_pool[pool]->count == 0) {
    573                dev->rx_pool[pool]->bufsize = size;
    574                /*
    575                 * Sort pools by size so that spapr_vlan_receive()
    576                 * can later find the smallest buffer pool easily.
    577                 */
    578                qsort(dev->rx_pool, RX_MAX_POOLS, sizeof(dev->rx_pool[0]),
    579                      rx_pool_size_compare);
    580                pool = spapr_vlan_get_rx_pool_id(dev, size);
    581                trace_spapr_vlan_add_rxbuf_to_pool_create(pool,
    582                                                          VLAN_BD_LEN(buf));
    583                break;
    584            }
    585        }
    586    }
    587    /* Still no usable pool? Give up */
    588    if (pool < 0 || dev->rx_pool[pool]->count >= RX_POOL_MAX_BDS) {
    589        return H_RESOURCE;
    590    }
    591
    592    trace_spapr_vlan_add_rxbuf_to_pool(pool, VLAN_BD_LEN(buf),
    593                                       dev->rx_pool[pool]->count);
    594
    595    dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count++] = buf;
    596
    597    return 0;
    598}
    599
    600/**
    601 * This is the old way of enqueuing receive buffers: Add it to the rx queue
    602 * page that has been supplied by the guest (which is quite limited in size).
    603 */
    604static target_long spapr_vlan_add_rxbuf_to_page(SpaprVioVlan *dev,
    605                                                target_ulong buf)
    606{
    607    vlan_bd_t bd;
    608
    609    if (dev->rx_bufs >= VLAN_MAX_BUFS) {
    610        return H_RESOURCE;
    611    }
    612
    613    do {
    614        dev->add_buf_ptr += 8;
    615        if (dev->add_buf_ptr >= VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF) {
    616            dev->add_buf_ptr = VLAN_RX_BDS_OFF;
    617        }
    618
    619        bd = vio_ldq(&dev->sdev, dev->buf_list + dev->add_buf_ptr);
    620    } while (bd & VLAN_BD_VALID);
    621
    622    vio_stq(&dev->sdev, dev->buf_list + dev->add_buf_ptr, buf);
    623
    624    trace_spapr_vlan_add_rxbuf_to_page(dev->add_buf_ptr, dev->rx_bufs, buf);
    625
    626    return 0;
    627}
    628
    629static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
    630                                             SpaprMachineState *spapr,
    631                                             target_ulong opcode,
    632                                             target_ulong *args)
    633{
    634    target_ulong reg = args[0];
    635    target_ulong buf = args[1];
    636    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    637    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    638    target_long ret;
    639
    640    trace_spapr_vlan_h_add_logical_lan_buffer(reg, buf);
    641
    642    if (!sdev) {
    643        hcall_dprintf("Bad device\n");
    644        return H_PARAMETER;
    645    }
    646
    647    if ((check_bd(dev, buf, 4) < 0)
    648        || (VLAN_BD_LEN(buf) < 16)) {
    649        hcall_dprintf("Bad buffer enqueued\n");
    650        return H_PARAMETER;
    651    }
    652
    653    if (!dev->isopen) {
    654        return H_RESOURCE;
    655    }
    656
    657    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
    658        ret = spapr_vlan_add_rxbuf_to_pool(dev, buf);
    659    } else {
    660        ret = spapr_vlan_add_rxbuf_to_page(dev, buf);
    661    }
    662    if (ret) {
    663        return ret;
    664    }
    665
    666    dev->rx_bufs++;
    667
    668    /*
    669     * Give guest some more time to add additional RX buffers before we
    670     * flush the receive queue, so that e.g. fragmented IP packets can
    671     * be passed to the guest in one go later (instead of passing single
    672     * fragments if there is only one receive buffer available).
    673     */
    674    timer_mod(dev->rxp_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500);
    675
    676    return H_SUCCESS;
    677}
    678
    679static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
    680                                       SpaprMachineState *spapr,
    681                                       target_ulong opcode, target_ulong *args)
    682{
    683    target_ulong reg = args[0];
    684    target_ulong *bufs = args + 1;
    685    target_ulong continue_token = args[7];
    686    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    687    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    688    unsigned total_len;
    689    uint8_t *p;
    690    g_autofree uint8_t *lbuf = NULL;
    691    int i, nbufs;
    692    int ret;
    693
    694    trace_spapr_vlan_h_send_logical_lan(reg, continue_token);
    695
    696    if (!sdev) {
    697        return H_PARAMETER;
    698    }
    699
    700    trace_spapr_vlan_h_send_logical_lan_rxbufs(dev->rx_bufs);
    701
    702    if (!dev->isopen) {
    703        return H_DROPPED;
    704    }
    705
    706    if (continue_token) {
    707        return H_HARDWARE; /* FIXME actually handle this */
    708    }
    709
    710    total_len = 0;
    711    for (i = 0; i < 6; i++) {
    712        trace_spapr_vlan_h_send_logical_lan_buf_desc(bufs[i]);
    713        if (!(bufs[i] & VLAN_BD_VALID)) {
    714            break;
    715        }
    716        total_len += VLAN_BD_LEN(bufs[i]);
    717    }
    718
    719    nbufs = i;
    720    trace_spapr_vlan_h_send_logical_lan_total(nbufs, total_len);
    721
    722    if (total_len == 0) {
    723        return H_SUCCESS;
    724    }
    725
    726    if (total_len > MAX_PACKET_SIZE) {
    727        /* Don't let the guest force too large an allocation */
    728        return H_RESOURCE;
    729    }
    730
    731    lbuf = g_malloc(total_len);
    732    p = lbuf;
    733    for (i = 0; i < nbufs; i++) {
    734        ret = spapr_vio_dma_read(sdev, VLAN_BD_ADDR(bufs[i]),
    735                                 p, VLAN_BD_LEN(bufs[i]));
    736        if (ret < 0) {
    737            return ret;
    738        }
    739
    740        p += VLAN_BD_LEN(bufs[i]);
    741    }
    742
    743    qemu_send_packet(qemu_get_queue(dev->nic), lbuf, total_len);
    744
    745    return H_SUCCESS;
    746}
    747
    748static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, SpaprMachineState *spapr,
    749                                     target_ulong opcode, target_ulong *args)
    750{
    751    target_ulong reg = args[0];
    752    SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    753
    754    if (!dev) {
    755        return H_PARAMETER;
    756    }
    757
    758    return H_SUCCESS;
    759}
    760
    761static target_ulong h_change_logical_lan_mac(PowerPCCPU *cpu,
    762                                             SpaprMachineState *spapr,
    763                                             target_ulong opcode,
    764                                             target_ulong *args)
    765{
    766    target_ulong reg = args[0];
    767    target_ulong macaddr = args[1];
    768    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    769    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    770    int i;
    771
    772    for (i = 0; i < ETH_ALEN; i++) {
    773        dev->nicconf.macaddr.a[ETH_ALEN - i - 1] = macaddr & 0xff;
    774        macaddr >>= 8;
    775    }
    776
    777    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
    778
    779    return H_SUCCESS;
    780}
    781
    782static Property spapr_vlan_properties[] = {
    783    DEFINE_SPAPR_PROPERTIES(SpaprVioVlan, sdev),
    784    DEFINE_NIC_PROPERTIES(SpaprVioVlan, nicconf),
    785    DEFINE_PROP_BIT("use-rx-buffer-pools", SpaprVioVlan,
    786                    compat_flags, SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT, true),
    787    DEFINE_PROP_END_OF_LIST(),
    788};
    789
    790static bool spapr_vlan_rx_buffer_pools_needed(void *opaque)
    791{
    792    SpaprVioVlan *dev = opaque;
    793
    794    return (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) != 0;
    795}
    796
    797static const VMStateDescription vmstate_rx_buffer_pool = {
    798    .name = "spapr_llan/rx_buffer_pool",
    799    .version_id = 1,
    800    .minimum_version_id = 1,
    801    .needed = spapr_vlan_rx_buffer_pools_needed,
    802    .fields = (VMStateField[]) {
    803        VMSTATE_INT32(bufsize, RxBufPool),
    804        VMSTATE_INT32(count, RxBufPool),
    805        VMSTATE_UINT64_ARRAY(bds, RxBufPool, RX_POOL_MAX_BDS),
    806        VMSTATE_END_OF_LIST()
    807    }
    808};
    809
    810static const VMStateDescription vmstate_rx_pools = {
    811    .name = "spapr_llan/rx_pools",
    812    .version_id = 1,
    813    .minimum_version_id = 1,
    814    .needed = spapr_vlan_rx_buffer_pools_needed,
    815    .fields = (VMStateField[]) {
    816        VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(rx_pool, SpaprVioVlan,
    817                                           RX_MAX_POOLS, 1,
    818                                           vmstate_rx_buffer_pool, RxBufPool),
    819        VMSTATE_END_OF_LIST()
    820    }
    821};
    822
    823static const VMStateDescription vmstate_spapr_llan = {
    824    .name = "spapr_llan",
    825    .version_id = 1,
    826    .minimum_version_id = 1,
    827    .fields = (VMStateField[]) {
    828        VMSTATE_SPAPR_VIO(sdev, SpaprVioVlan),
    829        /* LLAN state */
    830        VMSTATE_BOOL(isopen, SpaprVioVlan),
    831        VMSTATE_UINT64(buf_list, SpaprVioVlan),
    832        VMSTATE_UINT32(add_buf_ptr, SpaprVioVlan),
    833        VMSTATE_UINT32(use_buf_ptr, SpaprVioVlan),
    834        VMSTATE_UINT32(rx_bufs, SpaprVioVlan),
    835        VMSTATE_UINT64(rxq_ptr, SpaprVioVlan),
    836
    837        VMSTATE_END_OF_LIST()
    838    },
    839    .subsections = (const VMStateDescription * []) {
    840        &vmstate_rx_pools,
    841        NULL
    842    }
    843};
    844
    845static void spapr_vlan_class_init(ObjectClass *klass, void *data)
    846{
    847    DeviceClass *dc = DEVICE_CLASS(klass);
    848    SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
    849
    850    k->realize = spapr_vlan_realize;
    851    k->reset = spapr_vlan_reset;
    852    k->devnode = spapr_vlan_devnode;
    853    k->dt_name = "l-lan";
    854    k->dt_type = "network";
    855    k->dt_compatible = "IBM,l-lan";
    856    k->signal_mask = 0x1;
    857    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
    858    device_class_set_props(dc, spapr_vlan_properties);
    859    k->rtce_window_size = 0x10000000;
    860    dc->vmsd = &vmstate_spapr_llan;
    861}
    862
    863static const TypeInfo spapr_vlan_info = {
    864    .name          = TYPE_VIO_SPAPR_VLAN_DEVICE,
    865    .parent        = TYPE_VIO_SPAPR_DEVICE,
    866    .instance_size = sizeof(SpaprVioVlan),
    867    .class_init    = spapr_vlan_class_init,
    868    .instance_init = spapr_vlan_instance_init,
    869    .instance_finalize = spapr_vlan_instance_finalize,
    870};
    871
    872static void spapr_vlan_register_types(void)
    873{
    874    spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
    875    spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
    876    spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
    877    spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
    878                             h_add_logical_lan_buffer);
    879    spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
    880    spapr_register_hypercall(H_CHANGE_LOGICAL_LAN_MAC,
    881                             h_change_logical_lan_mac);
    882    type_register_static(&spapr_vlan_info);
    883}
    884
    885type_init(spapr_vlan_register_types)