Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1247257 > unrolled thread
| Started by | David Matlack <dmatlack@google.com> |
|---|---|
| First post | 2015-10-15 01:50 +0200 |
| Last post | 2015-10-16 03:50 +0200 |
| Articles | 5 — 3 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH v9 17/18] KVM: Update Posted-Interrupts Descriptor when vCPU is blocked David Matlack <dmatlack@google.com> - 2015-10-15 01:50 +0200
RE: [PATCH v9 17/18] KVM: Update Posted-Interrupts Descriptor when vCPU is blocked "Wu, Feng" <feng.wu@intel.com> - 2015-10-15 03:40 +0200
Re: [PATCH v9 17/18] KVM: Update Posted-Interrupts Descriptor when vCPU is blocked David Matlack <dmatlack@google.com> - 2015-10-15 19:40 +0200
Re: [PATCH v9 17/18] KVM: Update Posted-Interrupts Descriptor when vCPU is blocked Paolo Bonzini <pbonzini@redhat.com> - 2015-10-15 20:20 +0200
RE: [PATCH v9 17/18] KVM: Update Posted-Interrupts Descriptor when vCPU is blocked "Wu, Feng" <feng.wu@intel.com> - 2015-10-16 03:50 +0200
| From | David Matlack <dmatlack@google.com> |
|---|---|
| Date | 2015-10-15 01:50 +0200 |
| Subject | Re: [PATCH v9 17/18] KVM: Update Posted-Interrupts Descriptor when vCPU is blocked |
| Message-ID | <qjDXX-5He-3@gated-at.bofh.it> |
Hi Feng.
On Fri, Sep 18, 2015 at 7:29 AM, Feng Wu <feng.wu@intel.com> wrote:
> This patch updates the Posted-Interrupts Descriptor when vCPU
> is blocked.
>
> pre-block:
> - Add the vCPU to the blocked per-CPU list
> - Set 'NV' to POSTED_INTR_WAKEUP_VECTOR
>
> post-block:
> - Remove the vCPU from the per-CPU list
I'm wondering what happens if a posted interrupt arrives at the IOMMU
after pre-block and before post-block.
In pre_block, NV is set to POSTED_INTR_WAKEUP_VECTOR. IIUC, this means
future posted interrupts will not trigger "Posted-Interrupt Processing"
(PIR will not get copied to VIRR). Instead, the IOMMU will do ON := 1,
PIR |= (1 << vector), and send POSTED_INTR_WAKEUP_VECTOR. PIWV calls
wakeup_handler which does kvm_vcpu_kick. kvm_vcpu_kick does a wait-queue
wakeup and possibly a scheduler ipi.
But the VCPU is sitting in kvm_vcpu_block. It spins and/or schedules
(wait queue) until it has a reason to wake up. I couldn't find a code
path from kvm_vcpu_block that lead to checking ON or PIR. How does the
blocked VCPU "receive" the posted interrupt? (And when does Posted-
Interrupt Processing get triggered?)
Thanks!
>
> Signed-off-by: Feng Wu <feng.wu@intel.com>
> ---
> v9:
> - Add description for blocked_vcpu_on_cpu_lock in Documentation/virtual/kvm/locking.txt
> - Check !kvm_arch_has_assigned_device(vcpu->kvm) first, then
> !irq_remapping_cap(IRQ_POSTING_CAP)
>
> v8:
> - Rename 'pi_pre_block' to 'pre_block'
> - Rename 'pi_post_block' to 'post_block'
> - Change some comments
> - Only add the vCPU to the blocking list when the VM has assigned devices.
>
> Documentation/virtual/kvm/locking.txt | 12 +++
> arch/x86/include/asm/kvm_host.h | 13 +++
> arch/x86/kvm/vmx.c | 153 ++++++++++++++++++++++++++++++++++
> arch/x86/kvm/x86.c | 53 +++++++++---
> include/linux/kvm_host.h | 3 +
> virt/kvm/kvm_main.c | 3 +
> 6 files changed, 227 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/virtual/kvm/locking.txt b/Documentation/virtual/kvm/locking.txt
> index d68af4d..19f94a6 100644
> --- a/Documentation/virtual/kvm/locking.txt
> +++ b/Documentation/virtual/kvm/locking.txt
> @@ -166,3 +166,15 @@ Comment: The srcu read lock must be held while accessing memslots (e.g.
> MMIO/PIO address->device structure mapping (kvm->buses).
> The srcu index can be stored in kvm_vcpu->srcu_idx per vcpu
> if it is needed by multiple functions.
> +
> +Name: blocked_vcpu_on_cpu_lock
> +Type: spinlock_t
> +Arch: x86
> +Protects: blocked_vcpu_on_cpu
> +Comment: This is a per-CPU lock and it is used for VT-d posted-interrupts.
> + When VT-d posted-interrupts is supported and the VM has assigned
> + devices, we put the blocked vCPU on the list blocked_vcpu_on_cpu
> + protected by blocked_vcpu_on_cpu_lock, when VT-d hardware issues
> + wakeup notification event since external interrupts from the
> + assigned devices happens, we will find the vCPU on the list to
> + wakeup.
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 0ddd353..304fbb5 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -552,6 +552,8 @@ struct kvm_vcpu_arch {
> */
> bool write_fault_to_shadow_pgtable;
>
> + bool halted;
> +
> /* set at EPT violation at this point */
> unsigned long exit_qualification;
>
> @@ -864,6 +866,17 @@ struct kvm_x86_ops {
> /* pmu operations of sub-arch */
> const struct kvm_pmu_ops *pmu_ops;
>
> + /*
> + * Architecture specific hooks for vCPU blocking due to
> + * HLT instruction.
> + * Returns for .pre_block():
> + * - 0 means continue to block the vCPU.
> + * - 1 means we cannot block the vCPU since some event
> + * happens during this period, such as, 'ON' bit in
> + * posted-interrupts descriptor is set.
> + */
> + int (*pre_block)(struct kvm_vcpu *vcpu);
> + void (*post_block)(struct kvm_vcpu *vcpu);
> int (*update_pi_irte)(struct kvm *kvm, unsigned int host_irq,
> uint32_t guest_irq, bool set);
> };
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 902a67d..9968896 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -879,6 +879,13 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
> static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu);
> static DEFINE_PER_CPU(struct desc_ptr, host_gdt);
>
> +/*
> + * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we
> + * can find which vCPU should be waken up.
> + */
> +static DEFINE_PER_CPU(struct list_head, blocked_vcpu_on_cpu);
> +static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock);
> +
> static unsigned long *vmx_io_bitmap_a;
> static unsigned long *vmx_io_bitmap_b;
> static unsigned long *vmx_msr_bitmap_legacy;
> @@ -2985,6 +2992,8 @@ static int hardware_enable(void)
> return -EBUSY;
>
> INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu));
> + INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu));
> + spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
>
> /*
> * Now we can enable the vmclear operation in kdump
> @@ -6121,6 +6130,25 @@ static void update_ple_window_actual_max(void)
> ple_window_grow, INT_MIN);
> }
>
> +/*
> + * Handler for POSTED_INTERRUPT_WAKEUP_VECTOR.
> + */
> +static void wakeup_handler(void)
> +{
> + struct kvm_vcpu *vcpu;
> + int cpu = smp_processor_id();
> +
> + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
> + list_for_each_entry(vcpu, &per_cpu(blocked_vcpu_on_cpu, cpu),
> + blocked_vcpu_list) {
> + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
> +
> + if (pi_test_on(pi_desc) == 1)
> + kvm_vcpu_kick(vcpu);
> + }
> + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
> +}
> +
> static __init int hardware_setup(void)
> {
> int r = -ENOMEM, i, msr;
> @@ -6305,6 +6333,8 @@ static __init int hardware_setup(void)
> kvm_x86_ops->enable_log_dirty_pt_masked = NULL;
> }
>
> + kvm_set_posted_intr_wakeup_handler(wakeup_handler);
> +
> return alloc_kvm_area();
>
> out8:
> @@ -10430,6 +10460,126 @@ static void vmx_enable_log_dirty_pt_masked(struct kvm *kvm,
> }
>
> /*
> + * This routine does the following things for vCPU which is going
> + * to be blocked if VT-d PI is enabled.
> + * - Store the vCPU to the wakeup list, so when interrupts happen
> + * we can find the right vCPU to wake up.
> + * - Change the Posted-interrupt descriptor as below:
> + * 'NDST' <-- vcpu->pre_pcpu
> + * 'NV' <-- POSTED_INTR_WAKEUP_VECTOR
> + * - If 'ON' is set during this process, which means at least one
> + * interrupt is posted for this vCPU, we cannot block it, in
> + * this case, return 1, otherwise, return 0.
> + *
> + */
> +static int vmx_pre_block(struct kvm_vcpu *vcpu)
> +{
> + unsigned long flags;
> + unsigned int dest;
> + struct pi_desc old, new;
> + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
> +
> + if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
> + !irq_remapping_cap(IRQ_POSTING_CAP))
> + return 0;
> +
> + vcpu->pre_pcpu = vcpu->cpu;
> + spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock,
> + vcpu->pre_pcpu), flags);
> + list_add_tail(&vcpu->blocked_vcpu_list,
> + &per_cpu(blocked_vcpu_on_cpu,
> + vcpu->pre_pcpu));
> + spin_unlock_irqrestore(&per_cpu(blocked_vcpu_on_cpu_lock,
> + vcpu->pre_pcpu), flags);
> +
> + do {
> + old.control = new.control = pi_desc->control;
> +
> + /*
> + * We should not block the vCPU if
> + * an interrupt is posted for it.
> + */
> + if (pi_test_on(pi_desc) == 1) {
> + spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock,
> + vcpu->pre_pcpu), flags);
> + list_del(&vcpu->blocked_vcpu_list);
> + spin_unlock_irqrestore(
> + &per_cpu(blocked_vcpu_on_cpu_lock,
> + vcpu->pre_pcpu), flags);
> + vcpu->pre_pcpu = -1;
> +
> + return 1;
> + }
> +
> + WARN((pi_desc->sn == 1),
> + "Warning: SN field of posted-interrupts "
> + "is set before blocking\n");
> +
> + /*
> + * Since vCPU can be preempted during this process,
> + * vcpu->cpu could be different with pre_pcpu, we
> + * need to set pre_pcpu as the destination of wakeup
> + * notification event, then we can find the right vCPU
> + * to wakeup in wakeup handler if interrupts happen
> + * when the vCPU is in blocked state.
> + */
> + dest = cpu_physical_id(vcpu->pre_pcpu);
> +
> + if (x2apic_enabled())
> + new.ndst = dest;
> + else
> + new.ndst = (dest << 8) & 0xFF00;
> +
> + /* set 'NV' to 'wakeup vector' */
> + new.nv = POSTED_INTR_WAKEUP_VECTOR;
> + } while (cmpxchg(&pi_desc->control, old.control,
> + new.control) != old.control);
> +
> + return 0;
> +}
> +
> +static void vmx_post_block(struct kvm_vcpu *vcpu)
> +{
> + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
> + struct pi_desc old, new;
> + unsigned int dest;
> + unsigned long flags;
> +
> + if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
> + !irq_remapping_cap(IRQ_POSTING_CAP))
> + return;
> +
> + do {
> + old.control = new.control = pi_desc->control;
> +
> + dest = cpu_physical_id(vcpu->cpu);
> +
> + if (x2apic_enabled())
> + new.ndst = dest;
> + else
> + new.ndst = (dest << 8) & 0xFF00;
> +
> + /* Allow posting non-urgent interrupts */
> + new.sn = 0;
> +
> + /* set 'NV' to 'notification vector' */
> + new.nv = POSTED_INTR_VECTOR;
> + } while (cmpxchg(&pi_desc->control, old.control,
> + new.control) != old.control);
> +
> + if(vcpu->pre_pcpu != -1) {
> + spin_lock_irqsave(
> + &per_cpu(blocked_vcpu_on_cpu_lock,
> + vcpu->pre_pcpu), flags);
> + list_del(&vcpu->blocked_vcpu_list);
> + spin_unlock_irqrestore(
> + &per_cpu(blocked_vcpu_on_cpu_lock,
> + vcpu->pre_pcpu), flags);
> + vcpu->pre_pcpu = -1;
> + }
> +}
> +
> +/*
> * vmx_update_pi_irte - set IRTE for Posted-Interrupts
> *
> * @kvm: kvm
> @@ -10620,6 +10770,9 @@ static struct kvm_x86_ops vmx_x86_ops = {
> .flush_log_dirty = vmx_flush_log_dirty,
> .enable_log_dirty_pt_masked = vmx_enable_log_dirty_pt_masked,
>
> + .pre_block = vmx_pre_block,
> + .post_block = vmx_post_block,
> +
> .pmu_ops = &intel_pmu_ops,
>
> .update_pi_irte = vmx_update_pi_irte,
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 58688aa..46f55b2 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -5869,7 +5869,12 @@ int kvm_vcpu_halt(struct kvm_vcpu *vcpu)
> {
> ++vcpu->stat.halt_exits;
> if (irqchip_in_kernel(vcpu->kvm)) {
> - vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
> + /* Handle posted-interrupt when vCPU is to be halted */
> + if (!kvm_x86_ops->pre_block ||
> + kvm_x86_ops->pre_block(vcpu) == 0) {
> + vcpu->arch.halted = true;
> + vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
> + }
> return 1;
> } else {
> vcpu->run->exit_reason = KVM_EXIT_HLT;
> @@ -6518,6 +6523,20 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
> kvm_vcpu_reload_apic_access_page(vcpu);
> }
>
> + /*
> + * KVM_REQ_EVENT is not set when posted interrupts are set by
> + * VT-d hardware, so we have to update RVI unconditionally.
> + */
> + if (kvm_lapic_enabled(vcpu)) {
> + /*
> + * Update architecture specific hints for APIC
> + * virtual interrupt delivery.
> + */
> + if (kvm_x86_ops->hwapic_irr_update)
> + kvm_x86_ops->hwapic_irr_update(vcpu,
> + kvm_lapic_find_highest_irr(vcpu));
> + }
> +
> if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
> kvm_apic_accept_events(vcpu);
> if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) {
> @@ -6534,13 +6553,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
> kvm_x86_ops->enable_irq_window(vcpu);
>
> if (kvm_lapic_enabled(vcpu)) {
> - /*
> - * Update architecture specific hints for APIC
> - * virtual interrupt delivery.
> - */
> - if (kvm_x86_ops->hwapic_irr_update)
> - kvm_x86_ops->hwapic_irr_update(vcpu,
> - kvm_lapic_find_highest_irr(vcpu));
> update_cr8_intercept(vcpu);
> kvm_lapic_sync_to_vapic(vcpu);
> }
> @@ -6711,10 +6723,31 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
>
> for (;;) {
> if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
> - !vcpu->arch.apf.halted)
> + !vcpu->arch.apf.halted) {
> + /*
> + * For some cases, we can get here with
> + * vcpu->arch.halted being true.
> + */
> + if (kvm_x86_ops->post_block && vcpu->arch.halted) {
> + kvm_x86_ops->post_block(vcpu);
> + vcpu->arch.halted = false;
> + }
> +
> r = vcpu_enter_guest(vcpu);
> - else
> + } else {
> r = vcpu_block(kvm, vcpu);
> +
> + /*
> + * post_block() must be called after
> + * pre_block() which is called in
> + * kvm_vcpu_halt().
> + */
> + if (kvm_x86_ops->post_block && vcpu->arch.halted) {
> + kvm_x86_ops->post_block(vcpu);
> + vcpu->arch.halted = false;
> + }
> + }
> +
> if (r <= 0)
> break;
>
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index feba1fb..bf462e7 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -231,6 +231,9 @@ struct kvm_vcpu {
> unsigned long requests;
> unsigned long guest_debug;
>
> + int pre_pcpu;
> + struct list_head blocked_vcpu_list;
> +
> struct mutex mutex;
> struct kvm_run *run;
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 8b8a444..191c7eb 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -220,6 +220,9 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
> init_waitqueue_head(&vcpu->wq);
> kvm_async_pf_vcpu_init(vcpu);
>
> + vcpu->pre_pcpu = -1;
> + INIT_LIST_HEAD(&vcpu->blocked_vcpu_list);
> +
> page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> if (!page) {
> r = -ENOMEM;
> --
> 2.1.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | "Wu, Feng" <feng.wu@intel.com> |
|---|---|
| Date | 2015-10-15 03:40 +0200 |
| Message-ID | <qjFGq-8dL-25@gated-at.bofh.it> |
| In reply to | #1247257 |
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogRGF2aWQgTWF0bGFjayBb bWFpbHRvOmRtYXRsYWNrQGdvb2dsZS5jb21dDQo+IFNlbnQ6IFRodXJzZGF5LCBPY3RvYmVyIDE1 LCAyMDE1IDc6NDEgQU0NCj4gVG86IFd1LCBGZW5nIDxmZW5nLnd1QGludGVsLmNvbT4NCj4gQ2M6 IFBhb2xvIEJvbnppbmkgPHBib256aW5pQHJlZGhhdC5jb20+OyBhbGV4LndpbGxpYW1zb25AcmVk aGF0LmNvbTsgSm9lcmcNCj4gUm9lZGVsIDxqb3JvQDhieXRlcy5vcmc+OyBNYXJjZWxvIFRvc2F0 dGkgPG10b3NhdHRpQHJlZGhhdC5jb20+Ow0KPiBlcmljLmF1Z2VyQGxpbmFyby5vcmc7IGt2bSBs aXN0IDxrdm1Admdlci5rZXJuZWwub3JnPjsgaW9tbXVAbGlzdHMubGludXgtDQo+IGZvdW5kYXRp b24ub3JnOyBsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnDQo+IFN1YmplY3Q6IFJlOiBbUEFU Q0ggdjkgMTcvMThdIEtWTTogVXBkYXRlIFBvc3RlZC1JbnRlcnJ1cHRzIERlc2NyaXB0b3Igd2hl bg0KPiB2Q1BVIGlzIGJsb2NrZWQNCj4gDQo+IEhpIEZlbmcuDQo+IA0KPiBPbiBGcmksIFNlcCAx OCwgMjAxNSBhdCA3OjI5IEFNLCBGZW5nIFd1IDxmZW5nLnd1QGludGVsLmNvbT4gd3JvdGU6DQo+ ID4gVGhpcyBwYXRjaCB1cGRhdGVzIHRoZSBQb3N0ZWQtSW50ZXJydXB0cyBEZXNjcmlwdG9yIHdo ZW4gdkNQVQ0KPiA+IGlzIGJsb2NrZWQuDQo+ID4NCj4gPiBwcmUtYmxvY2s6DQo+ID4gLSBBZGQg dGhlIHZDUFUgdG8gdGhlIGJsb2NrZWQgcGVyLUNQVSBsaXN0DQo+ID4gLSBTZXQgJ05WJyB0byBQ T1NURURfSU5UUl9XQUtFVVBfVkVDVE9SDQo+ID4NCj4gPiBwb3N0LWJsb2NrOg0KPiA+IC0gUmVt b3ZlIHRoZSB2Q1BVIGZyb20gdGhlIHBlci1DUFUgbGlzdA0KPiANCj4gSSdtIHdvbmRlcmluZyB3 aGF0IGhhcHBlbnMgaWYgYSBwb3N0ZWQgaW50ZXJydXB0IGFycml2ZXMgYXQgdGhlIElPTU1VDQo+ IGFmdGVyIHByZS1ibG9jayBhbmQgYmVmb3JlIHBvc3QtYmxvY2suDQo+IA0KPiBJbiBwcmVfYmxv Y2ssIE5WIGlzIHNldCB0byBQT1NURURfSU5UUl9XQUtFVVBfVkVDVE9SLiBJSVVDLCB0aGlzIG1l YW5zDQo+IGZ1dHVyZSBwb3N0ZWQgaW50ZXJydXB0cyB3aWxsIG5vdCB0cmlnZ2VyICJQb3N0ZWQt SW50ZXJydXB0IFByb2Nlc3NpbmciDQo+IChQSVIgd2lsbCBub3QgZ2V0IGNvcGllZCB0byBWSVJS KS4gSW5zdGVhZCwgdGhlIElPTU1VIHdpbGwgZG8gT04gOj0gMSwNCj4gUElSIHw9ICgxIDw8IHZl Y3RvciksIGFuZCBzZW5kIFBPU1RFRF9JTlRSX1dBS0VVUF9WRUNUT1IuIFBJV1YgY2FsbHMNCj4g d2FrZXVwX2hhbmRsZXIgd2hpY2ggZG9lcyBrdm1fdmNwdV9raWNrLiBrdm1fdmNwdV9raWNrIGRv ZXMgYSB3YWl0LXF1ZXVlDQo+IHdha2V1cCBhbmQgcG9zc2libHkgYSBzY2hlZHVsZXIgaXBpLg0K PiANCj4gQnV0IHRoZSBWQ1BVIGlzIHNpdHRpbmcgaW4ga3ZtX3ZjcHVfYmxvY2suIEl0IHNwaW5z IGFuZC9vciBzY2hlZHVsZXMNCj4gKHdhaXQgcXVldWUpIHVudGlsIGl0IGhhcyBhIHJlYXNvbiB0 byB3YWtlIHVwLiBJIGNvdWxkbid0IGZpbmQgYSBjb2RlDQo+IHBhdGggZnJvbSBrdm1fdmNwdV9i bG9jayB0aGF0IGxlYWQgdG8gY2hlY2tpbmcgT04gb3IgUElSLiBIb3cgZG9lcyB0aGUNCj4gYmxv Y2tlZCBWQ1BVICJyZWNlaXZlIiB0aGUgcG9zdGVkIGludGVycnVwdD8gKEFuZCB3aGVuIGRvZXMg UG9zdGVkLQ0KPiBJbnRlcnJ1cHQgUHJvY2Vzc2luZyBnZXQgdHJpZ2dlcmVkPykNCg0KSW4gdGhl IHByZV9ibG9jaywgaXQgYWxzbyBjaGFuZ2UgdGhlICdORFNUJyBmaWxlZCB0byB0aGUgcENQVSwg b24gd2hpY2ggdGhlIHZDUFUNCmlzIHB1dCB0byB0aGUgcGVyLUNQVSBsaXN0ICdibG9ja2VkX3Zj cHVfb25fY3B1Jywgc28gd2hlbiBwb3N0ZWQtaW50ZXJydXB0cw0KY29tZSBpdCwgaXQgd2lsbCBz ZW50IHRoZSB3YWtldXAgbm90aWZpY2F0aW9uIGV2ZW50IHRvIHRoZSBwQ1BVIGFib3ZlLCB0aGVu IGluDQp0aGUgd2FrZXVwX2hhbmRsZXIsIGl0IGNhbiBmaW5kIHRoZSB2Q1BVIGZyb20gdGhlIHBl ci1DUFUgbGlzdCwgaGVuY2UNCmt2bV92Y3B1X2tpY2sgY2FuIHdha2UgdXAgaXQuDQoNClRoYW5r cywNCkZlbmcNCg0KPiANCj4gVGhhbmtzIQ0KPiANCj4gPg0KPiA+IFNpZ25lZC1vZmYtYnk6IEZl bmcgV3UgPGZlbmcud3VAaW50ZWwuY29tPg0KPiA+IC0tLQ0KPiA+IHY5Og0KPiA+IC0gQWRkIGRl c2NyaXB0aW9uIGZvciBibG9ja2VkX3ZjcHVfb25fY3B1X2xvY2sgaW4NCj4gRG9jdW1lbnRhdGlv bi92aXJ0dWFsL2t2bS9sb2NraW5nLnR4dA0KPiA+IC0gQ2hlY2sgIWt2bV9hcmNoX2hhc19hc3Np Z25lZF9kZXZpY2UodmNwdS0+a3ZtKSBmaXJzdCwgdGhlbg0KPiA+ICAgIWlycV9yZW1hcHBpbmdf Y2FwKElSUV9QT1NUSU5HX0NBUCkNCj4gPg0KPiA+IHY4Og0KPiA+IC0gUmVuYW1lICdwaV9wcmVf YmxvY2snIHRvICdwcmVfYmxvY2snDQo+ID4gLSBSZW5hbWUgJ3BpX3Bvc3RfYmxvY2snIHRvICdw b3N0X2Jsb2NrJw0KPiA+IC0gQ2hhbmdlIHNvbWUgY29tbWVudHMNCj4gPiAtIE9ubHkgYWRkIHRo ZSB2Q1BVIHRvIHRoZSBibG9ja2luZyBsaXN0IHdoZW4gdGhlIFZNIGhhcyBhc3NpZ25lZCBkZXZp Y2VzLg0KPiA+DQo+ID4gIERvY3VtZW50YXRpb24vdmlydHVhbC9rdm0vbG9ja2luZy50eHQgfCAg MTIgKysrDQo+ID4gIGFyY2gveDg2L2luY2x1ZGUvYXNtL2t2bV9ob3N0LmggICAgICAgfCAgMTMg KysrDQo+ID4gIGFyY2gveDg2L2t2bS92bXguYyAgICAgICAgICAgICAgICAgICAgfCAxNTMNCj4g KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKw0KPiA+ICBhcmNoL3g4Ni9rdm0veDg2 LmMgICAgICAgICAgICAgICAgICAgIHwgIDUzICsrKysrKysrKy0tLQ0KPiA+ICBpbmNsdWRlL2xp bnV4L2t2bV9ob3N0LmggICAgICAgICAgICAgIHwgICAzICsNCj4gPiAgdmlydC9rdm0va3ZtX21h aW4uYyAgICAgICAgICAgICAgICAgICB8ICAgMyArDQo+ID4gIDYgZmlsZXMgY2hhbmdlZCwgMjI3 IGluc2VydGlvbnMoKyksIDEwIGRlbGV0aW9ucygtKQ0KPiA+DQo+ID4gZGlmZiAtLWdpdCBhL0Rv Y3VtZW50YXRpb24vdmlydHVhbC9rdm0vbG9ja2luZy50eHQNCj4gYi9Eb2N1bWVudGF0aW9uL3Zp cnR1YWwva3ZtL2xvY2tpbmcudHh0DQo+ID4gaW5kZXggZDY4YWY0ZC4uMTlmOTRhNiAxMDA2NDQN Cj4gPiAtLS0gYS9Eb2N1bWVudGF0aW9uL3ZpcnR1YWwva3ZtL2xvY2tpbmcudHh0DQo+ID4gKysr IGIvRG9jdW1lbnRhdGlvbi92aXJ0dWFsL2t2bS9sb2NraW5nLnR4dA0KPiA+IEBAIC0xNjYsMyAr MTY2LDE1IEBAIENvbW1lbnQ6ICAgVGhlIHNyY3UgcmVhZCBsb2NrIG11c3QgYmUgaGVsZCB3aGls ZQ0KPiBhY2Nlc3NpbmcgbWVtc2xvdHMgKGUuZy4NCj4gPiAgICAgICAgICAgICAgICAgTU1JTy9Q SU8gYWRkcmVzcy0+ZGV2aWNlIHN0cnVjdHVyZSBtYXBwaW5nIChrdm0tPmJ1c2VzKS4NCj4gPiAg ICAgICAgICAgICAgICAgVGhlIHNyY3UgaW5kZXggY2FuIGJlIHN0b3JlZCBpbiBrdm1fdmNwdS0+ c3JjdV9pZHggcGVyIHZjcHUNCj4gPiAgICAgICAgICAgICAgICAgaWYgaXQgaXMgbmVlZGVkIGJ5 IG11bHRpcGxlIGZ1bmN0aW9ucy4NCj4gPiArDQo+ID4gK05hbWU6ICAgICAgICAgIGJsb2NrZWRf dmNwdV9vbl9jcHVfbG9jaw0KPiA+ICtUeXBlOiAgICAgICAgICBzcGlubG9ja190DQo+ID4gK0Fy Y2g6ICAgICAgICAgIHg4Ng0KPiA+ICtQcm90ZWN0czogICAgICBibG9ja2VkX3ZjcHVfb25fY3B1 DQo+ID4gK0NvbW1lbnQ6ICAgICAgIFRoaXMgaXMgYSBwZXItQ1BVIGxvY2sgYW5kIGl0IGlzIHVz ZWQgZm9yIFZULWQgcG9zdGVkLWludGVycnVwdHMuDQo+ID4gKyAgICAgICAgICAgICAgIFdoZW4g VlQtZCBwb3N0ZWQtaW50ZXJydXB0cyBpcyBzdXBwb3J0ZWQgYW5kIHRoZSBWTSBoYXMgYXNzaWdu ZWQNCj4gPiArICAgICAgICAgICAgICAgZGV2aWNlcywgd2UgcHV0IHRoZSBibG9ja2VkIHZDUFUg b24gdGhlIGxpc3QgYmxvY2tlZF92Y3B1X29uX2NwdQ0KPiA+ICsgICAgICAgICAgICAgICBwcm90 ZWN0ZWQgYnkgYmxvY2tlZF92Y3B1X29uX2NwdV9sb2NrLCB3aGVuIFZULWQgaGFyZHdhcmUNCj4g aXNzdWVzDQo+ID4gKyAgICAgICAgICAgICAgIHdha2V1cCBub3RpZmljYXRpb24gZXZlbnQgc2lu Y2UgZXh0ZXJuYWwgaW50ZXJydXB0cyBmcm9tIHRoZQ0KPiA+ICsgICAgICAgICAgICAgICBhc3Np Z25lZCBkZXZpY2VzIGhhcHBlbnMsIHdlIHdpbGwgZmluZCB0aGUgdkNQVSBvbiB0aGUgbGlzdCB0 bw0KPiA+ICsgICAgICAgICAgICAgICB3YWtldXAuDQo+ID4gZGlmZiAtLWdpdCBhL2FyY2gveDg2 L2luY2x1ZGUvYXNtL2t2bV9ob3N0LmgNCj4gYi9hcmNoL3g4Ni9pbmNsdWRlL2FzbS9rdm1faG9z dC5oDQo+ID4gaW5kZXggMGRkZDM1My4uMzA0ZmJiNSAxMDA2NDQNCj4gPiAtLS0gYS9hcmNoL3g4 Ni9pbmNsdWRlL2FzbS9rdm1faG9zdC5oDQo+ID4gKysrIGIvYXJjaC94ODYvaW5jbHVkZS9hc20v a3ZtX2hvc3QuaA0KPiA+IEBAIC01NTIsNiArNTUyLDggQEAgc3RydWN0IGt2bV92Y3B1X2FyY2gg ew0KPiA+ICAgICAgICAgICovDQo+ID4gICAgICAgICBib29sIHdyaXRlX2ZhdWx0X3RvX3NoYWRv d19wZ3RhYmxlOw0KPiA+DQo+ID4gKyAgICAgICBib29sIGhhbHRlZDsNCj4gPiArDQo+ID4gICAg ICAgICAvKiBzZXQgYXQgRVBUIHZpb2xhdGlvbiBhdCB0aGlzIHBvaW50ICovDQo+ID4gICAgICAg ICB1bnNpZ25lZCBsb25nIGV4aXRfcXVhbGlmaWNhdGlvbjsNCj4gPg0KPiA+IEBAIC04NjQsNiAr ODY2LDE3IEBAIHN0cnVjdCBrdm1feDg2X29wcyB7DQo+ID4gICAgICAgICAvKiBwbXUgb3BlcmF0 aW9ucyBvZiBzdWItYXJjaCAqLw0KPiA+ICAgICAgICAgY29uc3Qgc3RydWN0IGt2bV9wbXVfb3Bz ICpwbXVfb3BzOw0KPiA+DQo+ID4gKyAgICAgICAvKg0KPiA+ICsgICAgICAgICogQXJjaGl0ZWN0 dXJlIHNwZWNpZmljIGhvb2tzIGZvciB2Q1BVIGJsb2NraW5nIGR1ZSB0bw0KPiA+ICsgICAgICAg ICogSExUIGluc3RydWN0aW9uLg0KPiA+ICsgICAgICAgICogUmV0dXJucyBmb3IgLnByZV9ibG9j aygpOg0KPiA+ICsgICAgICAgICogICAgLSAwIG1lYW5zIGNvbnRpbnVlIHRvIGJsb2NrIHRoZSB2 Q1BVLg0KPiA+ICsgICAgICAgICogICAgLSAxIG1lYW5zIHdlIGNhbm5vdCBibG9jayB0aGUgdkNQ VSBzaW5jZSBzb21lIGV2ZW50DQo+ID4gKyAgICAgICAgKiAgICAgICAgaGFwcGVucyBkdXJpbmcg dGhpcyBwZXJpb2QsIHN1Y2ggYXMsICdPTicgYml0IGluDQo+ID4gKyAgICAgICAgKiAgICAgICAg cG9zdGVkLWludGVycnVwdHMgZGVzY3JpcHRvciBpcyBzZXQuDQo+ID4gKyAgICAgICAgKi8NCj4g PiArICAgICAgIGludCAoKnByZV9ibG9jaykoc3RydWN0IGt2bV92Y3B1ICp2Y3B1KTsNCj4gPiAr ICAgICAgIHZvaWQgKCpwb3N0X2Jsb2NrKShzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUpOw0KPiA+ICAg ICAgICAgaW50ICgqdXBkYXRlX3BpX2lydGUpKHN0cnVjdCBrdm0gKmt2bSwgdW5zaWduZWQgaW50 IGhvc3RfaXJxLA0KPiA+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGd1 ZXN0X2lycSwgYm9vbCBzZXQpOw0KPiA+ICB9Ow0KPiA+IGRpZmYgLS1naXQgYS9hcmNoL3g4Ni9r dm0vdm14LmMgYi9hcmNoL3g4Ni9rdm0vdm14LmMNCj4gPiBpbmRleCA5MDJhNjdkLi45OTY4ODk2 IDEwMDY0NA0KPiA+IC0tLSBhL2FyY2gveDg2L2t2bS92bXguYw0KPiA+ICsrKyBiL2FyY2gveDg2 L2t2bS92bXguYw0KPiA+IEBAIC04NzksNiArODc5LDEzIEBAIHN0YXRpYyBERUZJTkVfUEVSX0NQ VShzdHJ1Y3Qgdm1jcyAqLA0KPiBjdXJyZW50X3ZtY3MpOw0KPiA+ICBzdGF0aWMgREVGSU5FX1BF Ul9DUFUoc3RydWN0IGxpc3RfaGVhZCwgbG9hZGVkX3ZtY3NzX29uX2NwdSk7DQo+ID4gIHN0YXRp YyBERUZJTkVfUEVSX0NQVShzdHJ1Y3QgZGVzY19wdHIsIGhvc3RfZ2R0KTsNCj4gPg0KPiA+ICsv Kg0KPiA+ICsgKiBXZSBtYWludGlhbiBhIHBlci1DUFUgbGlua2VkLWxpc3Qgb2YgdkNQVSwgc28g aW4gd2FrZXVwX2hhbmRsZXIoKSB3ZQ0KPiA+ICsgKiBjYW4gZmluZCB3aGljaCB2Q1BVIHNob3Vs ZCBiZSB3YWtlbiB1cC4NCj4gPiArICovDQo+ID4gK3N0YXRpYyBERUZJTkVfUEVSX0NQVShzdHJ1 Y3QgbGlzdF9oZWFkLCBibG9ja2VkX3ZjcHVfb25fY3B1KTsNCj4gPiArc3RhdGljIERFRklORV9Q RVJfQ1BVKHNwaW5sb2NrX3QsIGJsb2NrZWRfdmNwdV9vbl9jcHVfbG9jayk7DQo+ID4gKw0KPiA+ ICBzdGF0aWMgdW5zaWduZWQgbG9uZyAqdm14X2lvX2JpdG1hcF9hOw0KPiA+ICBzdGF0aWMgdW5z aWduZWQgbG9uZyAqdm14X2lvX2JpdG1hcF9iOw0KPiA+ICBzdGF0aWMgdW5zaWduZWQgbG9uZyAq dm14X21zcl9iaXRtYXBfbGVnYWN5Ow0KPiA+IEBAIC0yOTg1LDYgKzI5OTIsOCBAQCBzdGF0aWMg aW50IGhhcmR3YXJlX2VuYWJsZSh2b2lkKQ0KPiA+ICAgICAgICAgICAgICAgICByZXR1cm4gLUVC VVNZOw0KPiA+DQo+ID4gICAgICAgICBJTklUX0xJU1RfSEVBRCgmcGVyX2NwdShsb2FkZWRfdm1j c3Nfb25fY3B1LCBjcHUpKTsNCj4gPiArICAgICAgIElOSVRfTElTVF9IRUFEKCZwZXJfY3B1KGJs b2NrZWRfdmNwdV9vbl9jcHUsIGNwdSkpOw0KPiA+ICsgICAgICAgc3Bpbl9sb2NrX2luaXQoJnBl cl9jcHUoYmxvY2tlZF92Y3B1X29uX2NwdV9sb2NrLCBjcHUpKTsNCj4gPg0KPiA+ICAgICAgICAg LyoNCj4gPiAgICAgICAgICAqIE5vdyB3ZSBjYW4gZW5hYmxlIHRoZSB2bWNsZWFyIG9wZXJhdGlv biBpbiBrZHVtcA0KPiA+IEBAIC02MTIxLDYgKzYxMzAsMjUgQEAgc3RhdGljIHZvaWQgdXBkYXRl X3BsZV93aW5kb3dfYWN0dWFsX21heCh2b2lkKQ0KPiA+ICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgcGxlX3dpbmRvd19ncm93LCBJTlRfTUlOKTsNCj4gPiAgfQ0K PiA+DQo+ID4gKy8qDQo+ID4gKyAqIEhhbmRsZXIgZm9yIFBPU1RFRF9JTlRFUlJVUFRfV0FLRVVQ X1ZFQ1RPUi4NCj4gPiArICovDQo+ID4gK3N0YXRpYyB2b2lkIHdha2V1cF9oYW5kbGVyKHZvaWQp DQo+ID4gK3sNCj4gPiArICAgICAgIHN0cnVjdCBrdm1fdmNwdSAqdmNwdTsNCj4gPiArICAgICAg IGludCBjcHUgPSBzbXBfcHJvY2Vzc29yX2lkKCk7DQo+ID4gKw0KPiA+ICsgICAgICAgc3Bpbl9s b2NrKCZwZXJfY3B1KGJsb2NrZWRfdmNwdV9vbl9jcHVfbG9jaywgY3B1KSk7DQo+ID4gKyAgICAg ICBsaXN0X2Zvcl9lYWNoX2VudHJ5KHZjcHUsICZwZXJfY3B1KGJsb2NrZWRfdmNwdV9vbl9jcHUs IGNwdSksDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tlZF92Y3B1X2xpc3QpIHsN Cj4gPiArICAgICAgICAgICAgICAgc3RydWN0IHBpX2Rlc2MgKnBpX2Rlc2MgPSB2Y3B1X3RvX3Bp X2Rlc2ModmNwdSk7DQo+ID4gKw0KPiA+ICsgICAgICAgICAgICAgICBpZiAocGlfdGVzdF9vbihw aV9kZXNjKSA9PSAxKQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGt2bV92Y3B1X2tpY2so dmNwdSk7DQo+ID4gKyAgICAgICB9DQo+ID4gKyAgICAgICBzcGluX3VubG9jaygmcGVyX2NwdShi bG9ja2VkX3ZjcHVfb25fY3B1X2xvY2ssIGNwdSkpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICBzdGF0 aWMgX19pbml0IGludCBoYXJkd2FyZV9zZXR1cCh2b2lkKQ0KPiA+ICB7DQo+ID4gICAgICAgICBp bnQgciA9IC1FTk9NRU0sIGksIG1zcjsNCj4gPiBAQCAtNjMwNSw2ICs2MzMzLDggQEAgc3RhdGlj IF9faW5pdCBpbnQgaGFyZHdhcmVfc2V0dXAodm9pZCkNCj4gPiAgICAgICAgICAgICAgICAga3Zt X3g4Nl9vcHMtPmVuYWJsZV9sb2dfZGlydHlfcHRfbWFza2VkID0gTlVMTDsNCj4gPiAgICAgICAg IH0NCj4gPg0KPiA+ICsgICAgICAga3ZtX3NldF9wb3N0ZWRfaW50cl93YWtldXBfaGFuZGxlcih3 YWtldXBfaGFuZGxlcik7DQo+ID4gKw0KPiA+ICAgICAgICAgcmV0dXJuIGFsbG9jX2t2bV9hcmVh KCk7DQo+ID4NCj4gPiAgb3V0ODoNCj4gPiBAQCAtMTA0MzAsNiArMTA0NjAsMTI2IEBAIHN0YXRp YyB2b2lkDQo+IHZteF9lbmFibGVfbG9nX2RpcnR5X3B0X21hc2tlZChzdHJ1Y3Qga3ZtICprdm0s DQo+ID4gIH0NCj4gPg0KPiA+ICAvKg0KPiA+ICsgKiBUaGlzIHJvdXRpbmUgZG9lcyB0aGUgZm9s bG93aW5nIHRoaW5ncyBmb3IgdkNQVSB3aGljaCBpcyBnb2luZw0KPiA+ICsgKiB0byBiZSBibG9j a2VkIGlmIFZULWQgUEkgaXMgZW5hYmxlZC4NCj4gPiArICogLSBTdG9yZSB0aGUgdkNQVSB0byB0 aGUgd2FrZXVwIGxpc3QsIHNvIHdoZW4gaW50ZXJydXB0cyBoYXBwZW4NCj4gPiArICogICB3ZSBj YW4gZmluZCB0aGUgcmlnaHQgdkNQVSB0byB3YWtlIHVwLg0KPiA+ICsgKiAtIENoYW5nZSB0aGUg UG9zdGVkLWludGVycnVwdCBkZXNjcmlwdG9yIGFzIGJlbG93Og0KPiA+ICsgKiAgICAgICdORFNU JyA8LS0gdmNwdS0+cHJlX3BjcHUNCj4gPiArICogICAgICAnTlYnIDwtLSBQT1NURURfSU5UUl9X QUtFVVBfVkVDVE9SDQo+ID4gKyAqIC0gSWYgJ09OJyBpcyBzZXQgZHVyaW5nIHRoaXMgcHJvY2Vz cywgd2hpY2ggbWVhbnMgYXQgbGVhc3Qgb25lDQo+ID4gKyAqICAgaW50ZXJydXB0IGlzIHBvc3Rl ZCBmb3IgdGhpcyB2Q1BVLCB3ZSBjYW5ub3QgYmxvY2sgaXQsIGluDQo+ID4gKyAqICAgdGhpcyBj YXNlLCByZXR1cm4gMSwgb3RoZXJ3aXNlLCByZXR1cm4gMC4NCj4gPiArICoNCj4gPiArICovDQo+ ID4gK3N0YXRpYyBpbnQgdm14X3ByZV9ibG9jayhzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUpDQo+ID4g K3sNCj4gPiArICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3M7DQo+ID4gKyAgICAgICB1bnNpZ25l ZCBpbnQgZGVzdDsNCj4gPiArICAgICAgIHN0cnVjdCBwaV9kZXNjIG9sZCwgbmV3Ow0KPiA+ICsg ICAgICAgc3RydWN0IHBpX2Rlc2MgKnBpX2Rlc2MgPSB2Y3B1X3RvX3BpX2Rlc2ModmNwdSk7DQo+ ID4gKw0KPiA+ICsgICAgICAgaWYgKCFrdm1fYXJjaF9oYXNfYXNzaWduZWRfZGV2aWNlKHZjcHUt Pmt2bSkgfHwNCj4gPiArICAgICAgICAgICAgICAgIWlycV9yZW1hcHBpbmdfY2FwKElSUV9QT1NU SU5HX0NBUCkpDQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybiAwOw0KPiA+ICsNCj4gPiArICAg ICAgIHZjcHUtPnByZV9wY3B1ID0gdmNwdS0+Y3B1Ow0KPiA+ICsgICAgICAgc3Bpbl9sb2NrX2ly cXNhdmUoJnBlcl9jcHUoYmxvY2tlZF92Y3B1X29uX2NwdV9sb2NrLA0KPiA+ICsgICAgICAgICAg ICAgICAgICAgICAgICAgdmNwdS0+cHJlX3BjcHUpLCBmbGFncyk7DQo+ID4gKyAgICAgICBsaXN0 X2FkZF90YWlsKCZ2Y3B1LT5ibG9ja2VkX3ZjcHVfbGlzdCwNCj4gPiArICAgICAgICAgICAgICAg ICAgICAgJnBlcl9jcHUoYmxvY2tlZF92Y3B1X29uX2NwdSwNCj4gPiArICAgICAgICAgICAgICAg ICAgICAgdmNwdS0+cHJlX3BjcHUpKTsNCj4gPiArICAgICAgIHNwaW5fdW5sb2NrX2lycXJlc3Rv cmUoJnBlcl9jcHUoYmxvY2tlZF92Y3B1X29uX2NwdV9sb2NrLA0KPiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICB2Y3B1LT5wcmVfcGNwdSksIGZsYWdzKTsNCj4gPiArDQo+ID4gKyAg ICAgICBkbyB7DQo+ID4gKyAgICAgICAgICAgICAgIG9sZC5jb250cm9sID0gbmV3LmNvbnRyb2wg PSBwaV9kZXNjLT5jb250cm9sOw0KPiA+ICsNCj4gPiArICAgICAgICAgICAgICAgLyoNCj4gPiAr ICAgICAgICAgICAgICAgICogV2Ugc2hvdWxkIG5vdCBibG9jayB0aGUgdkNQVSBpZg0KPiA+ICsg ICAgICAgICAgICAgICAgKiBhbiBpbnRlcnJ1cHQgaXMgcG9zdGVkIGZvciBpdC4NCj4gPiArICAg ICAgICAgICAgICAgICovDQo+ID4gKyAgICAgICAgICAgICAgIGlmIChwaV90ZXN0X29uKHBpX2Rl c2MpID09IDEpIHsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBzcGluX2xvY2tfaXJxc2F2 ZSgmcGVyX2NwdShibG9ja2VkX3ZjcHVfb25fY3B1X2xvY2ssDQo+ID4gKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgdmNwdS0+cHJlX3BjcHUpLCBmbGFncyk7DQo+ID4g KyAgICAgICAgICAgICAgICAgICAgICAgbGlzdF9kZWwoJnZjcHUtPmJsb2NrZWRfdmNwdV9saXN0 KTsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBzcGluX3VubG9ja19pcnFyZXN0b3JlKA0K PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGVyX2NwdShibG9j a2VkX3ZjcHVfb25fY3B1X2xvY2ssDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHZjcHUtPnByZV9wY3B1KSwgZmxhZ3MpOw0KPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgIHZjcHUtPnByZV9wY3B1ID0gLTE7DQo+ID4gKw0KPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgIHJldHVybiAxOw0KPiA+ICsgICAgICAgICAgICAgICB9DQo+ID4gKw0KPiA+ICsgICAg ICAgICAgICAgICBXQVJOKChwaV9kZXNjLT5zbiA9PSAxKSwNCj4gPiArICAgICAgICAgICAgICAg ICAgICAiV2FybmluZzogU04gZmllbGQgb2YgcG9zdGVkLWludGVycnVwdHMgIg0KPiA+ICsgICAg ICAgICAgICAgICAgICAgICJpcyBzZXQgYmVmb3JlIGJsb2NraW5nXG4iKTsNCj4gPiArDQo+ID4g KyAgICAgICAgICAgICAgIC8qDQo+ID4gKyAgICAgICAgICAgICAgICAqIFNpbmNlIHZDUFUgY2Fu IGJlIHByZWVtcHRlZCBkdXJpbmcgdGhpcyBwcm9jZXNzLA0KPiA+ICsgICAgICAgICAgICAgICAg KiB2Y3B1LT5jcHUgY291bGQgYmUgZGlmZmVyZW50IHdpdGggcHJlX3BjcHUsIHdlDQo+ID4gKyAg ICAgICAgICAgICAgICAqIG5lZWQgdG8gc2V0IHByZV9wY3B1IGFzIHRoZSBkZXN0aW5hdGlvbiBv ZiB3YWtldXANCj4gPiArICAgICAgICAgICAgICAgICogbm90aWZpY2F0aW9uIGV2ZW50LCB0aGVu IHdlIGNhbiBmaW5kIHRoZSByaWdodCB2Q1BVDQo+ID4gKyAgICAgICAgICAgICAgICAqIHRvIHdh a2V1cCBpbiB3YWtldXAgaGFuZGxlciBpZiBpbnRlcnJ1cHRzIGhhcHBlbg0KPiA+ICsgICAgICAg ICAgICAgICAgKiB3aGVuIHRoZSB2Q1BVIGlzIGluIGJsb2NrZWQgc3RhdGUuDQo+ID4gKyAgICAg ICAgICAgICAgICAqLw0KPiA+ICsgICAgICAgICAgICAgICBkZXN0ID0gY3B1X3BoeXNpY2FsX2lk KHZjcHUtPnByZV9wY3B1KTsNCj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIGlmICh4MmFwaWNf ZW5hYmxlZCgpKQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIG5ldy5uZHN0ID0gZGVzdDsN Cj4gPiArICAgICAgICAgICAgICAgZWxzZQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIG5l dy5uZHN0ID0gKGRlc3QgPDwgOCkgJiAweEZGMDA7DQo+ID4gKw0KPiA+ICsgICAgICAgICAgICAg ICAvKiBzZXQgJ05WJyB0byAnd2FrZXVwIHZlY3RvcicgKi8NCj4gPiArICAgICAgICAgICAgICAg bmV3Lm52ID0gUE9TVEVEX0lOVFJfV0FLRVVQX1ZFQ1RPUjsNCj4gPiArICAgICAgIH0gd2hpbGUg KGNtcHhjaGcoJnBpX2Rlc2MtPmNvbnRyb2wsIG9sZC5jb250cm9sLA0KPiA+ICsgICAgICAgICAg ICAgICAgICAgICAgIG5ldy5jb250cm9sKSAhPSBvbGQuY29udHJvbCk7DQo+ID4gKw0KPiA+ICsg ICAgICAgcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyB2b2lkIHZteF9wb3N0 X2Jsb2NrKHN0cnVjdCBrdm1fdmNwdSAqdmNwdSkNCj4gPiArew0KPiA+ICsgICAgICAgc3RydWN0 IHBpX2Rlc2MgKnBpX2Rlc2MgPSB2Y3B1X3RvX3BpX2Rlc2ModmNwdSk7DQo+ID4gKyAgICAgICBz dHJ1Y3QgcGlfZGVzYyBvbGQsIG5ldzsNCj4gPiArICAgICAgIHVuc2lnbmVkIGludCBkZXN0Ow0K PiA+ICsgICAgICAgdW5zaWduZWQgbG9uZyBmbGFnczsNCj4gPiArDQo+ID4gKyAgICAgICBpZiAo IWt2bV9hcmNoX2hhc19hc3NpZ25lZF9kZXZpY2UodmNwdS0+a3ZtKSB8fA0KPiA+ICsgICAgICAg ICAgICAgICAhaXJxX3JlbWFwcGluZ19jYXAoSVJRX1BPU1RJTkdfQ0FQKSkNCj4gPiArICAgICAg ICAgICAgICAgcmV0dXJuOw0KPiA+ICsNCj4gPiArICAgICAgIGRvIHsNCj4gPiArICAgICAgICAg ICAgICAgb2xkLmNvbnRyb2wgPSBuZXcuY29udHJvbCA9IHBpX2Rlc2MtPmNvbnRyb2w7DQo+ID4g Kw0KPiA+ICsgICAgICAgICAgICAgICBkZXN0ID0gY3B1X3BoeXNpY2FsX2lkKHZjcHUtPmNwdSk7 DQo+ID4gKw0KPiA+ICsgICAgICAgICAgICAgICBpZiAoeDJhcGljX2VuYWJsZWQoKSkNCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICBuZXcubmRzdCA9IGRlc3Q7DQo+ID4gKyAgICAgICAgICAg ICAgIGVsc2UNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBuZXcubmRzdCA9IChkZXN0IDw8 IDgpICYgMHhGRjAwOw0KPiA+ICsNCj4gPiArICAgICAgICAgICAgICAgLyogQWxsb3cgcG9zdGlu ZyBub24tdXJnZW50IGludGVycnVwdHMgKi8NCj4gPiArICAgICAgICAgICAgICAgbmV3LnNuID0g MDsNCj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIC8qIHNldCAnTlYnIHRvICdub3RpZmljYXRp b24gdmVjdG9yJyAqLw0KPiA+ICsgICAgICAgICAgICAgICBuZXcubnYgPSBQT1NURURfSU5UUl9W RUNUT1I7DQo+ID4gKyAgICAgICB9IHdoaWxlIChjbXB4Y2hnKCZwaV9kZXNjLT5jb250cm9sLCBv bGQuY29udHJvbCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBuZXcuY29udHJvbCkgIT0g b2xkLmNvbnRyb2wpOw0KPiA+ICsNCj4gPiArICAgICAgIGlmKHZjcHUtPnByZV9wY3B1ICE9IC0x KSB7DQo+ID4gKyAgICAgICAgICAgICAgIHNwaW5fbG9ja19pcnFzYXZlKA0KPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgICZwZXJfY3B1KGJsb2NrZWRfdmNwdV9vbl9jcHVfbG9jaywNCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICB2Y3B1LT5wcmVfcGNwdSksIGZsYWdzKTsNCj4gPiArICAg ICAgICAgICAgICAgbGlzdF9kZWwoJnZjcHUtPmJsb2NrZWRfdmNwdV9saXN0KTsNCj4gPiArICAg ICAgICAgICAgICAgc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgNCj4gPiArICAgICAgICAgICAgICAg ICAgICAgICAmcGVyX2NwdShibG9ja2VkX3ZjcHVfb25fY3B1X2xvY2ssDQo+ID4gKyAgICAgICAg ICAgICAgICAgICAgICAgdmNwdS0+cHJlX3BjcHUpLCBmbGFncyk7DQo+ID4gKyAgICAgICAgICAg ICAgIHZjcHUtPnByZV9wY3B1ID0gLTE7DQo+ID4gKyAgICAgICB9DQo+ID4gK30NCj4gPiArDQo+ ID4gKy8qDQo+ID4gICAqIHZteF91cGRhdGVfcGlfaXJ0ZSAtIHNldCBJUlRFIGZvciBQb3N0ZWQt SW50ZXJydXB0cw0KPiA+ICAgKg0KPiA+ICAgKiBAa3ZtOiBrdm0NCj4gPiBAQCAtMTA2MjAsNiAr MTA3NzAsOSBAQCBzdGF0aWMgc3RydWN0IGt2bV94ODZfb3BzIHZteF94ODZfb3BzID0gew0KPiA+ ICAgICAgICAgLmZsdXNoX2xvZ19kaXJ0eSA9IHZteF9mbHVzaF9sb2dfZGlydHksDQo+ID4gICAg ICAgICAuZW5hYmxlX2xvZ19kaXJ0eV9wdF9tYXNrZWQgPSB2bXhfZW5hYmxlX2xvZ19kaXJ0eV9w dF9tYXNrZWQsDQo+ID4NCj4gPiArICAgICAgIC5wcmVfYmxvY2sgPSB2bXhfcHJlX2Jsb2NrLA0K PiA+ICsgICAgICAgLnBvc3RfYmxvY2sgPSB2bXhfcG9zdF9ibG9jaywNCj4gPiArDQo+ID4gICAg ICAgICAucG11X29wcyA9ICZpbnRlbF9wbXVfb3BzLA0KPiA+DQo+ID4gICAgICAgICAudXBkYXRl X3BpX2lydGUgPSB2bXhfdXBkYXRlX3BpX2lydGUsDQo+ID4gZGlmZiAtLWdpdCBhL2FyY2gveDg2 L2t2bS94ODYuYyBiL2FyY2gveDg2L2t2bS94ODYuYw0KPiA+IGluZGV4IDU4Njg4YWEuLjQ2ZjU1 YjIgMTAwNjQ0DQo+ID4gLS0tIGEvYXJjaC94ODYva3ZtL3g4Ni5jDQo+ID4gKysrIGIvYXJjaC94 ODYva3ZtL3g4Ni5jDQo+ID4gQEAgLTU4NjksNyArNTg2OSwxMiBAQCBpbnQga3ZtX3ZjcHVfaGFs dChzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUpDQo+ID4gIHsNCj4gPiAgICAgICAgICsrdmNwdS0+c3Rh dC5oYWx0X2V4aXRzOw0KPiA+ICAgICAgICAgaWYgKGlycWNoaXBfaW5fa2VybmVsKHZjcHUtPmt2 bSkpIHsNCj4gPiAtICAgICAgICAgICAgICAgdmNwdS0+YXJjaC5tcF9zdGF0ZSA9IEtWTV9NUF9T VEFURV9IQUxURUQ7DQo+ID4gKyAgICAgICAgICAgICAgIC8qIEhhbmRsZSBwb3N0ZWQtaW50ZXJy dXB0IHdoZW4gdkNQVSBpcyB0byBiZSBoYWx0ZWQgKi8NCj4gPiArICAgICAgICAgICAgICAgaWYg KCFrdm1feDg2X29wcy0+cHJlX2Jsb2NrIHx8DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBrdm1feDg2X29wcy0+cHJlX2Jsb2NrKHZjcHUpID09IDApIHsNCj4gPiArICAgICAg ICAgICAgICAgICAgICAgICB2Y3B1LT5hcmNoLmhhbHRlZCA9IHRydWU7DQo+ID4gKyAgICAgICAg ICAgICAgICAgICAgICAgdmNwdS0+YXJjaC5tcF9zdGF0ZSA9IEtWTV9NUF9TVEFURV9IQUxURUQ7 DQo+ID4gKyAgICAgICAgICAgICAgIH0NCj4gPiAgICAgICAgICAgICAgICAgcmV0dXJuIDE7DQo+ ID4gICAgICAgICB9IGVsc2Ugew0KPiA+ICAgICAgICAgICAgICAgICB2Y3B1LT5ydW4tPmV4aXRf cmVhc29uID0gS1ZNX0VYSVRfSExUOw0KPiA+IEBAIC02NTE4LDYgKzY1MjMsMjAgQEAgc3RhdGlj IGludCB2Y3B1X2VudGVyX2d1ZXN0KHN0cnVjdCBrdm1fdmNwdQ0KPiAqdmNwdSkNCj4gPiAgICAg ICAgICAgICAgICAgICAgICAgICBrdm1fdmNwdV9yZWxvYWRfYXBpY19hY2Nlc3NfcGFnZSh2Y3B1 KTsNCj4gPiAgICAgICAgIH0NCj4gPg0KPiA+ICsgICAgICAgLyoNCj4gPiArICAgICAgICAqIEtW TV9SRVFfRVZFTlQgaXMgbm90IHNldCB3aGVuIHBvc3RlZCBpbnRlcnJ1cHRzIGFyZSBzZXQgYnkN Cj4gPiArICAgICAgICAqIFZULWQgaGFyZHdhcmUsIHNvIHdlIGhhdmUgdG8gdXBkYXRlIFJWSSB1 bmNvbmRpdGlvbmFsbHkuDQo+ID4gKyAgICAgICAgKi8NCj4gPiArICAgICAgIGlmIChrdm1fbGFw aWNfZW5hYmxlZCh2Y3B1KSkgew0KPiA+ICsgICAgICAgICAgICAgICAvKg0KPiA+ICsgICAgICAg ICAgICAgICAgKiBVcGRhdGUgYXJjaGl0ZWN0dXJlIHNwZWNpZmljIGhpbnRzIGZvciBBUElDDQo+ ID4gKyAgICAgICAgICAgICAgICAqIHZpcnR1YWwgaW50ZXJydXB0IGRlbGl2ZXJ5Lg0KPiA+ICsg ICAgICAgICAgICAgICAgKi8NCj4gPiArICAgICAgICAgICAgICAgaWYgKGt2bV94ODZfb3BzLT5o d2FwaWNfaXJyX3VwZGF0ZSkNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBrdm1feDg2X29w cy0+aHdhcGljX2lycl91cGRhdGUodmNwdSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIGt2bV9sYXBpY19maW5kX2hpZ2hlc3RfaXJyKHZjcHUpKTsNCj4gPiArICAgICAgIH0N Cj4gPiArDQo+ID4gICAgICAgICBpZiAoa3ZtX2NoZWNrX3JlcXVlc3QoS1ZNX1JFUV9FVkVOVCwg dmNwdSkgfHwgcmVxX2ludF93aW4pIHsNCj4gPiAgICAgICAgICAgICAgICAga3ZtX2FwaWNfYWNj ZXB0X2V2ZW50cyh2Y3B1KTsNCj4gPiAgICAgICAgICAgICAgICAgaWYgKHZjcHUtPmFyY2gubXBf c3RhdGUgPT0gS1ZNX01QX1NUQVRFX0lOSVRfUkVDRUlWRUQpIHsNCj4gPiBAQCAtNjUzNCwxMyAr NjU1Myw2IEBAIHN0YXRpYyBpbnQgdmNwdV9lbnRlcl9ndWVzdChzdHJ1Y3Qga3ZtX3ZjcHUNCj4g KnZjcHUpDQo+ID4gICAgICAgICAgICAgICAgICAgICAgICAga3ZtX3g4Nl9vcHMtPmVuYWJsZV9p cnFfd2luZG93KHZjcHUpOw0KPiA+DQo+ID4gICAgICAgICAgICAgICAgIGlmIChrdm1fbGFwaWNf ZW5hYmxlZCh2Y3B1KSkgew0KPiA+IC0gICAgICAgICAgICAgICAgICAgICAgIC8qDQo+ID4gLSAg ICAgICAgICAgICAgICAgICAgICAgICogVXBkYXRlIGFyY2hpdGVjdHVyZSBzcGVjaWZpYyBoaW50 cyBmb3IgQVBJQw0KPiA+IC0gICAgICAgICAgICAgICAgICAgICAgICAqIHZpcnR1YWwgaW50ZXJy dXB0IGRlbGl2ZXJ5Lg0KPiA+IC0gICAgICAgICAgICAgICAgICAgICAgICAqLw0KPiA+IC0gICAg ICAgICAgICAgICAgICAgICAgIGlmIChrdm1feDg2X29wcy0+aHdhcGljX2lycl91cGRhdGUpDQo+ ID4gLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrdm1feDg2X29wcy0+aHdhcGljX2ly cl91cGRhdGUodmNwdSwNCj4gPiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAga3ZtX2xhcGljX2ZpbmRfaGlnaGVzdF9pcnIodmNwdSkpOw0KPiA+ICAgICAgICAgICAgICAg ICAgICAgICAgIHVwZGF0ZV9jcjhfaW50ZXJjZXB0KHZjcHUpOw0KPiA+ICAgICAgICAgICAgICAg ICAgICAgICAgIGt2bV9sYXBpY19zeW5jX3RvX3ZhcGljKHZjcHUpOw0KPiA+ICAgICAgICAgICAg ICAgICB9DQo+ID4gQEAgLTY3MTEsMTAgKzY3MjMsMzEgQEAgc3RhdGljIGludCB2Y3B1X3J1bihz dHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUpDQo+ID4NCj4gPiAgICAgICAgIGZvciAoOzspIHsNCj4gPiAg ICAgICAgICAgICAgICAgaWYgKHZjcHUtPmFyY2gubXBfc3RhdGUgPT0gS1ZNX01QX1NUQVRFX1JV Tk5BQkxFICYmDQo+ID4gLSAgICAgICAgICAgICAgICAgICAhdmNwdS0+YXJjaC5hcGYuaGFsdGVk KQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgIXZjcHUtPmFyY2guYXBmLmhhbHRlZCkgew0KPiA+ ICsgICAgICAgICAgICAgICAgICAgICAgIC8qDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg ICogRm9yIHNvbWUgY2FzZXMsIHdlIGNhbiBnZXQgaGVyZSB3aXRoDQo+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgICogdmNwdS0+YXJjaC5oYWx0ZWQgYmVpbmcgdHJ1ZS4NCj4gPiArICAgICAg ICAgICAgICAgICAgICAgICAgKi8NCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBpZiAoa3Zt X3g4Nl9vcHMtPnBvc3RfYmxvY2sgJiYgdmNwdS0+YXJjaC5oYWx0ZWQpIHsNCj4gPiArICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIGt2bV94ODZfb3BzLT5wb3N0X2Jsb2NrKHZjcHUpOw0K PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmNwdS0+YXJjaC5oYWx0ZWQgPSBm YWxzZTsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICB9DQo+ID4gKw0KPiA+ICAgICAgICAg ICAgICAgICAgICAgICAgIHIgPSB2Y3B1X2VudGVyX2d1ZXN0KHZjcHUpOw0KPiA+IC0gICAgICAg ICAgICAgICBlbHNlDQo+ID4gKyAgICAgICAgICAgICAgIH0gZWxzZSB7DQo+ID4gICAgICAgICAg ICAgICAgICAgICAgICAgciA9IHZjcHVfYmxvY2soa3ZtLCB2Y3B1KTsNCj4gPiArDQo+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgLyoNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgKiBw b3N0X2Jsb2NrKCkgbXVzdCBiZSBjYWxsZWQgYWZ0ZXINCj4gPiArICAgICAgICAgICAgICAgICAg ICAgICAgKiBwcmVfYmxvY2soKSB3aGljaCBpcyBjYWxsZWQgaW4NCj4gPiArICAgICAgICAgICAg ICAgICAgICAgICAgKiBrdm1fdmNwdV9oYWx0KCkuDQo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICovDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgaWYgKGt2bV94ODZfb3BzLT5wb3N0 X2Jsb2NrICYmIHZjcHUtPmFyY2guaGFsdGVkKSB7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBrdm1feDg2X29wcy0+cG9zdF9ibG9jayh2Y3B1KTsNCj4gPiArICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHZjcHUtPmFyY2guaGFsdGVkID0gZmFsc2U7DQo+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgfQ0KPiA+ICsgICAgICAgICAgICAgICB9DQo+ID4gKw0KPiA+ ICAgICAgICAgICAgICAgICBpZiAociA8PSAwKQ0KPiA+ICAgICAgICAgICAgICAgICAgICAgICAg IGJyZWFrOw0KPiA+DQo+ID4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgva3ZtX2hvc3QuaCBi L2luY2x1ZGUvbGludXgva3ZtX2hvc3QuaA0KPiA+IGluZGV4IGZlYmExZmIuLmJmNDYyZTcgMTAw NjQ0DQo+ID4gLS0tIGEvaW5jbHVkZS9saW51eC9rdm1faG9zdC5oDQo+ID4gKysrIGIvaW5jbHVk ZS9saW51eC9rdm1faG9zdC5oDQo+ID4gQEAgLTIzMSw2ICsyMzEsOSBAQCBzdHJ1Y3Qga3ZtX3Zj cHUgew0KPiA+ICAgICAgICAgdW5zaWduZWQgbG9uZyByZXF1ZXN0czsNCj4gPiAgICAgICAgIHVu c2lnbmVkIGxvbmcgZ3Vlc3RfZGVidWc7DQo+ID4NCj4gPiArICAgICAgIGludCBwcmVfcGNwdTsN Cj4gPiArICAgICAgIHN0cnVjdCBsaXN0X2hlYWQgYmxvY2tlZF92Y3B1X2xpc3Q7DQo+ID4gKw0K PiA+ICAgICAgICAgc3RydWN0IG11dGV4IG11dGV4Ow0KPiA+ICAgICAgICAgc3RydWN0IGt2bV9y dW4gKnJ1bjsNCj4gPg0KPiA+IGRpZmYgLS1naXQgYS92aXJ0L2t2bS9rdm1fbWFpbi5jIGIvdmly dC9rdm0va3ZtX21haW4uYw0KPiA+IGluZGV4IDhiOGE0NDQuLjE5MWM3ZWIgMTAwNjQ0DQo+ID4g LS0tIGEvdmlydC9rdm0va3ZtX21haW4uYw0KPiA+ICsrKyBiL3ZpcnQva3ZtL2t2bV9tYWluLmMN Cj4gPiBAQCAtMjIwLDYgKzIyMCw5IEBAIGludCBrdm1fdmNwdV9pbml0KHN0cnVjdCBrdm1fdmNw dSAqdmNwdSwgc3RydWN0IGt2bQ0KPiAqa3ZtLCB1bnNpZ25lZCBpZCkNCj4gPiAgICAgICAgIGlu aXRfd2FpdHF1ZXVlX2hlYWQoJnZjcHUtPndxKTsNCj4gPiAgICAgICAgIGt2bV9hc3luY19wZl92 Y3B1X2luaXQodmNwdSk7DQo+ID4NCj4gPiArICAgICAgIHZjcHUtPnByZV9wY3B1ID0gLTE7DQo+ ID4gKyAgICAgICBJTklUX0xJU1RfSEVBRCgmdmNwdS0+YmxvY2tlZF92Y3B1X2xpc3QpOw0KPiA+ ICsNCj4gPiAgICAgICAgIHBhZ2UgPSBhbGxvY19wYWdlKEdGUF9LRVJORUwgfCBfX0dGUF9aRVJP KTsNCj4gPiAgICAgICAgIGlmICghcGFnZSkgew0KPiA+ICAgICAgICAgICAgICAgICByID0gLUVO T01FTTsNCj4gPiAtLQ0KPiA+IDIuMS4wDQo+ID4NCj4gPiAtLQ0KPiA+IFRvIHVuc3Vic2NyaWJl IGZyb20gdGhpcyBsaXN0OiBzZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBrdm0iIGluDQo+ID4g dGhlIGJvZHkgb2YgYSBtZXNzYWdlIHRvIG1ham9yZG9tb0B2Z2VyLmtlcm5lbC5vcmcNCj4gPiBN b3JlIG1ham9yZG9tbyBpbmZvIGF0ICBodHRwOi8vdmdlci5rZXJuZWwub3JnL21ham9yZG9tby1p bmZvLmh0bWwNCg== -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Matlack <dmatlack@google.com> |
|---|---|
| Date | 2015-10-15 19:40 +0200 |
| Message-ID | <qjUFs-4Ty-21@gated-at.bofh.it> |
| In reply to | #1247300 |
On Wed, Oct 14, 2015 at 6:33 PM, Wu, Feng <feng.wu@intel.com> wrote:
>
>> -----Original Message-----
>> From: David Matlack [mailto:dmatlack@google.com]
>> Sent: Thursday, October 15, 2015 7:41 AM
>> To: Wu, Feng <feng.wu@intel.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>; alex.williamson@redhat.com; Joerg
>> Roedel <joro@8bytes.org>; Marcelo Tosatti <mtosatti@redhat.com>;
>> eric.auger@linaro.org; kvm list <kvm@vger.kernel.org>; iommu@lists.linux-
>> foundation.org; linux-kernel@vger.kernel.org
>> Subject: Re: [PATCH v9 17/18] KVM: Update Posted-Interrupts Descriptor when
>> vCPU is blocked
>>
>> Hi Feng.
>>
>> On Fri, Sep 18, 2015 at 7:29 AM, Feng Wu <feng.wu@intel.com> wrote:
>> > This patch updates the Posted-Interrupts Descriptor when vCPU
>> > is blocked.
>> >
>> > pre-block:
>> > - Add the vCPU to the blocked per-CPU list
>> > - Set 'NV' to POSTED_INTR_WAKEUP_VECTOR
>> >
>> > post-block:
>> > - Remove the vCPU from the per-CPU list
>>
>> I'm wondering what happens if a posted interrupt arrives at the IOMMU
>> after pre-block and before post-block.
>>
>> In pre_block, NV is set to POSTED_INTR_WAKEUP_VECTOR. IIUC, this means
>> future posted interrupts will not trigger "Posted-Interrupt Processing"
>> (PIR will not get copied to VIRR). Instead, the IOMMU will do ON := 1,
>> PIR |= (1 << vector), and send POSTED_INTR_WAKEUP_VECTOR. PIWV calls
>> wakeup_handler which does kvm_vcpu_kick. kvm_vcpu_kick does a wait-queue
>> wakeup and possibly a scheduler ipi.
>>
>> But the VCPU is sitting in kvm_vcpu_block. It spins and/or schedules
>> (wait queue) until it has a reason to wake up. I couldn't find a code
>> path from kvm_vcpu_block that lead to checking ON or PIR. How does the
>> blocked VCPU "receive" the posted interrupt? (And when does Posted-
>> Interrupt Processing get triggered?)
>
> In the pre_block, it also change the 'NDST' filed to the pCPU, on which the vCPU
> is put to the per-CPU list 'blocked_vcpu_on_cpu', so when posted-interrupts
> come it, it will sent the wakeup notification event to the pCPU above, then in
> the wakeup_handler, it can find the vCPU from the per-CPU list, hence
> kvm_vcpu_kick can wake up it.
Thank you for your response. I was actually confused about something
else. After wakeup_handler->kvm_vcpu_kick causes the vcpu to wake up,
that vcpu calls kvm_vcpu_check_block() to check if there are pending
events, otherwise the vcpu goes back to sleep. I had trouble yesterday
finding the code path from kvm_vcpu_check_block() which checks PIR/ON.
But after spending more time reading the source code this morning I
found that kvm_vcpu_check_block() eventually calls into
vmx_sync_pir_to_irr(), which copies PIR to IRR and clears ON. And then
apic_find_highest_irr() detects the pending posted interrupt.
>
> Thanks,
> Feng
>
>>
>> Thanks!
>>
>> >
>> > Signed-off-by: Feng Wu <feng.wu@intel.com>
>> > ---
>> > v9:
>> > - Add description for blocked_vcpu_on_cpu_lock in
>> Documentation/virtual/kvm/locking.txt
>> > - Check !kvm_arch_has_assigned_device(vcpu->kvm) first, then
>> > !irq_remapping_cap(IRQ_POSTING_CAP)
>> >
>> > v8:
>> > - Rename 'pi_pre_block' to 'pre_block'
>> > - Rename 'pi_post_block' to 'post_block'
>> > - Change some comments
>> > - Only add the vCPU to the blocking list when the VM has assigned devices.
>> >
>> > Documentation/virtual/kvm/locking.txt | 12 +++
>> > arch/x86/include/asm/kvm_host.h | 13 +++
>> > arch/x86/kvm/vmx.c | 153
>> ++++++++++++++++++++++++++++++++++
>> > arch/x86/kvm/x86.c | 53 +++++++++---
>> > include/linux/kvm_host.h | 3 +
>> > virt/kvm/kvm_main.c | 3 +
>> > 6 files changed, 227 insertions(+), 10 deletions(-)
>> >
>> > diff --git a/Documentation/virtual/kvm/locking.txt
>> b/Documentation/virtual/kvm/locking.txt
>> > index d68af4d..19f94a6 100644
>> > --- a/Documentation/virtual/kvm/locking.txt
>> > +++ b/Documentation/virtual/kvm/locking.txt
>> > @@ -166,3 +166,15 @@ Comment: The srcu read lock must be held while
>> accessing memslots (e.g.
>> > MMIO/PIO address->device structure mapping (kvm->buses).
>> > The srcu index can be stored in kvm_vcpu->srcu_idx per vcpu
>> > if it is needed by multiple functions.
>> > +
>> > +Name: blocked_vcpu_on_cpu_lock
>> > +Type: spinlock_t
>> > +Arch: x86
>> > +Protects: blocked_vcpu_on_cpu
>> > +Comment: This is a per-CPU lock and it is used for VT-d posted-interrupts.
>> > + When VT-d posted-interrupts is supported and the VM has assigned
>> > + devices, we put the blocked vCPU on the list blocked_vcpu_on_cpu
>> > + protected by blocked_vcpu_on_cpu_lock, when VT-d hardware
>> issues
>> > + wakeup notification event since external interrupts from the
>> > + assigned devices happens, we will find the vCPU on the list to
>> > + wakeup.
>> > diff --git a/arch/x86/include/asm/kvm_host.h
>> b/arch/x86/include/asm/kvm_host.h
>> > index 0ddd353..304fbb5 100644
>> > --- a/arch/x86/include/asm/kvm_host.h
>> > +++ b/arch/x86/include/asm/kvm_host.h
>> > @@ -552,6 +552,8 @@ struct kvm_vcpu_arch {
>> > */
>> > bool write_fault_to_shadow_pgtable;
>> >
>> > + bool halted;
>> > +
>> > /* set at EPT violation at this point */
>> > unsigned long exit_qualification;
>> >
>> > @@ -864,6 +866,17 @@ struct kvm_x86_ops {
>> > /* pmu operations of sub-arch */
>> > const struct kvm_pmu_ops *pmu_ops;
>> >
>> > + /*
>> > + * Architecture specific hooks for vCPU blocking due to
>> > + * HLT instruction.
>> > + * Returns for .pre_block():
>> > + * - 0 means continue to block the vCPU.
>> > + * - 1 means we cannot block the vCPU since some event
>> > + * happens during this period, such as, 'ON' bit in
>> > + * posted-interrupts descriptor is set.
>> > + */
>> > + int (*pre_block)(struct kvm_vcpu *vcpu);
>> > + void (*post_block)(struct kvm_vcpu *vcpu);
>> > int (*update_pi_irte)(struct kvm *kvm, unsigned int host_irq,
>> > uint32_t guest_irq, bool set);
>> > };
>> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> > index 902a67d..9968896 100644
>> > --- a/arch/x86/kvm/vmx.c
>> > +++ b/arch/x86/kvm/vmx.c
>> > @@ -879,6 +879,13 @@ static DEFINE_PER_CPU(struct vmcs *,
>> current_vmcs);
>> > static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu);
>> > static DEFINE_PER_CPU(struct desc_ptr, host_gdt);
>> >
>> > +/*
>> > + * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we
>> > + * can find which vCPU should be waken up.
>> > + */
>> > +static DEFINE_PER_CPU(struct list_head, blocked_vcpu_on_cpu);
>> > +static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock);
>> > +
>> > static unsigned long *vmx_io_bitmap_a;
>> > static unsigned long *vmx_io_bitmap_b;
>> > static unsigned long *vmx_msr_bitmap_legacy;
>> > @@ -2985,6 +2992,8 @@ static int hardware_enable(void)
>> > return -EBUSY;
>> >
>> > INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu));
>> > + INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu));
>> > + spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
>> >
>> > /*
>> > * Now we can enable the vmclear operation in kdump
>> > @@ -6121,6 +6130,25 @@ static void update_ple_window_actual_max(void)
>> > ple_window_grow, INT_MIN);
>> > }
>> >
>> > +/*
>> > + * Handler for POSTED_INTERRUPT_WAKEUP_VECTOR.
>> > + */
>> > +static void wakeup_handler(void)
>> > +{
>> > + struct kvm_vcpu *vcpu;
>> > + int cpu = smp_processor_id();
>> > +
>> > + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
>> > + list_for_each_entry(vcpu, &per_cpu(blocked_vcpu_on_cpu, cpu),
>> > + blocked_vcpu_list) {
>> > + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
>> > +
>> > + if (pi_test_on(pi_desc) == 1)
>> > + kvm_vcpu_kick(vcpu);
>> > + }
>> > + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
>> > +}
>> > +
>> > static __init int hardware_setup(void)
>> > {
>> > int r = -ENOMEM, i, msr;
>> > @@ -6305,6 +6333,8 @@ static __init int hardware_setup(void)
>> > kvm_x86_ops->enable_log_dirty_pt_masked = NULL;
>> > }
>> >
>> > + kvm_set_posted_intr_wakeup_handler(wakeup_handler);
>> > +
>> > return alloc_kvm_area();
>> >
>> > out8:
>> > @@ -10430,6 +10460,126 @@ static void
>> vmx_enable_log_dirty_pt_masked(struct kvm *kvm,
>> > }
>> >
>> > /*
>> > + * This routine does the following things for vCPU which is going
>> > + * to be blocked if VT-d PI is enabled.
>> > + * - Store the vCPU to the wakeup list, so when interrupts happen
>> > + * we can find the right vCPU to wake up.
>> > + * - Change the Posted-interrupt descriptor as below:
>> > + * 'NDST' <-- vcpu->pre_pcpu
>> > + * 'NV' <-- POSTED_INTR_WAKEUP_VECTOR
>> > + * - If 'ON' is set during this process, which means at least one
>> > + * interrupt is posted for this vCPU, we cannot block it, in
>> > + * this case, return 1, otherwise, return 0.
>> > + *
>> > + */
>> > +static int vmx_pre_block(struct kvm_vcpu *vcpu)
>> > +{
>> > + unsigned long flags;
>> > + unsigned int dest;
>> > + struct pi_desc old, new;
>> > + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
>> > +
>> > + if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
>> > + !irq_remapping_cap(IRQ_POSTING_CAP))
>> > + return 0;
>> > +
>> > + vcpu->pre_pcpu = vcpu->cpu;
>> > + spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock,
>> > + vcpu->pre_pcpu), flags);
>> > + list_add_tail(&vcpu->blocked_vcpu_list,
>> > + &per_cpu(blocked_vcpu_on_cpu,
>> > + vcpu->pre_pcpu));
>> > + spin_unlock_irqrestore(&per_cpu(blocked_vcpu_on_cpu_lock,
>> > + vcpu->pre_pcpu), flags);
>> > +
>> > + do {
>> > + old.control = new.control = pi_desc->control;
>> > +
>> > + /*
>> > + * We should not block the vCPU if
>> > + * an interrupt is posted for it.
>> > + */
>> > + if (pi_test_on(pi_desc) == 1) {
>> > + spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock,
>> > + vcpu->pre_pcpu), flags);
>> > + list_del(&vcpu->blocked_vcpu_list);
>> > + spin_unlock_irqrestore(
>> > + &per_cpu(blocked_vcpu_on_cpu_lock,
>> > + vcpu->pre_pcpu), flags);
>> > + vcpu->pre_pcpu = -1;
>> > +
>> > + return 1;
>> > + }
>> > +
>> > + WARN((pi_desc->sn == 1),
>> > + "Warning: SN field of posted-interrupts "
>> > + "is set before blocking\n");
>> > +
>> > + /*
>> > + * Since vCPU can be preempted during this process,
>> > + * vcpu->cpu could be different with pre_pcpu, we
>> > + * need to set pre_pcpu as the destination of wakeup
>> > + * notification event, then we can find the right vCPU
>> > + * to wakeup in wakeup handler if interrupts happen
>> > + * when the vCPU is in blocked state.
>> > + */
>> > + dest = cpu_physical_id(vcpu->pre_pcpu);
>> > +
>> > + if (x2apic_enabled())
>> > + new.ndst = dest;
>> > + else
>> > + new.ndst = (dest << 8) & 0xFF00;
>> > +
>> > + /* set 'NV' to 'wakeup vector' */
>> > + new.nv = POSTED_INTR_WAKEUP_VECTOR;
>> > + } while (cmpxchg(&pi_desc->control, old.control,
>> > + new.control) != old.control);
>> > +
>> > + return 0;
>> > +}
>> > +
>> > +static void vmx_post_block(struct kvm_vcpu *vcpu)
>> > +{
>> > + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
>> > + struct pi_desc old, new;
>> > + unsigned int dest;
>> > + unsigned long flags;
>> > +
>> > + if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
>> > + !irq_remapping_cap(IRQ_POSTING_CAP))
>> > + return;
>> > +
>> > + do {
>> > + old.control = new.control = pi_desc->control;
>> > +
>> > + dest = cpu_physical_id(vcpu->cpu);
>> > +
>> > + if (x2apic_enabled())
>> > + new.ndst = dest;
>> > + else
>> > + new.ndst = (dest << 8) & 0xFF00;
>> > +
>> > + /* Allow posting non-urgent interrupts */
>> > + new.sn = 0;
>> > +
>> > + /* set 'NV' to 'notification vector' */
>> > + new.nv = POSTED_INTR_VECTOR;
>> > + } while (cmpxchg(&pi_desc->control, old.control,
>> > + new.control) != old.control);
>> > +
>> > + if(vcpu->pre_pcpu != -1) {
>> > + spin_lock_irqsave(
>> > + &per_cpu(blocked_vcpu_on_cpu_lock,
>> > + vcpu->pre_pcpu), flags);
>> > + list_del(&vcpu->blocked_vcpu_list);
>> > + spin_unlock_irqrestore(
>> > + &per_cpu(blocked_vcpu_on_cpu_lock,
>> > + vcpu->pre_pcpu), flags);
>> > + vcpu->pre_pcpu = -1;
>> > + }
>> > +}
>> > +
>> > +/*
>> > * vmx_update_pi_irte - set IRTE for Posted-Interrupts
>> > *
>> > * @kvm: kvm
>> > @@ -10620,6 +10770,9 @@ static struct kvm_x86_ops vmx_x86_ops = {
>> > .flush_log_dirty = vmx_flush_log_dirty,
>> > .enable_log_dirty_pt_masked = vmx_enable_log_dirty_pt_masked,
>> >
>> > + .pre_block = vmx_pre_block,
>> > + .post_block = vmx_post_block,
>> > +
>> > .pmu_ops = &intel_pmu_ops,
>> >
>> > .update_pi_irte = vmx_update_pi_irte,
>> > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
>> > index 58688aa..46f55b2 100644
>> > --- a/arch/x86/kvm/x86.c
>> > +++ b/arch/x86/kvm/x86.c
>> > @@ -5869,7 +5869,12 @@ int kvm_vcpu_halt(struct kvm_vcpu *vcpu)
>> > {
>> > ++vcpu->stat.halt_exits;
>> > if (irqchip_in_kernel(vcpu->kvm)) {
>> > - vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
>> > + /* Handle posted-interrupt when vCPU is to be halted */
>> > + if (!kvm_x86_ops->pre_block ||
>> > + kvm_x86_ops->pre_block(vcpu) == 0) {
>> > + vcpu->arch.halted = true;
>> > + vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
>> > + }
>> > return 1;
>> > } else {
>> > vcpu->run->exit_reason = KVM_EXIT_HLT;
>> > @@ -6518,6 +6523,20 @@ static int vcpu_enter_guest(struct kvm_vcpu
>> *vcpu)
>> > kvm_vcpu_reload_apic_access_page(vcpu);
>> > }
>> >
>> > + /*
>> > + * KVM_REQ_EVENT is not set when posted interrupts are set by
>> > + * VT-d hardware, so we have to update RVI unconditionally.
>> > + */
>> > + if (kvm_lapic_enabled(vcpu)) {
>> > + /*
>> > + * Update architecture specific hints for APIC
>> > + * virtual interrupt delivery.
>> > + */
>> > + if (kvm_x86_ops->hwapic_irr_update)
>> > + kvm_x86_ops->hwapic_irr_update(vcpu,
>> > + kvm_lapic_find_highest_irr(vcpu));
>> > + }
>> > +
>> > if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
>> > kvm_apic_accept_events(vcpu);
>> > if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) {
>> > @@ -6534,13 +6553,6 @@ static int vcpu_enter_guest(struct kvm_vcpu
>> *vcpu)
>> > kvm_x86_ops->enable_irq_window(vcpu);
>> >
>> > if (kvm_lapic_enabled(vcpu)) {
>> > - /*
>> > - * Update architecture specific hints for APIC
>> > - * virtual interrupt delivery.
>> > - */
>> > - if (kvm_x86_ops->hwapic_irr_update)
>> > - kvm_x86_ops->hwapic_irr_update(vcpu,
>> > - kvm_lapic_find_highest_irr(vcpu));
>> > update_cr8_intercept(vcpu);
>> > kvm_lapic_sync_to_vapic(vcpu);
>> > }
>> > @@ -6711,10 +6723,31 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
>> >
>> > for (;;) {
>> > if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
>> > - !vcpu->arch.apf.halted)
>> > + !vcpu->arch.apf.halted) {
>> > + /*
>> > + * For some cases, we can get here with
>> > + * vcpu->arch.halted being true.
>> > + */
>> > + if (kvm_x86_ops->post_block && vcpu->arch.halted) {
>> > + kvm_x86_ops->post_block(vcpu);
>> > + vcpu->arch.halted = false;
>> > + }
>> > +
>> > r = vcpu_enter_guest(vcpu);
>> > - else
>> > + } else {
>> > r = vcpu_block(kvm, vcpu);
>> > +
>> > + /*
>> > + * post_block() must be called after
>> > + * pre_block() which is called in
>> > + * kvm_vcpu_halt().
>> > + */
>> > + if (kvm_x86_ops->post_block && vcpu->arch.halted) {
>> > + kvm_x86_ops->post_block(vcpu);
>> > + vcpu->arch.halted = false;
>> > + }
>> > + }
>> > +
>> > if (r <= 0)
>> > break;
>> >
>> > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
>> > index feba1fb..bf462e7 100644
>> > --- a/include/linux/kvm_host.h
>> > +++ b/include/linux/kvm_host.h
>> > @@ -231,6 +231,9 @@ struct kvm_vcpu {
>> > unsigned long requests;
>> > unsigned long guest_debug;
>> >
>> > + int pre_pcpu;
>> > + struct list_head blocked_vcpu_list;
>> > +
>> > struct mutex mutex;
>> > struct kvm_run *run;
>> >
>> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
>> > index 8b8a444..191c7eb 100644
>> > --- a/virt/kvm/kvm_main.c
>> > +++ b/virt/kvm/kvm_main.c
>> > @@ -220,6 +220,9 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm
>> *kvm, unsigned id)
>> > init_waitqueue_head(&vcpu->wq);
>> > kvm_async_pf_vcpu_init(vcpu);
>> >
>> > + vcpu->pre_pcpu = -1;
>> > + INIT_LIST_HEAD(&vcpu->blocked_vcpu_list);
>> > +
>> > page = alloc_page(GFP_KERNEL | __GFP_ZERO);
>> > if (!page) {
>> > r = -ENOMEM;
>> > --
>> > 2.1.0
>> >
>> > --
>> > To unsubscribe from this list: send the line "unsubscribe kvm" in
>> > the body of a message to majordomo@vger.kernel.org
>> > More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2015-10-15 20:20 +0200 |
| Message-ID | <qjVib-5Uv-15@gated-at.bofh.it> |
| In reply to | #1248036 |
On 15/10/2015 19:39, David Matlack wrote:
> But after spending more time reading the source code this morning I
> found that kvm_vcpu_check_block() eventually calls into
> vmx_sync_pir_to_irr(), which copies PIR to IRR and clears ON. And then
> apic_find_highest_irr() detects the pending posted interrupt.
Right. And related to this, Feng, can you check if this is still
necessary on kvm/queue:
@@ -6518,6 +6523,20 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
kvm_vcpu_reload_apic_access_page(vcpu);
}
+ /*
+ * KVM_REQ_EVENT is not set when posted interrupts are set by
+ * VT-d hardware, so we have to update RVI unconditionally.
+ */
+ if (kvm_lapic_enabled(vcpu)) {
+ /*
+ * Update architecture specific hints for APIC
+ * virtual interrupt delivery.
+ */
+ if (kvm_x86_ops->hwapic_irr_update)
+ kvm_x86_ops->hwapic_irr_update(vcpu,
+ kvm_lapic_find_highest_irr(vcpu));
+ }
+
if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
kvm_apic_accept_events(vcpu);
if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) {
@@ -6534,13 +6553,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
kvm_x86_ops->enable_irq_window(vcpu);
if (kvm_lapic_enabled(vcpu)) {
- /*
- * Update architecture specific hints for APIC
- * virtual interrupt delivery.
- */
- if (kvm_x86_ops->hwapic_irr_update)
- kvm_x86_ops->hwapic_irr_update(vcpu,
- kvm_lapic_find_highest_irr(vcpu));
update_cr8_intercept(vcpu);
kvm_lapic_sync_to_vapic(vcpu);
}
It may be obsolete now that we have the patch from Radim to set KVM_REQ_EVENT
in vmx_sync_pir_to_irr (http://permalink.gmane.org/gmane.linux.kernel/2057138).
Thanks,
Paolo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Wu, Feng" <feng.wu@intel.com> |
|---|---|
| Date | 2015-10-16 03:50 +0200 |
| Message-ID | <qk2jD-85Q-7@gated-at.bofh.it> |
| In reply to | #1248059 |
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogUGFvbG8gQm9uemluaSBb bWFpbHRvOnBhb2xvLmJvbnppbmlAZ21haWwuY29tXSBPbiBCZWhhbGYgT2YgUGFvbG8NCj4gQm9u emluaQ0KPiBTZW50OiBGcmlkYXksIE9jdG9iZXIgMTYsIDIwMTUgMjoxMyBBTQ0KPiBUbzogRGF2 aWQgTWF0bGFjayA8ZG1hdGxhY2tAZ29vZ2xlLmNvbT47IFd1LCBGZW5nIDxmZW5nLnd1QGludGVs LmNvbT4NCj4gQ2M6IGFsZXgud2lsbGlhbXNvbkByZWRoYXQuY29tOyBKb2VyZyBSb2VkZWwgPGpv cm9AOGJ5dGVzLm9yZz47IE1hcmNlbG8NCj4gVG9zYXR0aSA8bXRvc2F0dGlAcmVkaGF0LmNvbT47 IGVyaWMuYXVnZXJAbGluYXJvLm9yZzsga3ZtIGxpc3QNCj4gPGt2bUB2Z2VyLmtlcm5lbC5vcmc+ OyBpb21tdUBsaXN0cy5saW51eC1mb3VuZGF0aW9uLm9yZzsgbGludXgtDQo+IGtlcm5lbEB2Z2Vy Lmtlcm5lbC5vcmcNCj4gU3ViamVjdDogUmU6IFtQQVRDSCB2OSAxNy8xOF0gS1ZNOiBVcGRhdGUg UG9zdGVkLUludGVycnVwdHMgRGVzY3JpcHRvciB3aGVuDQo+IHZDUFUgaXMgYmxvY2tlZA0KPiAN Cj4gDQo+IA0KPiBPbiAxNS8xMC8yMDE1IDE5OjM5LCBEYXZpZCBNYXRsYWNrIHdyb3RlOg0KPiA+ IEJ1dCBhZnRlciBzcGVuZGluZyBtb3JlIHRpbWUgcmVhZGluZyB0aGUgc291cmNlIGNvZGUgdGhp cyBtb3JuaW5nIEkNCj4gPiBmb3VuZCB0aGF0IGt2bV92Y3B1X2NoZWNrX2Jsb2NrKCkgZXZlbnR1 YWxseSBjYWxscyBpbnRvDQo+ID4gdm14X3N5bmNfcGlyX3RvX2lycigpLCB3aGljaCBjb3BpZXMg UElSIHRvIElSUiBhbmQgY2xlYXJzIE9OLiBBbmQgdGhlbg0KPiA+IGFwaWNfZmluZF9oaWdoZXN0 X2lycigpIGRldGVjdHMgdGhlIHBlbmRpbmcgcG9zdGVkIGludGVycnVwdC4NCj4gDQo+IFJpZ2h0 LiAgQW5kIHJlbGF0ZWQgdG8gdGhpcywgRmVuZywgY2FuIHlvdSBjaGVjayBpZiB0aGlzIGlzIHN0 aWxsDQo+IG5lY2Vzc2FyeSBvbiBrdm0vcXVldWU6DQo+IA0KPiBAQCAtNjUxOCw2ICs2NTIzLDIw IEBAIHN0YXRpYyBpbnQgdmNwdV9lbnRlcl9ndWVzdChzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUpDQo+ ICAJCQlrdm1fdmNwdV9yZWxvYWRfYXBpY19hY2Nlc3NfcGFnZSh2Y3B1KTsNCj4gIAl9DQo+IA0K PiArCS8qDQo+ICsJICogS1ZNX1JFUV9FVkVOVCBpcyBub3Qgc2V0IHdoZW4gcG9zdGVkIGludGVy cnVwdHMgYXJlIHNldCBieQ0KPiArCSAqIFZULWQgaGFyZHdhcmUsIHNvIHdlIGhhdmUgdG8gdXBk YXRlIFJWSSB1bmNvbmRpdGlvbmFsbHkuDQo+ICsJICovDQo+ICsJaWYgKGt2bV9sYXBpY19lbmFi bGVkKHZjcHUpKSB7DQo+ICsJCS8qDQo+ICsJCSAqIFVwZGF0ZSBhcmNoaXRlY3R1cmUgc3BlY2lm aWMgaGludHMgZm9yIEFQSUMNCj4gKwkJICogdmlydHVhbCBpbnRlcnJ1cHQgZGVsaXZlcnkuDQo+ ICsJCSAqLw0KPiArCQlpZiAoa3ZtX3g4Nl9vcHMtPmh3YXBpY19pcnJfdXBkYXRlKQ0KPiArCQkJ a3ZtX3g4Nl9vcHMtPmh3YXBpY19pcnJfdXBkYXRlKHZjcHUsDQo+ICsJCQkJa3ZtX2xhcGljX2Zp bmRfaGlnaGVzdF9pcnIodmNwdSkpOw0KPiArCX0NCj4gKw0KPiAgCWlmIChrdm1fY2hlY2tfcmVx dWVzdChLVk1fUkVRX0VWRU5ULCB2Y3B1KSB8fCByZXFfaW50X3dpbikgew0KPiAgCQlrdm1fYXBp Y19hY2NlcHRfZXZlbnRzKHZjcHUpOw0KPiAgCQlpZiAodmNwdS0+YXJjaC5tcF9zdGF0ZSA9PSBL Vk1fTVBfU1RBVEVfSU5JVF9SRUNFSVZFRCkgew0KPiBAQCAtNjUzNCwxMyArNjU1Myw2IEBAIHN0 YXRpYyBpbnQgdmNwdV9lbnRlcl9ndWVzdChzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUpDQo+ICAJCQlr dm1feDg2X29wcy0+ZW5hYmxlX2lycV93aW5kb3codmNwdSk7DQo+IA0KPiAgCQlpZiAoa3ZtX2xh cGljX2VuYWJsZWQodmNwdSkpIHsNCj4gLQkJCS8qDQo+IC0JCQkgKiBVcGRhdGUgYXJjaGl0ZWN0 dXJlIHNwZWNpZmljIGhpbnRzIGZvciBBUElDDQo+IC0JCQkgKiB2aXJ0dWFsIGludGVycnVwdCBk ZWxpdmVyeS4NCj4gLQkJCSAqLw0KPiAtCQkJaWYgKGt2bV94ODZfb3BzLT5od2FwaWNfaXJyX3Vw ZGF0ZSkNCj4gLQkJCQlrdm1feDg2X29wcy0+aHdhcGljX2lycl91cGRhdGUodmNwdSwNCj4gLQkJ CQkJa3ZtX2xhcGljX2ZpbmRfaGlnaGVzdF9pcnIodmNwdSkpOw0KPiAgCQkJdXBkYXRlX2NyOF9p bnRlcmNlcHQodmNwdSk7DQo+ICAJCQlrdm1fbGFwaWNfc3luY190b192YXBpYyh2Y3B1KTsNCj4g IAkJfQ0KPiANCg0KSSB0aGluayB0aGUgYWJvdmUgY29kZSBpcyBuZWVkZWQsIGJlZm9yZSB0aGUg cGxhY2Ugd2hlcmUgJ0tWTV9SRVFfRVZFTlQnDQpnb3QgY2hlY2tlZCBpbiB2Y3B1X2VudGVyX2d1 ZXN0KCksIFZULWQgaGFyZHdhcmUgY2FuIGlzc3VlIG5vdGlmaWNhdGlvbg0KZXZlbnQgYXQgYW55 IHRpbWUuIENvbnNpZGVyIHRoZSBmb2xsb3dpbmcgc2NlbmFyaW86DQoNCnZjcHVfcnVuKCkNCnsN CgkuLi4uLi4JDQoJDQoJZm9yKDs7KSB7DQoJCXBvaW50ICMxDQoJCXZjcHVfZW50ZXJfZ3Vlc3Qo KQ0KCX0JDQoNCglwb2ludCAjMg0KfQ0KDQpGb3IgZXhhbXBsZSwgaWYgd2UgcmVjZWl2ZSBub3Rp ZmljYXRpb24gZXZlbnRzIGlzc3VlZCBieSBWVC1kIGhhcmR3YXJlIGF0DQpwb2ludCAjMSBhbmQg cG9pbnQjMiwgdGhlbiBlbnRlciB2Y3B1X2VudGVyX2d1ZXN0KCkgd2l0aCAnS1ZNX1JFUV9FVkVO VCcNCm5vdCBzZXQsIHRoZSBpbnRlcnJ1cHRzIGNhbm5vdCBiZSBkZWxpdmVyZWQgdG8gZ3Vlc3Qg ZHVyaW5nIF90aGlzXyBWTS1FbnRyeS4NCg0KVGhlIHBvaW50IGlzIHRoYXQgVlQtZCBoYXJkd2Fy ZSBjYW4gaXNzdWUgbm90aWZpY2F0aW9uIGV2ZW50IGF0IGFueSB0aW1lLA0KYnV0IGl0IGNhbm5v dCBzZXQgJ0tWTV9SRVFfRVZFTlQnIGxpa2Ugc29mdHdhcmUgZG9lcy4NCg0KTWF5YmUgb25lIHRo aW5nIHdlIGNhbiBkbyBpcyBvbmx5IGV4ZWN1dGluZyB0aGUgZm9sbG93aW5nIGNvZGUgd2hlbg0K dnQtZCBwaSBpcyBlbmFibGVkLA0KDQogKwkvKg0KICsJICogS1ZNX1JFUV9FVkVOVCBpcyBub3Qg c2V0IHdoZW4gcG9zdGVkIGludGVycnVwdHMgYXJlIHNldCBieQ0KICsJICogVlQtZCBoYXJkd2Fy ZSwgc28gd2UgaGF2ZSB0byB1cGRhdGUgUlZJIHVuY29uZGl0aW9uYWxseS4NCiArCSAqLw0KICsJ aWYgKGt2bV9sYXBpY19lbmFibGVkKHZjcHUpKSB7DQogKwkJLyoNCiArCQkgKiBVcGRhdGUgYXJj aGl0ZWN0dXJlIHNwZWNpZmljIGhpbnRzIGZvciBBUElDDQogKwkJICogdmlydHVhbCBpbnRlcnJ1 cHQgZGVsaXZlcnkuDQogKwkJICovDQogKwkJaWYgKGt2bV94ODZfb3BzLT5od2FwaWNfaXJyX3Vw ZGF0ZSkNCiArCQkJa3ZtX3g4Nl9vcHMtPmh3YXBpY19pcnJfdXBkYXRlKHZjcHUsDQogKwkJCQlr dm1fbGFwaWNfZmluZF9oaWdoZXN0X2lycih2Y3B1KSk7DQogKwl9DQogKw0KDQpBbmQgZG8gdGhp cyBpbnNpZGUgdGhlIEtWTV9SRVFfRVZFTlQgY2hlY2sgd2hlbiBWVC1kIFBJIGlzIG5vdCBlbmFi bGVkLg0KDQpUaGFua3MsDQpGZW5nDQoNCj4gDQo+IEl0IG1heSBiZSBvYnNvbGV0ZSBub3cgdGhh dCB3ZSBoYXZlIHRoZSBwYXRjaCBmcm9tIFJhZGltIHRvIHNldA0KPiBLVk1fUkVRX0VWRU5UDQo+ IGluIHZteF9zeW5jX3Bpcl90b19pcnINCj4gKGh0dHA6Ly9wZXJtYWxpbmsuZ21hbmUub3JnL2dt YW5lLmxpbnV4Lmtlcm5lbC8yMDU3MTM4KS4NCj4gDQo+IFRoYW5rcywNCj4gDQo+IFBhb2xvDQo= -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web