linux/arch/x86/kvm/i8259.c
<<
>>
Prefs
   1/*
   2 * 8259 interrupt controller emulation
   3 *
   4 * Copyright (c) 2003-2004 Fabrice Bellard
   5 * Copyright (c) 2007 Intel Corporation
   6 * Copyright 2009 Red Hat, Inc. and/or its affiliates.
   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 * Authors:
  26 *   Yaozu (Eddie) Dong <Eddie.dong@intel.com>
  27 *   Port from Qemu.
  28 */
  29#include <linux/mm.h>
  30#include <linux/slab.h>
  31#include <linux/bitops.h>
  32#include "irq.h"
  33
  34#include <linux/kvm_host.h>
  35#include "trace.h"
  36
  37#define pr_pic_unimpl(fmt, ...) \
  38        pr_err_ratelimited("kvm: pic: " fmt, ## __VA_ARGS__)
  39
  40static void pic_irq_request(struct kvm *kvm, int level);
  41
  42static void pic_lock(struct kvm_pic *s)
  43        __acquires(&s->lock)
  44{
  45        spin_lock(&s->lock);
  46}
  47
  48static void pic_unlock(struct kvm_pic *s)
  49        __releases(&s->lock)
  50{
  51        bool wakeup = s->wakeup_needed;
  52        struct kvm_vcpu *vcpu, *found = NULL;
  53        int i;
  54
  55        s->wakeup_needed = false;
  56
  57        spin_unlock(&s->lock);
  58
  59        if (wakeup) {
  60                kvm_for_each_vcpu(i, vcpu, s->kvm) {
  61                        if (kvm_apic_accept_pic_intr(vcpu)) {
  62                                found = vcpu;
  63                                break;
  64                        }
  65                }
  66
  67                if (!found)
  68                        return;
  69
  70                kvm_make_request(KVM_REQ_EVENT, found);
  71                kvm_vcpu_kick(found);
  72        }
  73}
  74
  75static void pic_clear_isr(struct kvm_kpic_state *s, int irq)
  76{
  77        s->isr &= ~(1 << irq);
  78        if (s != &s->pics_state->pics[0])
  79                irq += 8;
  80        /*
  81         * We are dropping lock while calling ack notifiers since ack
  82         * notifier callbacks for assigned devices call into PIC recursively.
  83         * Other interrupt may be delivered to PIC while lock is dropped but
  84         * it should be safe since PIC state is already updated at this stage.
  85         */
  86        pic_unlock(s->pics_state);
  87        kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq);
  88        pic_lock(s->pics_state);
  89}
  90
  91/*
  92 * set irq level. If an edge is detected, then the IRR is set to 1
  93 */
  94static inline int pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
  95{
  96        int mask, ret = 1;
  97        mask = 1 << irq;
  98        if (s->elcr & mask)     /* level triggered */
  99                if (level) {
 100                        ret = !(s->irr & mask);
 101                        s->irr |= mask;
 102                        s->last_irr |= mask;
 103                } else {
 104                        s->irr &= ~mask;
 105                        s->last_irr &= ~mask;
 106                }
 107        else    /* edge triggered */
 108                if (level) {
 109                        if ((s->last_irr & mask) == 0) {
 110                                ret = !(s->irr & mask);
 111                                s->irr |= mask;
 112                        }
 113                        s->last_irr |= mask;
 114                } else
 115                        s->last_irr &= ~mask;
 116
 117        return (s->imr & mask) ? -1 : ret;
 118}
 119
 120/*
 121 * return the highest priority found in mask (highest = smallest
 122 * number). Return 8 if no irq
 123 */
 124static inline int get_priority(struct kvm_kpic_state *s, int mask)
 125{
 126        int priority;
 127        if (mask == 0)
 128                return 8;
 129        priority = 0;
 130        while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
 131                priority++;
 132        return priority;
 133}
 134
 135/*
 136 * return the pic wanted interrupt. return -1 if none
 137 */
 138static int pic_get_irq(struct kvm_kpic_state *s)
 139{
 140        int mask, cur_priority, priority;
 141
 142        mask = s->irr & ~s->imr;
 143        priority = get_priority(s, mask);
 144        if (priority == 8)
 145                return -1;
 146        /*
 147         * compute current priority. If special fully nested mode on the
 148         * master, the IRQ coming from the slave is not taken into account
 149         * for the priority computation.
 150         */
 151        mask = s->isr;
 152        if (s->special_fully_nested_mode && s == &s->pics_state->pics[0])
 153                mask &= ~(1 << 2);
 154        cur_priority = get_priority(s, mask);
 155        if (priority < cur_priority)
 156                /*
 157                 * higher priority found: an irq should be generated
 158                 */
 159                return (priority + s->priority_add) & 7;
 160        else
 161                return -1;
 162}
 163
 164/*
 165 * raise irq to CPU if necessary. must be called every time the active
 166 * irq may change
 167 */
 168static void pic_update_irq(struct kvm_pic *s)
 169{
 170        int irq2, irq;
 171
 172        irq2 = pic_get_irq(&s->pics[1]);
 173        if (irq2 >= 0) {
 174                /*
 175                 * if irq request by slave pic, signal master PIC
 176                 */
 177                pic_set_irq1(&s->pics[0], 2, 1);
 178                pic_set_irq1(&s->pics[0], 2, 0);
 179        }
 180        irq = pic_get_irq(&s->pics[0]);
 181        pic_irq_request(s->kvm, irq >= 0);
 182}
 183
 184void kvm_pic_update_irq(struct kvm_pic *s)
 185{
 186        pic_lock(s);
 187        pic_update_irq(s);
 188        pic_unlock(s);
 189}
 190
 191int kvm_pic_set_irq(void *opaque, int irq, int level)
 192{
 193        struct kvm_pic *s = opaque;
 194        int ret = -1;
 195
 196        pic_lock(s);
 197        if (irq >= 0 && irq < PIC_NUM_PINS) {
 198                ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
 199                pic_update_irq(s);
 200                trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr,
 201                                      s->pics[irq >> 3].imr, ret == 0);
 202        }
 203        pic_unlock(s);
 204
 205        return ret;
 206}
 207
 208/*
 209 * acknowledge interrupt 'irq'
 210 */
 211static inline void pic_intack(struct kvm_kpic_state *s, int irq)
 212{
 213        s->isr |= 1 << irq;
 214        /*
 215         * We don't clear a level sensitive interrupt here
 216         */
 217        if (!(s->elcr & (1 << irq)))
 218                s->irr &= ~(1 << irq);
 219
 220        if (s->auto_eoi) {
 221                if (s->rotate_on_auto_eoi)
 222                        s->priority_add = (irq + 1) & 7;
 223                pic_clear_isr(s, irq);
 224        }
 225
 226}
 227
 228int kvm_pic_read_irq(struct kvm *kvm)
 229{
 230        int irq, irq2, intno;
 231        struct kvm_pic *s = pic_irqchip(kvm);
 232
 233        pic_lock(s);
 234        irq = pic_get_irq(&s->pics[0]);
 235        if (irq >= 0) {
 236                pic_intack(&s->pics[0], irq);
 237                if (irq == 2) {
 238                        irq2 = pic_get_irq(&s->pics[1]);
 239                        if (irq2 >= 0)
 240                                pic_intack(&s->pics[1], irq2);
 241                        else
 242                                /*
 243                                 * spurious IRQ on slave controller
 244                                 */
 245                                irq2 = 7;
 246                        intno = s->pics[1].irq_base + irq2;
 247                        irq = irq2 + 8;
 248                } else
 249                        intno = s->pics[0].irq_base + irq;
 250        } else {
 251                /*
 252                 * spurious IRQ on host controller
 253                 */
 254                irq = 7;
 255                intno = s->pics[0].irq_base + irq;
 256        }
 257        pic_update_irq(s);
 258        pic_unlock(s);
 259
 260        return intno;
 261}
 262
 263void kvm_pic_reset(struct kvm_kpic_state *s)
 264{
 265        int irq, i;
 266        struct kvm_vcpu *vcpu;
 267        u8 irr = s->irr, isr = s->imr;
 268        bool found = false;
 269
 270        s->last_irr = 0;
 271        s->irr = 0;
 272        s->imr = 0;
 273        s->isr = 0;
 274        s->priority_add = 0;
 275        s->irq_base = 0;
 276        s->read_reg_select = 0;
 277        s->poll = 0;
 278        s->special_mask = 0;
 279        s->init_state = 0;
 280        s->auto_eoi = 0;
 281        s->rotate_on_auto_eoi = 0;
 282        s->special_fully_nested_mode = 0;
 283        s->init4 = 0;
 284
 285        kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm)
 286                if (kvm_apic_accept_pic_intr(vcpu)) {
 287                        found = true;
 288                        break;
 289                }
 290
 291
 292        if (!found)
 293                return;
 294
 295        for (irq = 0; irq < PIC_NUM_PINS/2; irq++)
 296                if (irr & (1 << irq) || isr & (1 << irq))
 297                        pic_clear_isr(s, irq);
 298}
 299
 300static void pic_ioport_write(void *opaque, u32 addr, u32 val)
 301{
 302        struct kvm_kpic_state *s = opaque;
 303        int priority, cmd, irq;
 304
 305        addr &= 1;
 306        if (addr == 0) {
 307                if (val & 0x10) {
 308                        s->init4 = val & 1;
 309                        s->last_irr = 0;
 310                        s->imr = 0;
 311                        s->priority_add = 0;
 312                        s->special_mask = 0;
 313                        s->read_reg_select = 0;
 314                        if (!s->init4) {
 315                                s->special_fully_nested_mode = 0;
 316                                s->auto_eoi = 0;
 317                        }
 318                        s->init_state = 1;
 319                        if (val & 0x02)
 320                                pr_pic_unimpl("single mode not supported");
 321                        if (val & 0x08)
 322                                pr_pic_unimpl(
 323                                        "level sensitive irq not supported");
 324                } else if (val & 0x08) {
 325                        if (val & 0x04)
 326                                s->poll = 1;
 327                        if (val & 0x02)
 328                                s->read_reg_select = val & 1;
 329                        if (val & 0x40)
 330                                s->special_mask = (val >> 5) & 1;
 331                } else {
 332                        cmd = val >> 5;
 333                        switch (cmd) {
 334                        case 0:
 335                        case 4:
 336                                s->rotate_on_auto_eoi = cmd >> 2;
 337                                break;
 338                        case 1: /* end of interrupt */
 339                        case 5:
 340                                priority = get_priority(s, s->isr);
 341                                if (priority != 8) {
 342                                        irq = (priority + s->priority_add) & 7;
 343                                        if (cmd == 5)
 344                                                s->priority_add = (irq + 1) & 7;
 345                                        pic_clear_isr(s, irq);
 346                                        pic_update_irq(s->pics_state);
 347                                }
 348                                break;
 349                        case 3:
 350                                irq = val & 7;
 351                                pic_clear_isr(s, irq);
 352                                pic_update_irq(s->pics_state);
 353                                break;
 354                        case 6:
 355                                s->priority_add = (val + 1) & 7;
 356                                pic_update_irq(s->pics_state);
 357                                break;
 358                        case 7:
 359                                irq = val & 7;
 360                                s->priority_add = (irq + 1) & 7;
 361                                pic_clear_isr(s, irq);
 362                                pic_update_irq(s->pics_state);
 363                                break;
 364                        default:
 365                                break;  /* no operation */
 366                        }
 367                }
 368        } else
 369                switch (s->init_state) {
 370                case 0: { /* normal mode */
 371                        u8 imr_diff = s->imr ^ val,
 372                                off = (s == &s->pics_state->pics[0]) ? 0 : 8;
 373                        s->imr = val;
 374                        for (irq = 0; irq < PIC_NUM_PINS/2; irq++)
 375                                if (imr_diff & (1 << irq))
 376                                        kvm_fire_mask_notifiers(
 377                                                s->pics_state->kvm,
 378                                                SELECT_PIC(irq + off),
 379                                                irq + off,
 380                                                !!(s->imr & (1 << irq)));
 381                        pic_update_irq(s->pics_state);
 382                        break;
 383                }
 384                case 1:
 385                        s->irq_base = val & 0xf8;
 386                        s->init_state = 2;
 387                        break;
 388                case 2:
 389                        if (s->init4)
 390                                s->init_state = 3;
 391                        else
 392                                s->init_state = 0;
 393                        break;
 394                case 3:
 395                        s->special_fully_nested_mode = (val >> 4) & 1;
 396                        s->auto_eoi = (val >> 1) & 1;
 397                        s->init_state = 0;
 398                        break;
 399                }
 400}
 401
 402static u32 pic_poll_read(struct kvm_kpic_state *s, u32 addr1)
 403{
 404        int ret;
 405
 406        ret = pic_get_irq(s);
 407        if (ret >= 0) {
 408                if (addr1 >> 7) {
 409                        s->pics_state->pics[0].isr &= ~(1 << 2);
 410                        s->pics_state->pics[0].irr &= ~(1 << 2);
 411                }
 412                s->irr &= ~(1 << ret);
 413                pic_clear_isr(s, ret);
 414                if (addr1 >> 7 || ret != 2)
 415                        pic_update_irq(s->pics_state);
 416        } else {
 417                ret = 0x07;
 418                pic_update_irq(s->pics_state);
 419        }
 420
 421        return ret;
 422}
 423
 424static u32 pic_ioport_read(void *opaque, u32 addr1)
 425{
 426        struct kvm_kpic_state *s = opaque;
 427        unsigned int addr;
 428        int ret;
 429
 430        addr = addr1;
 431        addr &= 1;
 432        if (s->poll) {
 433                ret = pic_poll_read(s, addr1);
 434                s->poll = 0;
 435        } else
 436                if (addr == 0)
 437                        if (s->read_reg_select)
 438                                ret = s->isr;
 439                        else
 440                                ret = s->irr;
 441                else
 442                        ret = s->imr;
 443        return ret;
 444}
 445
 446static void elcr_ioport_write(void *opaque, u32 addr, u32 val)
 447{
 448        struct kvm_kpic_state *s = opaque;
 449        s->elcr = val & s->elcr_mask;
 450}
 451
 452static u32 elcr_ioport_read(void *opaque, u32 addr1)
 453{
 454        struct kvm_kpic_state *s = opaque;
 455        return s->elcr;
 456}
 457
 458static int picdev_in_range(gpa_t addr)
 459{
 460        switch (addr) {
 461        case 0x20:
 462        case 0x21:
 463        case 0xa0:
 464        case 0xa1:
 465        case 0x4d0:
 466        case 0x4d1:
 467                return 1;
 468        default:
 469                return 0;
 470        }
 471}
 472
 473static int picdev_write(struct kvm_pic *s,
 474                         gpa_t addr, int len, const void *val)
 475{
 476        unsigned char data = *(unsigned char *)val;
 477        if (!picdev_in_range(addr))
 478                return -EOPNOTSUPP;
 479
 480        if (len != 1) {
 481                pr_pic_unimpl("non byte write\n");
 482                return 0;
 483        }
 484        pic_lock(s);
 485        switch (addr) {
 486        case 0x20:
 487        case 0x21:
 488        case 0xa0:
 489        case 0xa1:
 490                pic_ioport_write(&s->pics[addr >> 7], addr, data);
 491                break;
 492        case 0x4d0:
 493        case 0x4d1:
 494                elcr_ioport_write(&s->pics[addr & 1], addr, data);
 495                break;
 496        }
 497        pic_unlock(s);
 498        return 0;
 499}
 500
 501static int picdev_read(struct kvm_pic *s,
 502                       gpa_t addr, int len, void *val)
 503{
 504        unsigned char data = 0;
 505        if (!picdev_in_range(addr))
 506                return -EOPNOTSUPP;
 507
 508        if (len != 1) {
 509                pr_pic_unimpl("non byte read\n");
 510                return 0;
 511        }
 512        pic_lock(s);
 513        switch (addr) {
 514        case 0x20:
 515        case 0x21:
 516        case 0xa0:
 517        case 0xa1:
 518                data = pic_ioport_read(&s->pics[addr >> 7], addr);
 519                break;
 520        case 0x4d0:
 521        case 0x4d1:
 522                data = elcr_ioport_read(&s->pics[addr & 1], addr);
 523                break;
 524        }
 525        *(unsigned char *)val = data;
 526        pic_unlock(s);
 527        return 0;
 528}
 529
 530static int picdev_master_write(struct kvm_io_device *dev,
 531                               gpa_t addr, int len, const void *val)
 532{
 533        return picdev_write(container_of(dev, struct kvm_pic, dev_master),
 534                            addr, len, val);
 535}
 536
 537static int picdev_master_read(struct kvm_io_device *dev,
 538                              gpa_t addr, int len, void *val)
 539{
 540        return picdev_read(container_of(dev, struct kvm_pic, dev_master),
 541                            addr, len, val);
 542}
 543
 544static int picdev_slave_write(struct kvm_io_device *dev,
 545                              gpa_t addr, int len, const void *val)
 546{
 547        return picdev_write(container_of(dev, struct kvm_pic, dev_slave),
 548                            addr, len, val);
 549}
 550
 551static int picdev_slave_read(struct kvm_io_device *dev,
 552                             gpa_t addr, int len, void *val)
 553{
 554        return picdev_read(container_of(dev, struct kvm_pic, dev_slave),
 555                            addr, len, val);
 556}
 557
 558static int picdev_eclr_write(struct kvm_io_device *dev,
 559                             gpa_t addr, int len, const void *val)
 560{
 561        return picdev_write(container_of(dev, struct kvm_pic, dev_eclr),
 562                            addr, len, val);
 563}
 564
 565static int picdev_eclr_read(struct kvm_io_device *dev,
 566                            gpa_t addr, int len, void *val)
 567{
 568        return picdev_read(container_of(dev, struct kvm_pic, dev_eclr),
 569                            addr, len, val);
 570}
 571
 572/*
 573 * callback when PIC0 irq status changed
 574 */
 575static void pic_irq_request(struct kvm *kvm, int level)
 576{
 577        struct kvm_pic *s = pic_irqchip(kvm);
 578
 579        if (!s->output)
 580                s->wakeup_needed = true;
 581        s->output = level;
 582}
 583
 584static const struct kvm_io_device_ops picdev_master_ops = {
 585        .read     = picdev_master_read,
 586        .write    = picdev_master_write,
 587};
 588
 589static const struct kvm_io_device_ops picdev_slave_ops = {
 590        .read     = picdev_slave_read,
 591        .write    = picdev_slave_write,
 592};
 593
 594static const struct kvm_io_device_ops picdev_eclr_ops = {
 595        .read     = picdev_eclr_read,
 596        .write    = picdev_eclr_write,
 597};
 598
 599struct kvm_pic *kvm_create_pic(struct kvm *kvm)
 600{
 601        struct kvm_pic *s;
 602        int ret;
 603
 604        s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
 605        if (!s)
 606                return NULL;
 607        spin_lock_init(&s->lock);
 608        s->kvm = kvm;
 609        s->pics[0].elcr_mask = 0xf8;
 610        s->pics[1].elcr_mask = 0xde;
 611        s->pics[0].pics_state = s;
 612        s->pics[1].pics_state = s;
 613
 614        /*
 615         * Initialize PIO device
 616         */
 617        kvm_iodevice_init(&s->dev_master, &picdev_master_ops);
 618        kvm_iodevice_init(&s->dev_slave, &picdev_slave_ops);
 619        kvm_iodevice_init(&s->dev_eclr, &picdev_eclr_ops);
 620        mutex_lock(&kvm->slots_lock);
 621        ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0x20, 2,
 622                                      &s->dev_master);
 623        if (ret < 0)
 624                goto fail_unlock;
 625
 626        ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0xa0, 2, &s->dev_slave);
 627        if (ret < 0)
 628                goto fail_unreg_2;
 629
 630        ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0x4d0, 2, &s->dev_eclr);
 631        if (ret < 0)
 632                goto fail_unreg_1;
 633
 634        mutex_unlock(&kvm->slots_lock);
 635
 636        return s;
 637
 638fail_unreg_1:
 639        kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &s->dev_slave);
 640
 641fail_unreg_2:
 642        kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &s->dev_master);
 643
 644fail_unlock:
 645        mutex_unlock(&kvm->slots_lock);
 646
 647        kfree(s);
 648
 649        return NULL;
 650}
 651
 652void kvm_destroy_pic(struct kvm *kvm)
 653{
 654        struct kvm_pic *vpic = kvm->arch.vpic;
 655
 656        if (vpic) {
 657                kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &vpic->dev_master);
 658                kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &vpic->dev_slave);
 659                kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &vpic->dev_eclr);
 660                kvm->arch.vpic = NULL;
 661                kfree(vpic);
 662        }
 663}
 664
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.