免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2951 | 回复: 11
打印 上一主题 下一主题

bug in kvm lapic 2.6.30 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-28 13:09 |只看该作者 |倒序浏览

  1. /* 2.6.30
  2. * x86/kvm/lapic.c
  3. */

  4. static void apic_send_ipi(struct kvm_lapic *apic)
  5. {
  6.         u32 icr_low = apic_get_reg(apic, APIC_ICR);
  7.         u32 icr_high = apic_get_reg(apic, APIC_ICR2);

  8.         unsigned int dest = GET_APIC_DEST_FIELD(icr_high);

  9.         unsigned int short_hand                = icr_low & APIC_SHORT_MASK;
  10.         unsigned int trig_mode                = icr_low & APIC_INT_LEVELTRIG;
  11.         unsigned int level                        = icr_low & APIC_INT_ASSERT;
  12.         unsigned int dest_mode                = icr_low & APIC_DEST_MASK;
  13.         unsigned int delivery_mode        = icr_low & APIC_MODE_MASK;
  14.         unsigned int vector                        = icr_low & APIC_VECTOR_MASK;

  15.         struct kvm_vcpu *target;
  16.         struct kvm_vcpu *vcpu;
  17.         unsigned long lpr_map = 0;
  18.         int i;

  19.         apic_debug("icr_high 0x%x, icr_low 0x%x, "
  20.                    "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
  21.                    "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n",
  22.                    icr_high, icr_low, short_hand, dest,
  23.                    trig_mode, level, dest_mode, delivery_mode, vector);

  24.         for (i = 0; i < KVM_MAX_VCPUS; i++) {
  25.                 vcpu = apic->vcpu->kvm->vcpus[i];
  26.                 if (!vcpu)
  27.                         continue;

  28.                 if (vcpu->arch.apic &&
  29.                     apic_match_dest(vcpu, apic, short_hand, dest, dest_mode)) {
  30.                         if (delivery_mode == APIC_DM_LOWEST)
  31.                                 set_bit(vcpu->vcpu_id, &lpr_map);
  32.                         else
  33.                                 __apic_accept_irq(vcpu->arch.apic, delivery_mode,
  34.                                                                   vector, level, trig_mode);
  35.                 }
  36.         }

  37.         if (delivery_mode == APIC_DM_LOWEST) {
  38. -                target = kvm_get_lowest_prio_vcpu(vcpu->kvm, vector, lpr_map);
  39. +                target = kvm_get_lowest_prio_vcpu(apic->vcpu->kvm, vector, lpr_map);
  40.                 if (target != NULL)
  41.                         __apic_accept_irq(target->arch.apic, delivery_mode,
  42.                                                           vector, level, trig_mode);
  43.         }
  44. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2009-06-28 13:33 |只看该作者
not a bug

  1. static u32 apic_get_tmcct(struct kvm_lapic *apic)
  2. {
  3.         ktime_t remaining;
  4.         s64 ns;
  5.         u32 tmcct; //cct cycle count

  6.         ASSERT(apic != NULL);

  7.         /* if initial count is 0, current count should also be 0 */
  8.         if (apic_get_reg(apic, APIC_TMICT) == 0)
  9.                 return 0;

  10.         remaining = hrtimer_expires_remaining(&apic->timer.dev);
  11.         if (ktime_to_ns(remaining) < 0)
  12. -                remaining = ktime_set(0, 0);
  13. +                return 0;

  14.         ns = mod_64(ktime_to_ns(remaining), apic->timer.period);

  15.         tmcct = div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
  16.         return tmcct;
  17. }
复制代码

论坛徽章:
0
3 [报告]
发表于 2009-06-28 13:47 |只看该作者
and patch it

  1. static u32 apic_get_tmcct(struct kvm_lapic *apic)
  2. {
  3.         ktime_t remaining;
  4.         s64 ns;
  5.         u32 tmcct; //cct cycle count

  6.         ASSERT(apic != NULL);

  7.         /* if initial count is 0, current count should also be 0 */
  8.         if (apic_get_reg(apic, APIC_TMICT) == 0)
  9.                 return 0;

  10.         remaining = hrtimer_expires_remaining(&apic->timer.dev);
  11. -        if (ktime_to_ns(remaining) < 0)
  12. -                remaining = ktime_set(0, 0);
  13. -
  14. -        ns = mod_64(ktime_to_ns(remaining), apic->timer.period);
  15. +        ns = ktime_to_ns(remaining);
  16. +        if (ns < 0)
  17. +                return 0;
  18. +        ns = mod_64(ns, apic->timer.period);

  19.         tmcct = div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
  20.         return tmcct;
  21. }
复制代码

[ 本帖最后由 rtable 于 2009-7-2 22:03 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-07-02 20:33 |只看该作者
patch

  1. unsigned long segment_base(u16 selector)
  2. {
  3.         struct descriptor_table gdt;
  4.         struct desc_struct *d;
  5.         unsigned long table_base;
  6.         unsigned long v;

  7.         if (selector == 0)
  8.                 return 0;

  9. -        asm("sgdt %0" : "=m"(gdt));
  10. -        table_base = gdt.base;
  11. -
  12.         if (selector & 4) { /* from ldt */
  13.                 u16 ldt_selector;

  14.                 asm("sldt %0" : "=g"(ldt_selector));
  15.                 table_base = segment_base(ldt_selector);
  16.         }
  17. +        else {
  18. +                asm("sgdt %0" : "=m"(gdt));
  19. +                table_base = gdt.base;
  20. +        }
  21.         d = (struct desc_struct *)(table_base + (selector & ~7));
  22.         v = d->base0 | ((unsigned long)d->base1 << 16) |
  23.                 ((unsigned long)d->base2 << 24);
  24. #ifdef CONFIG_X86_64
  25.         if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
  26.                 v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
  27. #endif
  28.         return v;
  29. }
  30. EXPORT_SYMBOL_GPL(segment_base);

  31. u64 kvm_get_apic_base(struct kvm_vcpu *vcpu)
  32. {
  33. -        if (irqchip_in_kernel(vcpu->kvm))
  34. -                return vcpu->arch.apic_base;
  35. -        else
  36.                 return vcpu->arch.apic_base;
  37. }
  38. EXPORT_SYMBOL_GPL(kvm_get_apic_base);

复制代码

[ 本帖最后由 rtable 于 2009-7-2 20:39 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-07-02 20:55 |只看该作者
patch

  1. /*
  2. * Load the pae pdptrs.  Return true is they are all valid.
  3. */
  4. int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
  5. {
  6.         gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT;
  7.         unsigned offset = ((cr3 & (PAGE_SIZE-1)) >> 5) << 2;
  8.         int i;
  9.         int ret;
  10.         u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];

  11.         ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn,
  12.                                                                 pdpte, offset * sizeof(u64), sizeof(pdpte));
  13.         if (ret < 0) {
  14.                 ret = 0;
  15.                 goto out;
  16.         }
  17. -        for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
  18. -                //since logic err, del the for loop
  19. -                if ((pdpte[i] & 1) && (pdpte[i] & 0xfffffff0000001e6ull)) {
  20. -                        ret = 0;
  21. -                        goto out;
  22. -                }
  23. -        }
  24.         ret = 1;

  25.         memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
  26. out:
  27.         return ret;
  28. }
  29. EXPORT_SYMBOL_GPL(load_pdptrs);
复制代码

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
6 [报告]
发表于 2009-07-02 23:26 |只看该作者
LZ描述一下BUG

论坛徽章:
0
7 [报告]
发表于 2009-07-05 18:37 |只看该作者
concern

  1. void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr, u32 error_code)
  2. {
  3.         ++vcpu->stat.pf_guest;

  4.         if (vcpu->arch.exception.pending) {
  5.                 if (vcpu->arch.exception.nr == PF_VECTOR) {
  6.                         printk(KERN_DEBUG "kvm: inject_page_fault: double fault 0x%lx\n", addr);
  7.                         vcpu->arch.exception.nr = DF_VECTOR;
  8.                         vcpu->arch.exception.error_code = 0;
  9.                 }
  10.                 else if (vcpu->arch.exception.nr == DF_VECTOR) {
  11.                         /* triple fault -> shutdown */
  12.                         set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
  13.                 }
  14. +                /* else
  15. +                        current fault lost,
  16. +                        is deferred until pending processed?
  17. +                */
  18.                 return;
  19.         }
  20.         vcpu->arch.cr2 = addr;
  21.         kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
  22. }

复制代码

论坛徽章:
0
8 [报告]
发表于 2009-07-06 14:52 |只看该作者
就是,拿文字描述下BUG,再贴下PATCH

论坛徽章:
0
9 [报告]
发表于 2009-07-13 09:43 |只看该作者
patch

  1. u32 kvm_ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest,
  2.                                                                     u8 dest_mode)
  3. {
  4.         u32 mask = 0;
  5.         int i;
  6.         struct kvm *kvm = ioapic->kvm;
  7.         struct kvm_vcpu *vcpu;

  8.         ioapic_debug("dest %d dest_mode %d\n", dest, dest_mode);

  9.         if (dest_mode == 0) {        /* Physical mode. */
  10.                 if (dest == 0xFF) {        /* Broadcast. */
  11.                         for (i = 0; i < KVM_MAX_VCPUS; ++i)
  12.                                 if (kvm->vcpus[i] && kvm->vcpus[i]->arch.apic)
  13.                                         mask |= 1 << i;
  14.                         return mask;
  15.                 }
  16.                 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
  17.                         vcpu = kvm->vcpus[i];
  18. -                        if (!vcpu)
  19. -                                continue;
  20. -                        if (kvm_apic_match_physical_addr(vcpu->arch.apic, dest)) {
  21. -                                if (vcpu->arch.apic)
  22. -                                        mask = 1 << i;
  23. -                                break;
  24. -                        }
  25. +                        if (vcpu && vcpu->arch.apic &&
  26. +                                kvm_apic_match_physical_addr(vcpu->arch.apic, dest)) {
  27. +                                mask = 1 << i;
  28. +                                break;
  29. +                        }
  30.                 }
  31.         }
  32.         else if (dest != 0)        /* Logical mode, MDA non-zero. */
  33.                 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
  34.                         vcpu = kvm->vcpus[i];
  35. -                        if (!vcpu)
  36. -                                continue;
  37. -                        if (vcpu->arch.apic &&
  38. +                        if (vcpu && vcpu->arch.apic &&
  39.                             kvm_apic_match_logical_addr(vcpu->arch.apic, dest))
  40.                                 mask |= 1 << vcpu->vcpu_id;
  41.                 }

  42.         ioapic_debug("mask %x\n", mask);
  43.         return mask;
  44. }
复制代码

论坛徽章:
0
10 [报告]
发表于 2009-07-13 11:04 |只看该作者
原帖由 rtable 于 2009-7-13 09:43 发表
patch
u32 kvm_ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest,
                                                                    u8 dest_mode)
{
        u32 mask = 0;
        int i;
        struct kvm *kvm = ioapic->kvm;
        struct kvm_vcpu *vcpu;

...

这么改,不遍历剩下的VCPU 就break了,这不是会有问题吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP