~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to arch/x86/kvm/lapic.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <asm/page.h>
34
34
#include <asm/current.h>
35
35
#include <asm/apicdef.h>
36
 
#include <asm/atomic.h>
 
36
#include <linux/atomic.h>
37
37
#include "kvm_cache_regs.h"
38
38
#include "irq.h"
39
39
#include "trace.h"
68
68
#define VEC_POS(v) ((v) & (32 - 1))
69
69
#define REG_POS(v) (((v) >> 5) << 4)
70
70
 
 
71
static unsigned int min_timer_period_us = 500;
 
72
module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR);
 
73
 
71
74
static inline u32 apic_get_reg(struct kvm_lapic *apic, int reg_off)
72
75
{
73
76
        return *((u32 *) (apic->regs + reg_off));
135
138
        return apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK;
136
139
}
137
140
 
 
141
static inline int apic_lvtt_oneshot(struct kvm_lapic *apic)
 
142
{
 
143
        return ((apic_get_reg(apic, APIC_LVTT) &
 
144
                apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_ONESHOT);
 
145
}
 
146
 
138
147
static inline int apic_lvtt_period(struct kvm_lapic *apic)
139
148
{
140
 
        return apic_get_reg(apic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC;
 
149
        return ((apic_get_reg(apic, APIC_LVTT) &
 
150
                apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_PERIODIC);
 
151
}
 
152
 
 
153
static inline int apic_lvtt_tscdeadline(struct kvm_lapic *apic)
 
154
{
 
155
        return ((apic_get_reg(apic, APIC_LVTT) &
 
156
                apic->lapic_timer.timer_mode_mask) ==
 
157
                        APIC_LVT_TIMER_TSCDEADLINE);
141
158
}
142
159
 
143
160
static inline int apic_lvt_nmi_mode(u32 lvt_val)
166
183
}
167
184
 
168
185
static unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
169
 
        LVT_MASK | APIC_LVT_TIMER_PERIODIC,     /* LVTT */
 
186
        LVT_MASK ,      /* part LVTT mask, timer mode mask added at runtime */
170
187
        LVT_MASK | APIC_MODE_MASK,      /* LVTTHMR */
171
188
        LVT_MASK | APIC_MODE_MASK,      /* LVTPC */
172
189
        LINT_MASK, LINT_MASK,   /* LVT0-1 */
316
333
                        result = 1;
317
334
                break;
318
335
        default:
319
 
                printk(KERN_WARNING "Bad DFR vcpu %d: %08x\n",
320
 
                       apic->vcpu->vcpu_id, apic_get_reg(apic, APIC_DFR));
 
336
                apic_debug("Bad DFR vcpu %d: %08x\n",
 
337
                           apic->vcpu->vcpu_id, apic_get_reg(apic, APIC_DFR));
321
338
                break;
322
339
        }
323
340
 
354
371
                result = (target != source);
355
372
                break;
356
373
        default:
357
 
                printk(KERN_WARNING "Bad dest shorthand value %x\n",
358
 
                       short_hand);
 
374
                apic_debug("kvm: apic: Bad dest shorthand value %x\n",
 
375
                           short_hand);
359
376
                break;
360
377
        }
361
378
 
401
418
                break;
402
419
 
403
420
        case APIC_DM_REMRD:
404
 
                printk(KERN_DEBUG "Ignoring delivery mode 3\n");
 
421
                apic_debug("Ignoring delivery mode 3\n");
405
422
                break;
406
423
 
407
424
        case APIC_DM_SMI:
408
 
                printk(KERN_DEBUG "Ignoring guest SMI\n");
 
425
                apic_debug("Ignoring guest SMI\n");
409
426
                break;
410
427
 
411
428
        case APIC_DM_NMI:
565
582
                        val = kvm_apic_id(apic) << 24;
566
583
                break;
567
584
        case APIC_ARBPRI:
568
 
                printk(KERN_WARNING "Access APIC ARBPRI register "
569
 
                       "which is for P6\n");
 
585
                apic_debug("Access APIC ARBPRI register which is for P6\n");
570
586
                break;
571
587
 
572
588
        case APIC_TMCCT:        /* Timer CCR */
 
589
                if (apic_lvtt_tscdeadline(apic))
 
590
                        return 0;
 
591
 
573
592
                val = apic_get_tmcct(apic);
574
593
                break;
575
594
 
664
683
 
665
684
static void start_apic_timer(struct kvm_lapic *apic)
666
685
{
667
 
        ktime_t now = apic->lapic_timer.timer.base->get_time();
668
 
 
669
 
        apic->lapic_timer.period = (u64)apic_get_reg(apic, APIC_TMICT) *
670
 
                    APIC_BUS_CYCLE_NS * apic->divide_count;
 
686
        ktime_t now;
671
687
        atomic_set(&apic->lapic_timer.pending, 0);
672
688
 
673
 
        if (!apic->lapic_timer.period)
674
 
                return;
675
 
        /*
676
 
         * Do not allow the guest to program periodic timers with small
677
 
         * interval, since the hrtimers are not throttled by the host
678
 
         * scheduler.
679
 
         */
680
 
        if (apic_lvtt_period(apic)) {
681
 
                if (apic->lapic_timer.period < NSEC_PER_MSEC/2)
682
 
                        apic->lapic_timer.period = NSEC_PER_MSEC/2;
683
 
        }
684
 
 
685
 
        hrtimer_start(&apic->lapic_timer.timer,
686
 
                      ktime_add_ns(now, apic->lapic_timer.period),
687
 
                      HRTIMER_MODE_ABS);
688
 
 
689
 
        apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016"
 
689
        if (apic_lvtt_period(apic) || apic_lvtt_oneshot(apic)) {
 
690
                /* lapic timer in oneshot or peroidic mode */
 
691
                now = apic->lapic_timer.timer.base->get_time();
 
692
                apic->lapic_timer.period = (u64)apic_get_reg(apic, APIC_TMICT)
 
693
                            * APIC_BUS_CYCLE_NS * apic->divide_count;
 
694
 
 
695
                if (!apic->lapic_timer.period)
 
696
                        return;
 
697
                /*
 
698
                 * Do not allow the guest to program periodic timers with small
 
699
                 * interval, since the hrtimers are not throttled by the host
 
700
                 * scheduler.
 
701
                 */
 
702
                if (apic_lvtt_period(apic)) {
 
703
                        s64 min_period = min_timer_period_us * 1000LL;
 
704
 
 
705
                        if (apic->lapic_timer.period < min_period) {
 
706
                                pr_info_ratelimited(
 
707
                                    "kvm: vcpu %i: requested %lld ns "
 
708
                                    "lapic timer period limited to %lld ns\n",
 
709
                                    apic->vcpu->vcpu_id,
 
710
                                    apic->lapic_timer.period, min_period);
 
711
                                apic->lapic_timer.period = min_period;
 
712
                        }
 
713
                }
 
714
 
 
715
                hrtimer_start(&apic->lapic_timer.timer,
 
716
                              ktime_add_ns(now, apic->lapic_timer.period),
 
717
                              HRTIMER_MODE_ABS);
 
718
 
 
719
                apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016"
690
720
                           PRIx64 ", "
691
721
                           "timer initial count 0x%x, period %lldns, "
692
722
                           "expire @ 0x%016" PRIx64 ".\n", __func__,
695
725
                           apic->lapic_timer.period,
696
726
                           ktime_to_ns(ktime_add_ns(now,
697
727
                                        apic->lapic_timer.period)));
 
728
        } else if (apic_lvtt_tscdeadline(apic)) {
 
729
                /* lapic timer in tsc deadline mode */
 
730
                u64 guest_tsc, tscdeadline = apic->lapic_timer.tscdeadline;
 
731
                u64 ns = 0;
 
732
                struct kvm_vcpu *vcpu = apic->vcpu;
 
733
                unsigned long this_tsc_khz = vcpu_tsc_khz(vcpu);
 
734
                unsigned long flags;
 
735
 
 
736
                if (unlikely(!tscdeadline || !this_tsc_khz))
 
737
                        return;
 
738
 
 
739
                local_irq_save(flags);
 
740
 
 
741
                now = apic->lapic_timer.timer.base->get_time();
 
742
                guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu);
 
743
                if (likely(tscdeadline > guest_tsc)) {
 
744
                        ns = (tscdeadline - guest_tsc) * 1000000ULL;
 
745
                        do_div(ns, this_tsc_khz);
 
746
                }
 
747
                hrtimer_start(&apic->lapic_timer.timer,
 
748
                        ktime_add_ns(now, ns), HRTIMER_MODE_ABS);
 
749
 
 
750
                local_irq_restore(flags);
 
751
        }
698
752
}
699
753
 
700
754
static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
782
836
 
783
837
        case APIC_LVT0:
784
838
                apic_manage_nmi_watchdog(apic, val);
785
 
        case APIC_LVTT:
786
839
        case APIC_LVTTHMR:
787
840
        case APIC_LVTPC:
788
841
        case APIC_LVT1:
796
849
 
797
850
                break;
798
851
 
 
852
        case APIC_LVTT:
 
853
                if ((apic_get_reg(apic, APIC_LVTT) &
 
854
                    apic->lapic_timer.timer_mode_mask) !=
 
855
                   (val & apic->lapic_timer.timer_mode_mask))
 
856
                        hrtimer_cancel(&apic->lapic_timer.timer);
 
857
 
 
858
                if (!apic_sw_enabled(apic))
 
859
                        val |= APIC_LVT_MASKED;
 
860
                val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask);
 
861
                apic_set_reg(apic, APIC_LVTT, val);
 
862
                break;
 
863
 
799
864
        case APIC_TMICT:
 
865
                if (apic_lvtt_tscdeadline(apic))
 
866
                        break;
 
867
 
800
868
                hrtimer_cancel(&apic->lapic_timer.timer);
801
869
                apic_set_reg(apic, APIC_TMICT, val);
802
870
                start_apic_timer(apic);
804
872
 
805
873
        case APIC_TDCR:
806
874
                if (val & 4)
807
 
                        printk(KERN_ERR "KVM_WRITE:TDCR %x\n", val);
 
875
                        apic_debug("KVM_WRITE:TDCR %x\n", val);
808
876
                apic_set_reg(apic, APIC_TDCR, val);
809
877
                update_divide_count(apic);
810
878
                break;
811
879
 
812
880
        case APIC_ESR:
813
881
                if (apic_x2apic_mode(apic) && val != 0) {
814
 
                        printk(KERN_ERR "KVM_WRITE:ESR not zero %x\n", val);
 
882
                        apic_debug("KVM_WRITE:ESR not zero %x\n", val);
815
883
                        ret = 1;
816
884
                }
817
885
                break;
864
932
        return 0;
865
933
}
866
934
 
 
935
void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu)
 
936
{
 
937
        struct kvm_lapic *apic = vcpu->arch.apic;
 
938
 
 
939
        if (apic)
 
940
                apic_reg_write(vcpu->arch.apic, APIC_EOI, 0);
 
941
}
 
942
EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
 
943
 
867
944
void kvm_free_lapic(struct kvm_vcpu *vcpu)
868
945
{
869
946
        if (!vcpu->arch.apic)
883
960
 *----------------------------------------------------------------------
884
961
 */
885
962
 
 
963
u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu)
 
964
{
 
965
        struct kvm_lapic *apic = vcpu->arch.apic;
 
966
        if (!apic)
 
967
                return 0;
 
968
 
 
969
        if (apic_lvtt_oneshot(apic) || apic_lvtt_period(apic))
 
970
                return 0;
 
971
 
 
972
        return apic->lapic_timer.tscdeadline;
 
973
}
 
974
 
 
975
void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data)
 
976
{
 
977
        struct kvm_lapic *apic = vcpu->arch.apic;
 
978
        if (!apic)
 
979
                return;
 
980
 
 
981
        if (apic_lvtt_oneshot(apic) || apic_lvtt_period(apic))
 
982
                return;
 
983
 
 
984
        hrtimer_cancel(&apic->lapic_timer.timer);
 
985
        apic->lapic_timer.tscdeadline = data;
 
986
        start_apic_timer(apic);
 
987
}
 
988
 
886
989
void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
887
990
{
888
991
        struct kvm_lapic *apic = vcpu->arch.apic;