From: Claudio Imbrenda <imbrenda@linux.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: kvm@vger.kernel.org, linux-s390@vger.kernel.org,
borntraeger@de.ibm.com, frankja@linux.ibm.com, david@kernel.org,
seiden@linux.ibm.com, nrb@linux.ibm.com,
schlameuss@linux.ibm.com, gra@linux.ibm.com
Subject: [PATCH v3 1/8] KVM: s390: Fix dirty marking in adapter_indicators_set*()
Date: Fri, 28 Aug 2026 13:54:32 +0200 [thread overview]
Message-ID: <20260828115439.145885-2-imbrenda@linux.ibm.com> (raw)
In-Reply-To: <20260828115439.145885-1-imbrenda@linux.ibm.com>
When the indicator and/or summary bits are set in the guest, the
accessed page was only marked dirty in KVM if the access was performed
using the slow path; accesses through the new kvm_arch_set_irq_inatomic
fast inject path would not mark the page as dirty.
Fix by adding/moving the missing calls to mark_page_dirty(). Note that
for the inatomic path set_page_dirty{,_lock}() is not needed as the
page stays pinned; the unpin path correctly marks it as dirty.
Opportunistically reorder the local variables to be in reverse
Christmas tree order and refactor to use guard().
Fixes: 1e95e3bc6b05 ("KVM: s390: Enable adapter_indicators_set to use mapped pages")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/s390/interrupt.c | 75 +++++++++++++++++-----------------
1 file changed, 38 insertions(+), 37 deletions(-)
diff --git a/arch/s390/kvm/s390/interrupt.c b/arch/s390/kvm/s390/interrupt.c
index 0381ae981703..49b4e233e791 100644
--- a/arch/s390/kvm/s390/interrupt.c
+++ b/arch/s390/kvm/s390/interrupt.c
@@ -2984,61 +2984,58 @@ static int adapter_indicators_set(struct kvm *kvm,
struct s390_io_adapter *adapter,
struct kvm_s390_adapter_int *adapter_int)
{
- unsigned long bit;
- int summary_set, idx;
struct s390_map_info *ind_info, *summary_info;
- void *map;
struct page *ind_page, *summary_page;
- unsigned long flags;
+ unsigned long bit;
+ int summary_set;
+ void *map;
ind_page = NULL;
- spin_lock_irqsave(&adapter->maps_lock, flags);
- ind_info = get_map_info(adapter, adapter_int->ind_addr);
+ scoped_guard(spinlock_irqsave, &adapter->maps_lock) {
+ ind_info = get_map_info(adapter, adapter_int->ind_addr);
+ if (ind_info) {
+ map = page_address(ind_info->page);
+ bit = get_ind_bit(ind_info->addr, adapter_int->ind_offset, adapter->swap);
+ set_bit(bit, map);
+ }
+ }
if (!ind_info) {
- spin_unlock_irqrestore(&adapter->maps_lock, flags);
ind_page = pin_map_page(kvm, adapter_int->ind_addr, 0);
if (!ind_page)
return -1;
- idx = srcu_read_lock(&kvm->srcu);
map = page_address(ind_page);
bit = get_ind_bit(adapter_int->ind_addr,
adapter_int->ind_offset, adapter->swap);
set_bit(bit, map);
- mark_page_dirty(kvm, adapter_int->ind_gaddr >> PAGE_SHIFT);
set_page_dirty_lock(ind_page);
- srcu_read_unlock(&kvm->srcu, idx);
unpin_user_page(ind_page);
- } else {
- map = page_address(ind_info->page);
- bit = get_ind_bit(ind_info->addr, adapter_int->ind_offset, adapter->swap);
- set_bit(bit, map);
- spin_unlock_irqrestore(&adapter->maps_lock, flags);
}
+ scoped_guard(srcu, &kvm->srcu)
+ mark_page_dirty(kvm, gpa_to_gfn(adapter_int->ind_gaddr));
- spin_lock_irqsave(&adapter->maps_lock, flags);
- summary_info = get_map_info(adapter, adapter_int->summary_addr);
+ scoped_guard(spinlock_irqsave, &adapter->maps_lock) {
+ summary_info = get_map_info(adapter, adapter_int->summary_addr);
+ if (summary_info) {
+ map = page_address(summary_info->page);
+ bit = get_ind_bit(summary_info->addr, adapter_int->summary_offset,
+ adapter->swap);
+ summary_set = test_and_set_bit(bit, map);
+ }
+ }
if (!summary_info) {
- spin_unlock_irqrestore(&adapter->maps_lock, flags);
summary_page = pin_map_page(kvm, adapter_int->summary_addr, 0);
if (!summary_page)
return -1;
- idx = srcu_read_lock(&kvm->srcu);
map = page_address(summary_page);
bit = get_ind_bit(adapter_int->summary_addr,
adapter_int->summary_offset, adapter->swap);
summary_set = test_and_set_bit(bit, map);
- mark_page_dirty(kvm, adapter_int->summary_gaddr >> PAGE_SHIFT);
set_page_dirty_lock(summary_page);
- srcu_read_unlock(&kvm->srcu, idx);
unpin_user_page(summary_page);
- } else {
- map = page_address(summary_info->page);
- bit = get_ind_bit(summary_info->addr, adapter_int->summary_offset,
- adapter->swap);
- summary_set = test_and_set_bit(bit, map);
- spin_unlock_irqrestore(&adapter->maps_lock, flags);
}
+ scoped_guard(srcu, &kvm->srcu)
+ mark_page_dirty(kvm, gpa_to_gfn(adapter_int->summary_gaddr));
return summary_set ? 0 : 1;
}
@@ -3048,26 +3045,29 @@ static int adapter_indicators_set_fast(struct kvm *kvm,
struct kvm_s390_adapter_int *adapter_int,
int setbit)
{
+ struct s390_map_info *ind_info, *summary_info;
unsigned long bit;
int summary_set;
- struct s390_map_info *ind_info, *summary_info;
void *map;
- spin_lock(&adapter->maps_lock);
+ guard(srcu)(&kvm->srcu);
+ guard(spinlock)(&adapter->maps_lock);
+
ind_info = get_map_info(adapter, adapter_int->ind_addr);
- if (!ind_info) {
- spin_unlock(&adapter->maps_lock);
+ if (!ind_info)
return -EWOULDBLOCK;
- }
+
map = page_address(ind_info->page);
bit = get_ind_bit(ind_info->addr, adapter_int->ind_offset, adapter->swap);
- if (setbit)
+ if (setbit) {
set_bit(bit, map);
+ mark_page_dirty(kvm, gpa_to_gfn(adapter_int->ind_gaddr));
+ }
+
summary_info = get_map_info(adapter, adapter_int->summary_addr);
- if (!summary_info) {
- spin_unlock(&adapter->maps_lock);
+ if (!summary_info)
return -EWOULDBLOCK;
- }
+
map = page_address(summary_info->page);
bit = get_ind_bit(summary_info->addr, adapter_int->summary_offset,
adapter->swap);
@@ -3077,7 +3077,8 @@ static int adapter_indicators_set_fast(struct kvm *kvm,
summary_set = test_and_set_bit(bit, map);
else
summary_set = test_and_clear_bit(bit, map);
- spin_unlock(&adapter->maps_lock);
+ mark_page_dirty(kvm, gpa_to_gfn(adapter_int->summary_gaddr));
+
return summary_set ? 0 : 1;
}
--
2.55.0
next prev parent reply other threads:[~2026-08-28 11:54 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-28 11:54 [PATCH v3 0/8] KVM: s390: Even more misc fixes Claudio Imbrenda
2026-08-28 11:54 ` Claudio Imbrenda [this message]
2026-08-28 12:08 ` [PATCH v3 1/8] KVM: s390: Fix dirty marking in adapter_indicators_set*() sashiko-bot
2026-08-28 11:54 ` [PATCH v3 2/8] KVM: s390: Fix compile warning for kvm_s390_update_cmma_dirty() Claudio Imbrenda
2026-08-28 12:02 ` sashiko-bot
2026-08-28 11:54 ` [PATCH v3 3/8] KVM: s390: Fix _gaccess_shadow_fault() Claudio Imbrenda
2026-08-28 12:08 ` sashiko-bot
2026-08-28 11:54 ` [PATCH v3 4/8] KVM: s390: Refactor dat_set_slot() Claudio Imbrenda
2026-08-28 12:05 ` sashiko-bot
2026-08-28 11:54 ` [PATCH v3 5/8] KVM: s390: Move all code into s390_kvm_mmu_prepare_memory_region() Claudio Imbrenda
2026-08-28 12:07 ` sashiko-bot
2026-08-28 11:54 ` [PATCH v3 6/8] KVM: s390: Add missing srcu in kvm_s390_set_irq_state() Claudio Imbrenda
2026-08-28 12:10 ` sashiko-bot
2026-08-28 11:54 ` [PATCH v3 7/8] KVM: s390: Fix potential races in dat skey functions Claudio Imbrenda
2026-08-28 12:08 ` sashiko-bot
2026-08-28 11:54 ` [PATCH v3 8/8] KVM: s390: Fix race in _destroy_pages_crste() Claudio Imbrenda
2026-08-28 12:18 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260828115439.145885-2-imbrenda@linux.ibm.com \
--to=imbrenda@linux.ibm.com \
--cc=borntraeger@de.ibm.com \
--cc=david@kernel.org \
--cc=frankja@linux.ibm.com \
--cc=gra@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=nrb@linux.ibm.com \
--cc=schlameuss@linux.ibm.com \
--cc=seiden@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox