diff options
| author | Philippe Mathieu-Daudé <philmd@linaro.org> | 2025-09-29 13:35:49 +0200 |
|---|---|---|
| committer | Philippe Mathieu-Daudé <philmd@linaro.org> | 2025-10-07 05:03:56 +0200 |
| commit | 84a8e6399bc06550e41f5b2f7b94e4a2213b2ebc (patch) | |
| tree | 942a31adc412c2b3a2dc603fd2c29652db58f190 /system/physmem.c | |
| parent | 3a0539afcbdf83aa919e32a36107bbe357ae9ef2 (diff) | |
| download | focaccia-qemu-84a8e6399bc06550e41f5b2f7b94e4a2213b2ebc.tar.gz focaccia-qemu-84a8e6399bc06550e41f5b2f7b94e4a2213b2ebc.zip | |
system/physmem: Un-inline cpu_physical_memory_range_includes_clean()
Avoid maintaining large functions in header, rely on the linker to optimize at linking time. cpu_physical_memory_all_dirty() doesn't involve any CPU, remove the 'cpu_' prefix. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20251001175448.18933-10-philmd@linaro.org>
Diffstat (limited to 'system/physmem.c')
| -rw-r--r-- | system/physmem.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/system/physmem.c b/system/physmem.c index e555b3196f..144fd7303b 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -952,6 +952,66 @@ bool cpu_physical_memory_is_clean(ram_addr_t addr) return !(vga && code && migration); } +static bool physical_memory_all_dirty(ram_addr_t start, ram_addr_t length, + unsigned client) +{ + DirtyMemoryBlocks *blocks; + unsigned long end, page; + unsigned long idx, offset, base; + bool dirty = true; + + assert(client < DIRTY_MEMORY_NUM); + + end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS; + page = start >> TARGET_PAGE_BITS; + + RCU_READ_LOCK_GUARD(); + + blocks = qatomic_rcu_read(&ram_list.dirty_memory[client]); + + idx = page / DIRTY_MEMORY_BLOCK_SIZE; + offset = page % DIRTY_MEMORY_BLOCK_SIZE; + base = page - offset; + while (page < end) { + unsigned long next = MIN(end, base + DIRTY_MEMORY_BLOCK_SIZE); + unsigned long num = next - base; + unsigned long found = find_next_zero_bit(blocks->blocks[idx], + num, offset); + if (found < num) { + dirty = false; + break; + } + + page = next; + idx++; + offset = 0; + base += DIRTY_MEMORY_BLOCK_SIZE; + } + + return dirty; +} + +uint8_t cpu_physical_memory_range_includes_clean(ram_addr_t start, + ram_addr_t length, + uint8_t mask) +{ + uint8_t ret = 0; + + if (mask & (1 << DIRTY_MEMORY_VGA) && + !physical_memory_all_dirty(start, length, DIRTY_MEMORY_VGA)) { + ret |= (1 << DIRTY_MEMORY_VGA); + } + if (mask & (1 << DIRTY_MEMORY_CODE) && + !physical_memory_all_dirty(start, length, DIRTY_MEMORY_CODE)) { + ret |= (1 << DIRTY_MEMORY_CODE); + } + if (mask & (1 << DIRTY_MEMORY_MIGRATION) && + !physical_memory_all_dirty(start, length, DIRTY_MEMORY_MIGRATION)) { + ret |= (1 << DIRTY_MEMORY_MIGRATION); + } + return ret; +} + /* Note: start and end must be within the same ram block. */ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start, ram_addr_t length, |