linux/arch/s390/pci/pci_clp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright IBM Corp. 2012
   4 *
   5 * Author(s):
   6 *   Jan Glauber <jang@linux.vnet.ibm.com>
   7 */
   8
   9#define KMSG_COMPONENT "zpci"
  10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  11
  12#include <linux/compat.h>
  13#include <linux/kernel.h>
  14#include <linux/miscdevice.h>
  15#include <linux/slab.h>
  16#include <linux/err.h>
  17#include <linux/delay.h>
  18#include <linux/pci.h>
  19#include <linux/uaccess.h>
  20#include <asm/pci_debug.h>
  21#include <asm/pci_clp.h>
  22#include <asm/clp.h>
  23#include <uapi/asm/clp.h>
  24
  25bool zpci_unique_uid;
  26
  27static void update_uid_checking(bool new)
  28{
  29        if (zpci_unique_uid != new)
  30                zpci_dbg(1, "uid checking:%d\n", new);
  31
  32        zpci_unique_uid = new;
  33}
  34
  35static inline void zpci_err_clp(unsigned int rsp, int rc)
  36{
  37        struct {
  38                unsigned int rsp;
  39                int rc;
  40        } __packed data = {rsp, rc};
  41
  42        zpci_err_hex(&data, sizeof(data));
  43}
  44
  45/*
  46 * Call Logical Processor with c=1, lps=0 and command 1
  47 * to get the bit mask of installed logical processors
  48 */
  49static inline int clp_get_ilp(unsigned long *ilp)
  50{
  51        unsigned long mask;
  52        int cc = 3;
  53
  54        asm volatile (
  55                "       .insn   rrf,0xb9a00000,%[mask],%[cmd],8,0\n"
  56                "0:     ipm     %[cc]\n"
  57                "       srl     %[cc],28\n"
  58                "1:\n"
  59                EX_TABLE(0b, 1b)
  60                : [cc] "+d" (cc), [mask] "=d" (mask) : [cmd] "a" (1)
  61                : "cc");
  62        *ilp = mask;
  63        return cc;
  64}
  65
  66/*
  67 * Call Logical Processor with c=0, the give constant lps and an lpcb request.
  68 */
  69static inline int clp_req(void *data, unsigned int lps)
  70{
  71        struct { u8 _[CLP_BLK_SIZE]; } *req = data;
  72        u64 ignored;
  73        int cc = 3;
  74
  75        asm volatile (
  76                "       .insn   rrf,0xb9a00000,%[ign],%[req],0,%[lps]\n"
  77                "0:     ipm     %[cc]\n"
  78                "       srl     %[cc],28\n"
  79                "1:\n"
  80                EX_TABLE(0b, 1b)
  81                : [cc] "+d" (cc), [ign] "=d" (ignored), "+m" (*req)
  82                : [req] "a" (req), [lps] "i" (lps)
  83                : "cc");
  84        return cc;
  85}
  86
  87static void *clp_alloc_block(gfp_t gfp_mask)
  88{
  89        return (void *) __get_free_pages(gfp_mask, get_order(CLP_BLK_SIZE));
  90}
  91
  92static void clp_free_block(void *ptr)
  93{
  94        free_pages((unsigned long) ptr, get_order(CLP_BLK_SIZE));
  95}
  96
  97static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
  98                                      struct clp_rsp_query_pci_grp *response)
  99{
 100        zdev->tlb_refresh = response->refresh;
 101        zdev->dma_mask = response->dasm;
 102        zdev->msi_addr = response->msia;
 103        zdev->max_msi = response->noi;
 104        zdev->fmb_update = response->mui;
 105
 106        switch (response->version) {
 107        case 1:
 108                zdev->max_bus_speed = PCIE_SPEED_5_0GT;
 109                break;
 110        default:
 111                zdev->max_bus_speed = PCI_SPEED_UNKNOWN;
 112                break;
 113        }
 114}
 115
 116static int clp_query_pci_fngrp(struct zpci_dev *zdev, u8 pfgid)
 117{
 118        struct clp_req_rsp_query_pci_grp *rrb;
 119        int rc;
 120
 121        rrb = clp_alloc_block(GFP_KERNEL);
 122        if (!rrb)
 123                return -ENOMEM;
 124
 125        memset(rrb, 0, sizeof(*rrb));
 126        rrb->request.hdr.len = sizeof(rrb->request);
 127        rrb->request.hdr.cmd = CLP_QUERY_PCI_FNGRP;
 128        rrb->response.hdr.len = sizeof(rrb->response);
 129        rrb->request.pfgid = pfgid;
 130
 131        rc = clp_req(rrb, CLP_LPS_PCI);
 132        if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
 133                clp_store_query_pci_fngrp(zdev, &rrb->response);
 134        else {
 135                zpci_err("Q PCI FGRP:\n");
 136                zpci_err_clp(rrb->response.hdr.rsp, rc);
 137                rc = -EIO;
 138        }
 139        clp_free_block(rrb);
 140        return rc;
 141}
 142
 143static int clp_store_query_pci_fn(struct zpci_dev *zdev,
 144                                  struct clp_rsp_query_pci *response)
 145{
 146        int i;
 147
 148        for (i = 0; i < PCI_BAR_COUNT; i++) {
 149                zdev->bars[i].val = le32_to_cpu(response->bar[i]);
 150                zdev->bars[i].size = response->bar_size[i];
 151        }
 152        zdev->start_dma = response->sdma;
 153        zdev->end_dma = response->edma;
 154        zdev->pchid = response->pchid;
 155        zdev->pfgid = response->pfgid;
 156        zdev->pft = response->pft;
 157        zdev->vfn = response->vfn;
 158        zdev->uid = response->uid;
 159        zdev->fmb_length = sizeof(u32) * response->fmb_len;
 160
 161        memcpy(zdev->pfip, response->pfip, sizeof(zdev->pfip));
 162        if (response->util_str_avail) {
 163                memcpy(zdev->util_str, response->util_str,
 164                       sizeof(zdev->util_str));
 165        }
 166        zdev->mio_capable = response->mio_addr_avail;
 167        for (i = 0; i < PCI_BAR_COUNT; i++) {
 168                if (!(response->mio.valid & (1 << (PCI_BAR_COUNT - i - 1))))
 169                        continue;
 170
 171                zdev->bars[i].mio_wb = (void __iomem *) response->mio.addr[i].wb;
 172                zdev->bars[i].mio_wt = (void __iomem *) response->mio.addr[i].wt;
 173        }
 174        return 0;
 175}
 176
 177static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh)
 178{
 179        struct clp_req_rsp_query_pci *rrb;
 180        int rc;
 181
 182        rrb = clp_alloc_block(GFP_KERNEL);
 183        if (!rrb)
 184                return -ENOMEM;
 185
 186        memset(rrb, 0, sizeof(*rrb));
 187        rrb->request.hdr.len = sizeof(rrb->request);
 188        rrb->request.hdr.cmd = CLP_QUERY_PCI_FN;
 189        rrb->response.hdr.len = sizeof(rrb->response);
 190        rrb->request.fh = fh;
 191
 192        rc = clp_req(rrb, CLP_LPS_PCI);
 193        if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
 194                rc = clp_store_query_pci_fn(zdev, &rrb->response);
 195                if (rc)
 196                        goto out;
 197                rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid);
 198        } else {
 199                zpci_err("Q PCI FN:\n");
 200                zpci_err_clp(rrb->response.hdr.rsp, rc);
 201                rc = -EIO;
 202        }
 203out:
 204        clp_free_block(rrb);
 205        return rc;
 206}
 207
 208int clp_add_pci_device(u32 fid, u32 fh, int configured)
 209{
 210        struct zpci_dev *zdev;
 211        int rc = -ENOMEM;
 212
 213        zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, configured);
 214        zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
 215        if (!zdev)
 216                goto error;
 217
 218        zdev->fh = fh;
 219        zdev->fid = fid;
 220
 221        /* Query function properties and update zdev */
 222        rc = clp_query_pci_fn(zdev, fh);
 223        if (rc)
 224                goto error;
 225
 226        if (configured)
 227                zdev->state = ZPCI_FN_STATE_CONFIGURED;
 228        else
 229                zdev->state = ZPCI_FN_STATE_STANDBY;
 230
 231        rc = zpci_create_device(zdev);
 232        if (rc)
 233                goto error;
 234        return 0;
 235
 236error:
 237        zpci_dbg(0, "add fid:%x, rc:%d\n", fid, rc);
 238        kfree(zdev);
 239        return rc;
 240}
 241
 242/*
 243 * Enable/Disable a given PCI function defined by its function handle.
 244 */
 245static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command)
 246{
 247        struct clp_req_rsp_set_pci *rrb;
 248        int rc, retries = 100;
 249
 250        rrb = clp_alloc_block(GFP_KERNEL);
 251        if (!rrb)
 252                return -ENOMEM;
 253
 254        do {
 255                memset(rrb, 0, sizeof(*rrb));
 256                rrb->request.hdr.len = sizeof(rrb->request);
 257                rrb->request.hdr.cmd = CLP_SET_PCI_FN;
 258                rrb->response.hdr.len = sizeof(rrb->response);
 259                rrb->request.fh = *fh;
 260                rrb->request.oc = command;
 261                rrb->request.ndas = nr_dma_as;
 262
 263                rc = clp_req(rrb, CLP_LPS_PCI);
 264                if (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY) {
 265                        retries--;
 266                        if (retries < 0)
 267                                break;
 268                        msleep(20);
 269                }
 270        } while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY);
 271
 272        if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
 273                *fh = rrb->response.fh;
 274        else {
 275                zpci_err("Set PCI FN:\n");
 276                zpci_err_clp(rrb->response.hdr.rsp, rc);
 277                rc = -EIO;
 278        }
 279        clp_free_block(rrb);
 280        return rc;
 281}
 282
 283int clp_enable_fh(struct zpci_dev *zdev, u8 nr_dma_as)
 284{
 285        u32 fh = zdev->fh;
 286        int rc;
 287
 288        rc = clp_set_pci_fn(&fh, nr_dma_as, CLP_SET_ENABLE_PCI_FN);
 289        zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc);
 290        if (rc)
 291                goto out;
 292
 293        zdev->fh = fh;
 294        if (zpci_use_mio(zdev)) {
 295                rc = clp_set_pci_fn(&fh, nr_dma_as, CLP_SET_ENABLE_MIO);
 296                zpci_dbg(3, "ena mio fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc);
 297                if (rc)
 298                        clp_disable_fh(zdev);
 299        }
 300out:
 301        return rc;
 302}
 303
 304int clp_disable_fh(struct zpci_dev *zdev)
 305{
 306        u32 fh = zdev->fh;
 307        int rc;
 308
 309        if (!zdev_enabled(zdev))
 310                return 0;
 311
 312        rc = clp_set_pci_fn(&fh, 0, CLP_SET_DISABLE_PCI_FN);
 313        zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc);
 314        if (!rc)
 315                zdev->fh = fh;
 316
 317        return rc;
 318}
 319
 320static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, void *data,
 321                        void (*cb)(struct clp_fh_list_entry *, void *))
 322{
 323        u64 resume_token = 0;
 324        int entries, i, rc;
 325
 326        do {
 327                memset(rrb, 0, sizeof(*rrb));
 328                rrb->request.hdr.len = sizeof(rrb->request);
 329                rrb->request.hdr.cmd = CLP_LIST_PCI;
 330                /* store as many entries as possible */
 331                rrb->response.hdr.len = CLP_BLK_SIZE - LIST_PCI_HDR_LEN;
 332                rrb->request.resume_token = resume_token;
 333
 334                /* Get PCI function handle list */
 335                rc = clp_req(rrb, CLP_LPS_PCI);
 336                if (rc || rrb->response.hdr.rsp != CLP_RC_OK) {
 337                        zpci_err("List PCI FN:\n");
 338                        zpci_err_clp(rrb->response.hdr.rsp, rc);
 339                        rc = -EIO;
 340                        goto out;
 341                }
 342
 343                update_uid_checking(rrb->response.uid_checking);
 344                WARN_ON_ONCE(rrb->response.entry_size !=
 345                        sizeof(struct clp_fh_list_entry));
 346
 347                entries = (rrb->response.hdr.len - LIST_PCI_HDR_LEN) /
 348                        rrb->response.entry_size;
 349
 350                resume_token = rrb->response.resume_token;
 351                for (i = 0; i < entries; i++)
 352                        cb(&rrb->response.fh_list[i], data);
 353        } while (resume_token);
 354out:
 355        return rc;
 356}
 357
 358static void __clp_add(struct clp_fh_list_entry *entry, void *data)
 359{
 360        struct zpci_dev *zdev;
 361
 362        if (!entry->vendor_id)
 363                return;
 364
 365        zdev = get_zdev_by_fid(entry->fid);
 366        if (!zdev)
 367                clp_add_pci_device(entry->fid, entry->fh, entry->config_state);
 368}
 369
 370static void __clp_update(struct clp_fh_list_entry *entry, void *data)
 371{
 372        struct zpci_dev *zdev;
 373
 374        if (!entry->vendor_id)
 375                return;
 376
 377        zdev = get_zdev_by_fid(entry->fid);
 378        if (!zdev)
 379                return;
 380
 381        zdev->fh = entry->fh;
 382}
 383
 384int clp_scan_pci_devices(void)
 385{
 386        struct clp_req_rsp_list_pci *rrb;
 387        int rc;
 388
 389        rrb = clp_alloc_block(GFP_KERNEL);
 390        if (!rrb)
 391                return -ENOMEM;
 392
 393        rc = clp_list_pci(rrb, NULL, __clp_add);
 394
 395        clp_free_block(rrb);
 396        return rc;
 397}
 398
 399int clp_rescan_pci_devices(void)
 400{
 401        struct clp_req_rsp_list_pci *rrb;
 402        int rc;
 403
 404        zpci_remove_reserved_devices();
 405
 406        rrb = clp_alloc_block(GFP_KERNEL);
 407        if (!rrb)
 408                return -ENOMEM;
 409
 410        rc = clp_list_pci(rrb, NULL, __clp_add);
 411
 412        clp_free_block(rrb);
 413        return rc;
 414}
 415
 416int clp_rescan_pci_devices_simple(void)
 417{
 418        struct clp_req_rsp_list_pci *rrb;
 419        int rc;
 420
 421        rrb = clp_alloc_block(GFP_NOWAIT);
 422        if (!rrb)
 423                return -ENOMEM;
 424
 425        rc = clp_list_pci(rrb, NULL, __clp_update);
 426
 427        clp_free_block(rrb);
 428        return rc;
 429}
 430
 431struct clp_state_data {
 432        u32 fid;
 433        enum zpci_state state;
 434};
 435
 436static void __clp_get_state(struct clp_fh_list_entry *entry, void *data)
 437{
 438        struct clp_state_data *sd = data;
 439
 440        if (entry->fid != sd->fid)
 441                return;
 442
 443        sd->state = entry->config_state;
 444}
 445
 446int clp_get_state(u32 fid, enum zpci_state *state)
 447{
 448        struct clp_req_rsp_list_pci *rrb;
 449        struct clp_state_data sd = {fid, ZPCI_FN_STATE_RESERVED};
 450        int rc;
 451
 452        rrb = clp_alloc_block(GFP_ATOMIC);
 453        if (!rrb)
 454                return -ENOMEM;
 455
 456        rc = clp_list_pci(rrb, &sd, __clp_get_state);
 457        if (!rc)
 458                *state = sd.state;
 459
 460        clp_free_block(rrb);
 461        return rc;
 462}
 463
 464static int clp_base_slpc(struct clp_req *req, struct clp_req_rsp_slpc *lpcb)
 465{
 466        unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
 467
 468        if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
 469            lpcb->response.hdr.len > limit)
 470                return -EINVAL;
 471        return clp_req(lpcb, CLP_LPS_BASE) ? -EOPNOTSUPP : 0;
 472}
 473
 474static int clp_base_command(struct clp_req *req, struct clp_req_hdr *lpcb)
 475{
 476        switch (lpcb->cmd) {
 477        case 0x0001: /* store logical-processor characteristics */
 478                return clp_base_slpc(req, (void *) lpcb);
 479        default:
 480                return -EINVAL;
 481        }
 482}
 483
 484static int clp_pci_slpc(struct clp_req *req, struct clp_req_rsp_slpc *lpcb)
 485{
 486        unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
 487
 488        if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
 489            lpcb->response.hdr.len > limit)
 490                return -EINVAL;
 491        return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
 492}
 493
 494static int clp_pci_list(struct clp_req *req, struct clp_req_rsp_list_pci *lpcb)
 495{
 496        unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
 497
 498        if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
 499            lpcb->response.hdr.len > limit)
 500                return -EINVAL;
 501        if (lpcb->request.reserved2 != 0)
 502                return -EINVAL;
 503        return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
 504}
 505
 506static int clp_pci_query(struct clp_req *req,
 507                         struct clp_req_rsp_query_pci *lpcb)
 508{
 509        unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
 510
 511        if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
 512            lpcb->response.hdr.len > limit)
 513                return -EINVAL;
 514        if (lpcb->request.reserved2 != 0 || lpcb->request.reserved3 != 0)
 515                return -EINVAL;
 516        return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
 517}
 518
 519static int clp_pci_query_grp(struct clp_req *req,
 520                             struct clp_req_rsp_query_pci_grp *lpcb)
 521{
 522        unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
 523
 524        if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
 525            lpcb->response.hdr.len > limit)
 526                return -EINVAL;
 527        if (lpcb->request.reserved2 != 0 || lpcb->request.reserved3 != 0 ||
 528            lpcb->request.reserved4 != 0)
 529                return -EINVAL;
 530        return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
 531}
 532
 533static int clp_pci_command(struct clp_req *req, struct clp_req_hdr *lpcb)
 534{
 535        switch (lpcb->cmd) {
 536        case 0x0001: /* store logical-processor characteristics */
 537                return clp_pci_slpc(req, (void *) lpcb);
 538        case 0x0002: /* list PCI functions */
 539                return clp_pci_list(req, (void *) lpcb);
 540        case 0x0003: /* query PCI function */
 541                return clp_pci_query(req, (void *) lpcb);
 542        case 0x0004: /* query PCI function group */
 543                return clp_pci_query_grp(req, (void *) lpcb);
 544        default:
 545                return -EINVAL;
 546        }
 547}
 548
 549static int clp_normal_command(struct clp_req *req)
 550{
 551        struct clp_req_hdr *lpcb;
 552        void __user *uptr;
 553        int rc;
 554
 555        rc = -EINVAL;
 556        if (req->lps != 0 && req->lps != 2)
 557                goto out;
 558
 559        rc = -ENOMEM;
 560        lpcb = clp_alloc_block(GFP_KERNEL);
 561        if (!lpcb)
 562                goto out;
 563
 564        rc = -EFAULT;
 565        uptr = (void __force __user *)(unsigned long) req->data_p;
 566        if (copy_from_user(lpcb, uptr, PAGE_SIZE) != 0)
 567                goto out_free;
 568
 569        rc = -EINVAL;
 570        if (lpcb->fmt != 0 || lpcb->reserved1 != 0 || lpcb->reserved2 != 0)
 571                goto out_free;
 572
 573        switch (req->lps) {
 574        case 0:
 575                rc = clp_base_command(req, lpcb);
 576                break;
 577        case 2:
 578                rc = clp_pci_command(req, lpcb);
 579                break;
 580        }
 581        if (rc)
 582                goto out_free;
 583
 584        rc = -EFAULT;
 585        if (copy_to_user(uptr, lpcb, PAGE_SIZE) != 0)
 586                goto out_free;
 587
 588        rc = 0;
 589
 590out_free:
 591        clp_free_block(lpcb);
 592out:
 593        return rc;
 594}
 595
 596static int clp_immediate_command(struct clp_req *req)
 597{
 598        void __user *uptr;
 599        unsigned long ilp;
 600        int exists;
 601
 602        if (req->cmd > 1 || clp_get_ilp(&ilp) != 0)
 603                return -EINVAL;
 604
 605        uptr = (void __force __user *)(unsigned long) req->data_p;
 606        if (req->cmd == 0) {
 607                /* Command code 0: test for a specific processor */
 608                exists = test_bit_inv(req->lps, &ilp);
 609                return put_user(exists, (int __user *) uptr);
 610        }
 611        /* Command code 1: return bit mask of installed processors */
 612        return put_user(ilp, (unsigned long __user *) uptr);
 613}
 614
 615static long clp_misc_ioctl(struct file *filp, unsigned int cmd,
 616                           unsigned long arg)
 617{
 618        struct clp_req req;
 619        void __user *argp;
 620
 621        if (cmd != CLP_SYNC)
 622                return -EINVAL;
 623
 624        argp = is_compat_task() ? compat_ptr(arg) : (void __user *) arg;
 625        if (copy_from_user(&req, argp, sizeof(req)))
 626                return -EFAULT;
 627        if (req.r != 0)
 628                return -EINVAL;
 629        return req.c ? clp_immediate_command(&req) : clp_normal_command(&req);
 630}
 631
 632static int clp_misc_release(struct inode *inode, struct file *filp)
 633{
 634        return 0;
 635}
 636
 637static const struct file_operations clp_misc_fops = {
 638        .owner = THIS_MODULE,
 639        .open = nonseekable_open,
 640        .release = clp_misc_release,
 641        .unlocked_ioctl = clp_misc_ioctl,
 642        .compat_ioctl = clp_misc_ioctl,
 643        .llseek = no_llseek,
 644};
 645
 646static struct miscdevice clp_misc_device = {
 647        .minor = MISC_DYNAMIC_MINOR,
 648        .name = "clp",
 649        .fops = &clp_misc_fops,
 650};
 651
 652static int __init clp_misc_init(void)
 653{
 654        return misc_register(&clp_misc_device);
 655}
 656
 657device_initcall(clp_misc_init);
 658