€•¯¯Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ*/translations/zh_CN/virt/kvm/vcpu-requests”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/zh_TW/virt/kvm/vcpu-requests”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/it_IT/virt/kvm/vcpu-requests”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/ja_JP/virt/kvm/vcpu-requests”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/ko_KR/virt/kvm/vcpu-requests”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/pt_BR/virt/kvm/vcpu-requests”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/sp_SP/virt/kvm/vcpu-requests”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…””}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒD/var/lib/git/docbuild/linux/Documentation/virt/kvm/vcpu-requests.rst”h´KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒKVM VCPU Requests”h]”hŒKVM VCPU Requests”…””}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒOverview”h]”hŒOverview”…””}”(hhàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÝh²hh³hÇh´KubhŒ paragraph”“”)”}”(hŒßKVM supports an internal API enabling threads to request a VCPU thread to perform some activity. For example, a thread may request a VCPU to flush its TLB with a VCPU request. The API consists of the following functions::”h]”hŒÞKVM supports an internal API enabling threads to request a VCPU thread to perform some activity. For example, a thread may request a VCPU to flush its TLB with a VCPU request. The API consists of the following functions:”…””}”(hhðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K hhÝh²hubhŒ literal_block”“”)”}”(hX‰/* Check if any requests are pending for VCPU @vcpu. */ bool kvm_request_pending(struct kvm_vcpu *vcpu); /* Check if VCPU @vcpu has request @req pending. */ bool kvm_test_request(int req, struct kvm_vcpu *vcpu); /* Clear request @req for VCPU @vcpu. */ void kvm_clear_request(int req, struct kvm_vcpu *vcpu); /* * Check if VCPU @vcpu has request @req pending. When the request is * pending it will be cleared and a memory barrier, which pairs with * another in kvm_make_request(), will be issued. */ bool kvm_check_request(int req, struct kvm_vcpu *vcpu); /* * Make request @req of VCPU @vcpu. Issues a memory barrier, which pairs * with another in kvm_check_request(), prior to setting the request. */ void kvm_make_request(int req, struct kvm_vcpu *vcpu); /* Make request @req of all VCPUs of the VM with struct kvm @kvm. */ bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);”h]”hX‰/* Check if any requests are pending for VCPU @vcpu. */ bool kvm_request_pending(struct kvm_vcpu *vcpu); /* Check if VCPU @vcpu has request @req pending. */ bool kvm_test_request(int req, struct kvm_vcpu *vcpu); /* Clear request @req for VCPU @vcpu. */ void kvm_clear_request(int req, struct kvm_vcpu *vcpu); /* * Check if VCPU @vcpu has request @req pending. When the request is * pending it will be cleared and a memory barrier, which pairs with * another in kvm_make_request(), will be issued. */ bool kvm_check_request(int req, struct kvm_vcpu *vcpu); /* * Make request @req of VCPU @vcpu. Issues a memory barrier, which pairs * with another in kvm_check_request(), prior to setting the request. */ void kvm_make_request(int req, struct kvm_vcpu *vcpu); /* Make request @req of all VCPUs of the VM with struct kvm @kvm. */ bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1hþh³hÇh´KhhÝh²hubhï)”}”(hXTypically a requester wants the VCPU to perform the activity as soon as possible after making the request. This means most requests (kvm_make_request() calls) are followed by a call to kvm_vcpu_kick(), and kvm_make_all_cpus_request() has the kicking of all VCPUs built into it.”h]”hXTypically a requester wants the VCPU to perform the activity as soon as possible after making the request. This means most requests (kvm_make_request() calls) are followed by a call to kvm_vcpu_kick(), and kvm_make_all_cpus_request() has the kicking of all VCPUs built into it.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K'hhÝh²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒ VCPU Kicks”h]”hŒ VCPU Kicks”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´K.ubhï)”}”(hXThe goal of a VCPU kick is to bring a VCPU thread out of guest mode in order to perform some KVM maintenance. To do so, an IPI is sent, forcing a guest mode exit. However, a VCPU thread may not be in guest mode at the time of the kick. Therefore, depending on the mode and state of the VCPU thread, there are two other actions a kick may take. All three actions are listed below:”h]”hXThe goal of a VCPU kick is to bring a VCPU thread out of guest mode in order to perform some KVM maintenance. To do so, an IPI is sent, forcing a guest mode exit. However, a VCPU thread may not be in guest mode at the time of the kick. Therefore, depending on the mode and state of the VCPU thread, there are two other actions a kick may take. All three actions are listed below:”…””}”(hj-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K0hjh²hubhŒenumerated_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒ,Send an IPI. This forces a guest mode exit.”h]”hï)”}”(hjDh]”hŒ,Send an IPI. This forces a guest mode exit.”…””}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K7hjBubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj=h²hh³hÇh´NubjA)”}”(hXWaking a sleeping VCPU. Sleeping VCPUs are VCPU threads outside guest mode that wait on waitqueues. Waking them removes the threads from the waitqueues, allowing the threads to run again. This behavior may be suppressed, see KVM_REQUEST_NO_WAKEUP below.”h]”hï)”}”(hXWaking a sleeping VCPU. Sleeping VCPUs are VCPU threads outside guest mode that wait on waitqueues. Waking them removes the threads from the waitqueues, allowing the threads to run again. This behavior may be suppressed, see KVM_REQUEST_NO_WAKEUP below.”h]”hXWaking a sleeping VCPU. Sleeping VCPUs are VCPU threads outside guest mode that wait on waitqueues. Waking them removes the threads from the waitqueues, allowing the threads to run again. This behavior may be suppressed, see KVM_REQUEST_NO_WAKEUP below.”…””}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K8hjYubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj=h²hh³hÇh´NubjA)”}”(hŒoNothing. When the VCPU is not in guest mode and the VCPU thread is not sleeping, then there is nothing to do. ”h]”hï)”}”(hŒnNothing. When the VCPU is not in guest mode and the VCPU thread is not sleeping, then there is nothing to do.”h]”hŒnNothing. When the VCPU is not in guest mode and the VCPU thread is not sleeping, then there is nothing to do.”…””}”(hjuh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kmode``, that is used to track whether the guest is running in guest mode or not, as well as some specific outside guest mode states. The architecture may use ``vcpu->mode`` to ensure VCPU requests are seen by VCPUs (see "Ensuring Requests Are Seen"), as well as to avoid sending unnecessary IPIs (see "IPI Reduction"), and even to ensure IPI acknowledgements are waited upon (see "Waiting for Acknowledgements"). The following modes are defined:”h]”(hŒVCPUs have a mode state, ”…””}”(hj­h²hh³Nh´NubhŒliteral”“”)”}”(hŒ``vcpu->mode``”h]”hŒ vcpu->mode”…””}”(hj·h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhj­ubhŒ™, that is used to track whether the guest is running in guest mode or not, as well as some specific outside guest mode states. The architecture may use ”…””}”(hj­h²hh³Nh´Nubj¶)”}”(hŒ``vcpu->mode``”h]”hŒ vcpu->mode”…””}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhj­ubhX to ensure VCPU requests are seen by VCPUs (see “Ensuring Requests Are Seenâ€), as well as to avoid sending unnecessary IPIs (see “IPI Reductionâ€), and even to ensure IPI acknowledgements are waited upon (see “Waiting for Acknowledgementsâ€). The following modes are defined:”…””}”(hj­h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KBhjœh²hubhï)”}”(hŒOUTSIDE_GUEST_MODE”h]”hŒOUTSIDE_GUEST_MODE”…””}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KJhjœh²hubhŒ block_quote”“”)”}”(hŒ'The VCPU thread is outside guest mode. ”h]”hï)”}”(hŒ&The VCPU thread is outside guest mode.”h]”hŒ&The VCPU thread is outside guest mode.”…””}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KLhjñubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´KLhjœh²hubhï)”}”(hŒ IN_GUEST_MODE”h]”hŒ IN_GUEST_MODE”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KNhjœh²hubjð)”}”(hŒ"The VCPU thread is in guest mode. ”h]”hï)”}”(hŒ!The VCPU thread is in guest mode.”h]”hŒ!The VCPU thread is in guest mode.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KPhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´KPhjœh²hubhï)”}”(hŒEXITING_GUEST_MODE”h]”hŒEXITING_GUEST_MODE”…””}”(hj/h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KRhjœh²hubjð)”}”(hŒKThe VCPU thread is transitioning from IN_GUEST_MODE to OUTSIDE_GUEST_MODE. ”h]”hï)”}”(hŒJThe VCPU thread is transitioning from IN_GUEST_MODE to OUTSIDE_GUEST_MODE.”h]”hŒJThe VCPU thread is transitioning from IN_GUEST_MODE to OUTSIDE_GUEST_MODE.”…””}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KThj=ubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´KThjœh²hubhï)”}”(hŒREADING_SHADOW_PAGE_TABLES”h]”hŒREADING_SHADOW_PAGE_TABLES”…””}”(hjUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KWhjœh²hubjð)”}”(hŒ²The VCPU thread is outside guest mode, but it wants the sender of certain VCPU requests, namely KVM_REQ_TLB_FLUSH, to wait until the VCPU thread is done reading the page tables. ”h]”hï)”}”(hŒ±The VCPU thread is outside guest mode, but it wants the sender of certain VCPU requests, namely KVM_REQ_TLB_FLUSH, to wait until the VCPU thread is done reading the page tables.”h]”hŒ±The VCPU thread is outside guest mode, but it wants the sender of certain VCPU requests, namely KVM_REQ_TLB_FLUSH, to wait until the VCPU thread is done reading the page tables.”…””}”(hjgh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KYhjcubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´KYhjœh²hubeh}”(h]”Œ vcpu-mode”ah ]”h"]”Œ vcpu mode”ah$]”h&]”uh1hÈhhÝh²hh³hÇh´K@ubeh}”(h]”Œoverview”ah ]”h"]”Œoverview”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒVCPU Request Internals”h]”hŒVCPU Request Internals”…””}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj‹h²hh³hÇh´K^ubhï)”}”(hŒ¤VCPU requests are simply bit indices of the ``vcpu->requests`` bitmap. This means general bitops, like those documented in [atomic-ops]_ could also be used, e.g. ::”h]”(hŒ,VCPU requests are simply bit indices of the ”…””}”(hjœh²hh³Nh´Nubj¶)”}”(hŒ``vcpu->requests``”h]”hŒvcpu->requests”…””}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhjœubhŒ= bitmap. This means general bitops, like those documented in ”…””}”(hjœh²hh³Nh´Nubh)”}”(hŒ atomic-ops”h]”hŒinline”“”)”}”(hj¸h]”hŒ [atomic-ops]”…””}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jºhj¶ubah}”(h]”Œid1”ah ]”h"]”h$]”h&]”Œ refdomain”Œcitation”Œreftype”Œref”Œ reftarget”j¸Œrefwarn”ˆŒsupport_smartquotes”‰uh1hh³hÇh´K`hjœh²hubhŒ could also be used, e.g.”…””}”(hjœh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K`hj‹h²hubhÿ)”}”(hŒ?clear_bit(KVM_REQ_UNBLOCK & KVM_REQUEST_MASK, &vcpu->requests);”h]”hŒ?clear_bit(KVM_REQ_UNBLOCK & KVM_REQUEST_MASK, &vcpu->requests);”…””}”hjásbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1hþh³hÇh´Kdhj‹h²hubhï)”}”(hŒéHowever, VCPU request users should refrain from doing so, as it would break the abstraction. The first 8 bits are reserved for architecture independent requests; all additional bits are available for architecture dependent requests.”h]”hŒéHowever, VCPU request users should refrain from doing so, as it would break the abstraction. The first 8 bits are reserved for architecture independent requests; all additional bits are available for architecture dependent requests.”…””}”(hjïh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kfhj‹h²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒ!Architecture Independent Requests”h]”hŒ!Architecture Independent Requests”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjýh²hh³hÇh´Klubhï)”}”(hŒKVM_REQ_TLB_FLUSH”h]”hŒKVM_REQ_TLB_FLUSH”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Knhjýh²hubjð)”}”(hŒïKVM's common MMU notifier may need to flush all of a guest's TLB entries, calling kvm_flush_remote_tlbs() to do so. Architectures that choose to use the common kvm_flush_remote_tlbs() implementation will need to handle this VCPU request. ”h]”hï)”}”(hŒîKVM's common MMU notifier may need to flush all of a guest's TLB entries, calling kvm_flush_remote_tlbs() to do so. Architectures that choose to use the common kvm_flush_remote_tlbs() implementation will need to handle this VCPU request.”h]”hŒòKVM’s common MMU notifier may need to flush all of a guest’s TLB entries, calling kvm_flush_remote_tlbs() to do so. Architectures that choose to use the common kvm_flush_remote_tlbs() implementation will need to handle this VCPU request.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kphjubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´Kphjýh²hubhï)”}”(hŒKVM_REQ_VM_DEAD”h]”hŒKVM_REQ_VM_DEAD”…””}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kuhjýh²hubjð)”}”(hŒ•This request informs all VCPUs that the VM is dead and unusable, e.g. due to fatal error or because the VM's state has been intentionally destroyed. ”h]”hï)”}”(hŒ”This request informs all VCPUs that the VM is dead and unusable, e.g. due to fatal error or because the VM's state has been intentionally destroyed.”h]”hŒ–This request informs all VCPUs that the VM is dead and unusable, e.g. due to fatal error or because the VM’s state has been intentionally destroyed.”…””}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KwhjBubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´Kwhjýh²hubhï)”}”(hŒKVM_REQ_UNBLOCK”h]”hŒKVM_REQ_UNBLOCK”…””}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kzhjýh²hubjð)”}”(hŒðThis request informs the vCPU to exit kvm_vcpu_block. It is used for example from timer handlers that run on the host on behalf of a vCPU, or in order to update the interrupt routing and ensure that assigned devices will wake up the vCPU. ”h]”hï)”}”(hŒïThis request informs the vCPU to exit kvm_vcpu_block. It is used for example from timer handlers that run on the host on behalf of a vCPU, or in order to update the interrupt routing and ensure that assigned devices will wake up the vCPU.”h]”hŒïThis request informs the vCPU to exit kvm_vcpu_block. It is used for example from timer handlers that run on the host on behalf of a vCPU, or in order to update the interrupt routing and ensure that assigned devices will wake up the vCPU.”…””}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K|hjhubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´K|hjýh²hubhï)”}”(hŒKVM_REQ_OUTSIDE_GUEST_MODE”h]”hŒKVM_REQ_OUTSIDE_GUEST_MODE”…””}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Khjýh²hubjð)”}”(hXThis "request" ensures the target vCPU has exited guest mode prior to the sender of the request continuing on. No action needs be taken by the target, and so no request is actually logged for the target. This request is similar to a "kick", but unlike a kick it guarantees the vCPU has actually exited guest mode. A kick only guarantees the vCPU will exit at some point in the future, e.g. a previous kick may have started the process, but there's no guarantee the to-be-kicked vCPU has fully exited guest mode. ”h]”hï)”}”(hXThis "request" ensures the target vCPU has exited guest mode prior to the sender of the request continuing on. No action needs be taken by the target, and so no request is actually logged for the target. This request is similar to a "kick", but unlike a kick it guarantees the vCPU has actually exited guest mode. A kick only guarantees the vCPU will exit at some point in the future, e.g. a previous kick may have started the process, but there's no guarantee the to-be-kicked vCPU has fully exited guest mode.”h]”hX This “request†ensures the target vCPU has exited guest mode prior to the sender of the request continuing on. No action needs be taken by the target, and so no request is actually logged for the target. This request is similar to a “kickâ€, but unlike a kick it guarantees the vCPU has actually exited guest mode. A kick only guarantees the vCPU will exit at some point in the future, e.g. a previous kick may have started the process, but there’s no guarantee the to-be-kicked vCPU has fully exited guest mode.”…””}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KƒhjŽubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´Kƒhjýh²hubeh}”(h]”Œ!architecture-independent-requests”ah ]”h"]”Œ!architecture independent requests”ah$]”h&]”uh1hÈhj‹h²hh³hÇh´KlubhÉ)”}”(hhh]”(hÎ)”}”(hŒKVM_REQUEST_MASK”h]”hŒKVM_REQUEST_MASK”…””}”(hj±h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj®h²hh³hÇh´KŒubhï)”}”(hŒîVCPU requests should be masked by KVM_REQUEST_MASK before using them with bitops. This is because only the lower 8 bits are used to represent the request's number. The upper bits are used as flags. Currently only two flags are defined.”h]”hŒðVCPU requests should be masked by KVM_REQUEST_MASK before using them with bitops. This is because only the lower 8 bits are used to represent the request’s number. The upper bits are used as flags. Currently only two flags are defined.”…””}”(hj¿h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KŽhj®h²hubeh}”(h]”Œkvm-request-mask”ah ]”h"]”Œkvm_request_mask”ah$]”h&]”uh1hÈhj‹h²hh³hÇh´KŒubhÉ)”}”(hhh]”(hÎ)”}”(hŒVCPU Request Flags”h]”hŒVCPU Request Flags”…””}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÕh²hh³hÇh´K”ubhï)”}”(hŒKVM_REQUEST_NO_WAKEUP”h]”hŒKVM_REQUEST_NO_WAKEUP”…””}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K–hjÕh²hubjð)”}”(hX This flag is applied to requests that only need immediate attention from VCPUs running in guest mode. That is, sleeping VCPUs do not need to be awakened for these requests. Sleeping VCPUs will handle the requests when they are awakened later for some other reason. ”h]”hï)”}”(hX This flag is applied to requests that only need immediate attention from VCPUs running in guest mode. That is, sleeping VCPUs do not need to be awakened for these requests. Sleeping VCPUs will handle the requests when they are awakened later for some other reason.”h]”hX This flag is applied to requests that only need immediate attention from VCPUs running in guest mode. That is, sleeping VCPUs do not need to be awakened for these requests. Sleeping VCPUs will handle the requests when they are awakened later for some other reason.”…””}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K˜hjôubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´K˜hjÕh²hubhï)”}”(hŒKVM_REQUEST_WAIT”h]”hŒKVM_REQUEST_WAIT”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KhjÕh²hubjð)”}”(hXêWhen requests with this flag are made with kvm_make_all_cpus_request(), then the caller will wait for each VCPU to acknowledge its IPI before proceeding. This flag only applies to VCPUs that would receive IPIs. If, for example, the VCPU is sleeping, so no IPI is necessary, then the requesting thread does not wait. This means that this flag may be safely combined with KVM_REQUEST_NO_WAKEUP. See "Waiting for Acknowledgements" for more information about requests with KVM_REQUEST_WAIT. ”h]”hï)”}”(hXéWhen requests with this flag are made with kvm_make_all_cpus_request(), then the caller will wait for each VCPU to acknowledge its IPI before proceeding. This flag only applies to VCPUs that would receive IPIs. If, for example, the VCPU is sleeping, so no IPI is necessary, then the requesting thread does not wait. This means that this flag may be safely combined with KVM_REQUEST_NO_WAKEUP. See "Waiting for Acknowledgements" for more information about requests with KVM_REQUEST_WAIT.”h]”hXíWhen requests with this flag are made with kvm_make_all_cpus_request(), then the caller will wait for each VCPU to acknowledge its IPI before proceeding. This flag only applies to VCPUs that would receive IPIs. If, for example, the VCPU is sleeping, so no IPI is necessary, then the requesting thread does not wait. This means that this flag may be safely combined with KVM_REQUEST_NO_WAKEUP. See “Waiting for Acknowledgements†for more information about requests with KVM_REQUEST_WAIT.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KŸhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jïh³hÇh´KŸhjÕh²hubeh}”(h]”Œvcpu-request-flags”ah ]”h"]”Œvcpu request flags”ah$]”h&]”uh1hÈhj‹h²hh³hÇh´K”ubeh}”(h]”Œvcpu-request-internals”ah ]”h"]”Œvcpu request internals”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K^ubhÉ)”}”(hhh]”(hÎ)”}”(hŒ#VCPU Requests with Associated State”h]”hŒ#VCPU Requests with Associated State”…””}”(hjEh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjBh²hh³hÇh´K©ubhï)”}”(hXRRequesters that want the receiving VCPU to handle new state need to ensure the newly written state is observable to the receiving VCPU thread's CPU by the time it observes the request. This means a write memory barrier must be inserted after writing the new state and before setting the VCPU request bit. Additionally, on the receiving VCPU thread's side, a corresponding read barrier must be inserted after reading the request bit and before proceeding to read the new state associated with it. See scenario 3, Message and Flag, of [lwn-mb]_ and the kernel documentation [memory-barriers]_.”h]”(hXRequesters that want the receiving VCPU to handle new state need to ensure the newly written state is observable to the receiving VCPU thread’s CPU by the time it observes the request. This means a write memory barrier must be inserted after writing the new state and before setting the VCPU request bit. Additionally, on the receiving VCPU thread’s side, a corresponding read barrier must be inserted after reading the request bit and before proceeding to read the new state associated with it. See scenario 3, Message and Flag, of ”…””}”(hjSh²hh³Nh´Nubh)”}”(hŒlwn-mb”h]”j»)”}”(hj]h]”hŒ[lwn-mb]”…””}”(hj_h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jºhj[ubah}”(h]”Œid2”ah ]”h"]”h$]”h&]”Œ refdomain”jÑŒreftype”jÓŒ reftarget”j]Œrefwarn”ˆŒsupport_smartquotes”‰uh1hh³hÇh´K«hjSh²hubhŒ and the kernel documentation ”…””}”(hjSh²hh³Nh´Nubh)”}”(hŒmemory-barriers”h]”j»)”}”(hj~h]”hŒ[memory-barriers]”…””}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jºhj|ubah}”(h]”Œid3”ah ]”h"]”h$]”h&]”Œ refdomain”jÑŒreftype”jÓŒ reftarget”j~Œrefwarn”ˆŒsupport_smartquotes”‰uh1hh³hÇh´K«hjSh²hubhŒ.”…””}”(hjSh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K«hjBh²hubhï)”}”(hŒžThe pair of functions, kvm_check_request() and kvm_make_request(), provide the memory barriers, allowing this requirement to be handled internally by the API.”h]”hŒžThe pair of functions, kvm_check_request() and kvm_make_request(), provide the memory barriers, allowing this requirement to be handled internally by the API.”…””}”(hj£h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KµhjBh²hubeh}”(h]”Œ#vcpu-requests-with-associated-state”ah ]”h"]”Œ#vcpu requests with associated state”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K©ubhÉ)”}”(hhh]”(hÎ)”}”(hŒEnsuring Requests Are Seen”h]”hŒEnsuring Requests Are Seen”…””}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj¹h²hh³hÇh´Kºubhï)”}”(hXVWhen making requests to VCPUs, we want to avoid the receiving VCPU executing in guest mode for an arbitrary long time without handling the request. We can be sure this won't happen as long as we ensure the VCPU thread checks kvm_request_pending() before entering guest mode and that a kick will send an IPI to force an exit from guest mode when necessary. Extra care must be taken to cover the period after the VCPU thread's last kvm_request_pending() check and before it has entered guest mode, as kick IPIs will only trigger guest mode exits for VCPU threads that are in guest mode or at least have already disabled interrupts in order to prepare to enter guest mode. This means that an optimized implementation (see "IPI Reduction") must be certain when it's safe to not send the IPI. One solution, which all architectures except s390 apply, is to:”h]”hX`When making requests to VCPUs, we want to avoid the receiving VCPU executing in guest mode for an arbitrary long time without handling the request. We can be sure this won’t happen as long as we ensure the VCPU thread checks kvm_request_pending() before entering guest mode and that a kick will send an IPI to force an exit from guest mode when necessary. Extra care must be taken to cover the period after the VCPU thread’s last kvm_request_pending() check and before it has entered guest mode, as kick IPIs will only trigger guest mode exits for VCPU threads that are in guest mode or at least have already disabled interrupts in order to prepare to enter guest mode. This means that an optimized implementation (see “IPI Reductionâ€) must be certain when it’s safe to not send the IPI. One solution, which all architectures except s390 apply, is to:”…””}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K¼hj¹h²hubhŒ bullet_list”“”)”}”(hhh]”(jA)”}”(hŒnset ``vcpu->mode`` to IN_GUEST_MODE between disabling the interrupts and the last kvm_request_pending() check;”h]”hï)”}”(hŒnset ``vcpu->mode`` to IN_GUEST_MODE between disabling the interrupts and the last kvm_request_pending() check;”h]”(hŒset ”…””}”(hjáh²hh³Nh´Nubj¶)”}”(hŒ``vcpu->mode``”h]”hŒ vcpu->mode”…””}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhjáubhŒ\ to IN_GUEST_MODE between disabling the interrupts and the last kvm_request_pending() check;”…””}”(hjáh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KÉhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÚh²hh³hÇh´NubjA)”}”(hŒ6enable interrupts atomically when entering the guest. ”h]”hï)”}”(hŒ5enable interrupts atomically when entering the guest.”h]”hŒ5enable interrupts atomically when entering the guest.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KËhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÚh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1jØh³hÇh´KÉhj¹h²hubhï)”}”(hXZThis solution also requires memory barriers to be placed carefully in both the requesting thread and the receiving VCPU. With the memory barriers we can exclude the possibility of a VCPU thread observing !kvm_request_pending() on its last check and then not receiving an IPI for the next request made of it, even if the request is made immediately after the check. This is done by way of the Dekker memory barrier pattern (scenario 10 of [lwn-mb]_). As the Dekker pattern requires two variables, this solution pairs ``vcpu->mode`` with ``vcpu->requests``. Substituting them into the pattern gives::”h]”(hX¸This solution also requires memory barriers to be placed carefully in both the requesting thread and the receiving VCPU. With the memory barriers we can exclude the possibility of a VCPU thread observing !kvm_request_pending() on its last check and then not receiving an IPI for the next request made of it, even if the request is made immediately after the check. This is done by way of the Dekker memory barrier pattern (scenario 10 of ”…””}”(hj'h²hh³Nh´Nubh)”}”(hŒlwn-mb”h]”j»)”}”(hj1h]”hŒ[lwn-mb]”…””}”(hj3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jºhj/ubah}”(h]”Œid4”ah ]”h"]”h$]”h&]”Œ refdomain”jÑŒreftype”jÓŒ reftarget”j1Œrefwarn”ˆŒsupport_smartquotes”‰uh1hh³hÇh´KÍhj'h²hubhŒF). As the Dekker pattern requires two variables, this solution pairs ”…””}”(hj'h²hh³Nh´Nubj¶)”}”(hŒ``vcpu->mode``”h]”hŒ vcpu->mode”…””}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhj'ubhŒ with ”…””}”(hj'h²hh³Nh´Nubj¶)”}”(hŒ``vcpu->requests``”h]”hŒvcpu->requests”…””}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhj'ubhŒ,. Substituting them into the pattern gives:”…””}”(hj'h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KÍhj¹h²hubhÿ)”}”(hXÙCPU1 CPU2 ================= ================= local_irq_disable(); WRITE_ONCE(vcpu->mode, IN_GUEST_MODE); kvm_make_request(REQ, vcpu); smp_mb(); smp_mb(); if (kvm_request_pending(vcpu)) { if (READ_ONCE(vcpu->mode) == IN_GUEST_MODE) { ...abort guest entry... ...send IPI... } }”h]”hXÙCPU1 CPU2 ================= ================= local_irq_disable(); WRITE_ONCE(vcpu->mode, IN_GUEST_MODE); kvm_make_request(REQ, vcpu); smp_mb(); smp_mb(); if (kvm_request_pending(vcpu)) { if (READ_ONCE(vcpu->mode) == IN_GUEST_MODE) { ...abort guest entry... ...send IPI... } }”…””}”hjzsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1hþh³hÇh´K×hj¹h²hubhï)”}”(hX¹As stated above, the IPI is only useful for VCPU threads in guest mode or that have already disabled interrupts. This is why this specific case of the Dekker pattern has been extended to disable interrupts before setting ``vcpu->mode`` to IN_GUEST_MODE. WRITE_ONCE() and READ_ONCE() are used to pedantically implement the memory barrier pattern, guaranteeing the compiler doesn't interfere with ``vcpu->mode``'s carefully planned accesses.”h]”(hŒÞAs stated above, the IPI is only useful for VCPU threads in guest mode or that have already disabled interrupts. This is why this specific case of the Dekker pattern has been extended to disable interrupts before setting ”…””}”(hjˆh²hh³Nh´Nubj¶)”}”(hŒ``vcpu->mode``”h]”hŒ vcpu->mode”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhjˆubhŒ£ to IN_GUEST_MODE. WRITE_ONCE() and READ_ONCE() are used to pedantically implement the memory barrier pattern, guaranteeing the compiler doesn’t interfere with ”…””}”(hjˆh²hh³Nh´Nubj¶)”}”(hŒ``vcpu->mode``”h]”hŒ vcpu->mode”…””}”(hj¢h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhjˆubhŒ ’s carefully planned accesses.”…””}”(hjˆh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Káhj¹h²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒ IPI Reduction”h]”hŒ IPI Reduction”…””}”(hj½h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjºh²hh³hÇh´Kêubhï)”}”(hXAs only one IPI is needed to get a VCPU to check for any/all requests, then they may be coalesced. This is easily done by having the first IPI sending kick also change the VCPU mode to something !IN_GUEST_MODE. The transitional state, EXITING_GUEST_MODE, is used for this purpose.”h]”hXAs only one IPI is needed to get a VCPU to check for any/all requests, then they may be coalesced. This is easily done by having the first IPI sending kick also change the VCPU mode to something !IN_GUEST_MODE. The transitional state, EXITING_GUEST_MODE, is used for this purpose.”…””}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kìhjºh²hubeh}”(h]”Œ ipi-reduction”ah ]”h"]”Œ ipi reduction”ah$]”h&]”uh1hÈhj¹h²hh³hÇh´KêubhÉ)”}”(hhh]”(hÎ)”}”(hŒWaiting for Acknowledgements”h]”hŒWaiting for Acknowledgements”…””}”(hjäh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjáh²hh³hÇh´Kòubhï)”}”(hXSome requests, those with the KVM_REQUEST_WAIT flag set, require IPIs to be sent, and the acknowledgements to be waited upon, even when the target VCPU threads are in modes other than IN_GUEST_MODE. For example, one case is when a target VCPU thread is in READING_SHADOW_PAGE_TABLES mode, which is set after disabling interrupts. To support these cases, the KVM_REQUEST_WAIT flag changes the condition for sending an IPI from checking that the VCPU is IN_GUEST_MODE to checking that it is not OUTSIDE_GUEST_MODE.”h]”hXSome requests, those with the KVM_REQUEST_WAIT flag set, require IPIs to be sent, and the acknowledgements to be waited upon, even when the target VCPU threads are in modes other than IN_GUEST_MODE. For example, one case is when a target VCPU thread is in READING_SHADOW_PAGE_TABLES mode, which is set after disabling interrupts. To support these cases, the KVM_REQUEST_WAIT flag changes the condition for sending an IPI from checking that the VCPU is IN_GUEST_MODE to checking that it is not OUTSIDE_GUEST_MODE.”…””}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kôhjáh²hubeh}”(h]”Œwaiting-for-acknowledgements”ah ]”h"]”Œwaiting for acknowledgements”ah$]”h&]”uh1hÈhj¹h²hh³hÇh´KòubhÉ)”}”(hhh]”(hÎ)”}”(hŒRequest-less VCPU Kicks”h]”hŒRequest-less VCPU Kicks”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´Kþubhï)”}”(hX£As the determination of whether or not to send an IPI depends on the two-variable Dekker memory barrier pattern, then it's clear that request-less VCPU kicks are almost never correct. Without the assurance that a non-IPI generating kick will still result in an action by the receiving VCPU, as the final kvm_request_pending() check does for request-accompanying kicks, then the kick may not do anything useful at all. If, for instance, a request-less kick was made to a VCPU that was just about to set its mode to IN_GUEST_MODE, meaning no IPI is sent, then the VCPU thread may continue its entry without actually having done whatever it was the kick was meant to initiate.”h]”hX¥As the determination of whether or not to send an IPI depends on the two-variable Dekker memory barrier pattern, then it’s clear that request-less VCPU kicks are almost never correct. Without the assurance that a non-IPI generating kick will still result in an action by the receiving VCPU, as the final kvm_request_pending() check does for request-accompanying kicks, then the kick may not do anything useful at all. If, for instance, a request-less kick was made to a VCPU that was just about to set its mode to IN_GUEST_MODE, meaning no IPI is sent, then the VCPU thread may continue its entry without actually having done whatever it was the kick was meant to initiate.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Mhjh²hubhï)”}”(hXäOne exception is x86's posted interrupt mechanism. In this case, however, even the request-less VCPU kick is coupled with the same local_irq_disable() + smp_mb() pattern described above; the ON bit (Outstanding Notification) in the posted interrupt descriptor takes the role of ``vcpu->requests``. When sending a posted interrupt, PIR.ON is set before reading ``vcpu->mode``; dually, in the VCPU thread, vmx_sync_pir_to_irr() reads PIR after setting ``vcpu->mode`` to IN_GUEST_MODE.”h]”(hXOne exception is x86’s posted interrupt mechanism. In this case, however, even the request-less VCPU kick is coupled with the same local_irq_disable() + smp_mb() pattern described above; the ON bit (Outstanding Notification) in the posted interrupt descriptor takes the role of ”…””}”(hj'h²hh³Nh´Nubj¶)”}”(hŒ``vcpu->requests``”h]”hŒvcpu->requests”…””}”(hj/h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhj'ubhŒA. When sending a posted interrupt, PIR.ON is set before reading ”…””}”(hj'h²hh³Nh´Nubj¶)”}”(hŒ``vcpu->mode``”h]”hŒ vcpu->mode”…””}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhj'ubhŒL; dually, in the VCPU thread, vmx_sync_pir_to_irr() reads PIR after setting ”…””}”(hj'h²hh³Nh´Nubj¶)”}”(hŒ``vcpu->mode``”h]”hŒ vcpu->mode”…””}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jµhj'ubhŒ to IN_GUEST_MODE.”…””}”(hj'h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´M hjh²hubeh}”(h]”Œrequest-less-vcpu-kicks”ah ]”h"]”Œrequest-less vcpu kicks”ah$]”h&]”uh1hÈhj¹h²hh³hÇh´Kþubeh}”(h]”Œensuring-requests-are-seen”ah ]”h"]”Œensuring requests are seen”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KºubhÉ)”}”(hhh]”(hÎ)”}”(hŒAdditional Considerations”h]”hŒAdditional Considerations”…””}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj{h²hh³hÇh´MubhÉ)”}”(hhh]”(hÎ)”}”(hŒSleeping VCPUs”h]”hŒSleeping VCPUs”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjŒh²hh³hÇh´Mubhï)”}”(hX¢VCPU threads may need to consider requests before and/or after calling functions that may put them to sleep, e.g. kvm_vcpu_block(). Whether they do or not, and, if they do, which requests need consideration, is architecture dependent. kvm_vcpu_block() calls kvm_arch_vcpu_runnable() to check if it should awaken. One reason to do so is to provide architectures a function where requests may be checked if necessary.”h]”hX¢VCPU threads may need to consider requests before and/or after calling functions that may put them to sleep, e.g. kvm_vcpu_block(). Whether they do or not, and, if they do, which requests need consideration, is architecture dependent. kvm_vcpu_block() calls kvm_arch_vcpu_runnable() to check if it should awaken. One reason to do so is to provide architectures a function where requests may be checked if necessary.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´MhjŒh²hubeh}”(h]”Œsleeping-vcpus”ah ]”h"]”Œsleeping vcpus”ah$]”h&]”uh1hÈhj{h²hh³hÇh´Mubeh}”(h]”Œadditional-considerations”ah ]”h"]”Œadditional considerations”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´MubhÉ)”}”(hhh]”(hÎ)”}”(hŒ References”h]”hŒ References”…””}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj»h²hh³hÇh´M"ubhjÑ“”)”}”(hŒ>Documentation/atomic_bitops.txt and Documentation/atomic_t.txt”h]”(hŒlabel”“”)”}”(hŒ atomic-ops”h]”hŒ atomic-ops”…””}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œsupport_smartquotes”‰uh1jÑhjÍubhï)”}”(hjÏh]”hŒ>Documentation/atomic_bitops.txt and Documentation/atomic_t.txt”…””}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´M$hjÍubeh}”(h]”Œ atomic-ops”ah ]”h"]”Œ atomic-ops”ah$]”h&]”jËaŒdocname”Œvirt/kvm/vcpu-requests”uh1jÑh³hÇh´M$hj»h²hŒresolved”KubjÌ)”}”(hŒ!Documentation/memory-barriers.txt”h]”(jÒ)”}”(hŒmemory-barriers”h]”hŒmemory-barriers”…””}”(hjþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”já‰uh1jÑhjúubhï)”}”(hjüh]”hŒ!Documentation/memory-barriers.txt”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´M%hjúubeh}”(h]”Œmemory-barriers”ah ]”h"]”Œmemory-barriers”ah$]”h&]”jaj÷jøuh1jÑh³hÇh´M%hj»h²hjùKubjÌ)”}”(hŒ https://lwn.net/Articles/573436/”h]”(jÒ)”}”(hŒlwn-mb”h]”hŒlwn-mb”…””}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”já‰uh1jÑhj!ubhï)”}”(hj#h]”hŒ reference”“”)”}”(hj#h]”hŒ https://lwn.net/Articles/573436/”…””}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j#uh1j6hj3ubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´M&hj!ubeh}”(h]”Œlwn-mb”ah ]”h"]”Œlwn-mb”ah$]”h&]”(jnjBej÷jøuh1jÑh³hÇh´M&hj»h²hjùKubeh}”(h]”Œ references”ah ]”h"]”Œ references”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´M"ubeh}”(h]”Œkvm-vcpu-requests”ah ]”h"]”Œkvm vcpu requests”ah$]”h&]”uh1hÈhhh²hh³hÇh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hÍNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j‡Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”(Œ atomic-ops”]”hŒcitation_reference”“”)”}”(hŒ [atomic-ops]_”h]”hŒ atomic-ops”…””}”hjËsbah}”(h]”jËah ]”h"]”h$]”h&]”Œrefid”jñuh1jÉhjœjùKubaŒlwn-mb”]”(jÊ)”}”(hŒ [lwn-mb]_”h]”hŒlwn-mb”…””}”hjÜsbah}”(h]”jnah ]”h"]”h$]”h&]”jÙjNuh1jÉhjSjùKubjÊ)”}”(hŒ [lwn-mb]_”h]”hŒlwn-mb”…””}”hjêsbah}”(h]”jBah ]”h"]”h$]”h&]”jÙjNuh1jÉhj'jùKubeŒmemory-barriers”]”jÊ)”}”(hŒ[memory-barriers]_”h]”hŒmemory-barriers”…””}”hjúsbah}”(h]”jah ]”h"]”h$]”h&]”jÙjuh1jÉhjSjùKubauŒrefids”}”Œnameids”}”(jaj^jˆj…j™j–j€j}j?j<j«j¨jÒjÏj7j4j¶j³jxjujÞjÛjjjpjmj¸jµj°j­jYjVjôjñjjjQjNuŒ nametypes”}”(ja‰jˆ‰j™‰j€‰j?‰j«‰jÒ‰j7‰j¶‰jx‰jÞ‰j‰jp‰j¸‰j°‰jY‰jôˆjˆjQˆuh}”(j^hÊj…hÝj–jj}jœj<j‹jËjËj¨jýjÏj®j4jÕj³jBjnjÜjjújuj¹jBjêjÛjºjjájmjjµj{j­jŒjVj»jñjÍjjújNj!uŒ footnote_refs”}”Œ citation_refs”}”(jÇ]”jËajÚ]”(jÜjêejø]”júauŒ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”(jÍjúj!eŒautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”j•Ks…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.