[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 4/6] cpu: Support a target CPU having a varia
From: |
Andrew Jones |
Subject: |
Re: [Qemu-devel] [PATCH v2 4/6] cpu: Support a target CPU having a variable page size |
Date: |
Tue, 21 Jun 2016 20:26:34 +0200 |
User-agent: |
Mutt/1.5.23.1 (2014-03-12) |
On Tue, Jun 21, 2016 at 06:09:32PM +0100, Peter Maydell wrote:
> Support target CPUs having a page size which isn't knownn
> at compile time. To use this, the CPU implementation should:
> * define TARGET_PAGE_BITS_VARY
> * not define TARGET_PAGE_BITS
> * define TARGET_PAGE_BITS_MIN to the smallest value it
> might possibly want for TARGET_PAGE_BITS
> * call set_preferred_target_page_bits() in its realize
> function to indicate the actual preferred target page
> size for the CPU (and report any error from it)
>
> In CONFIG_USER_ONLY, the CPU implementation should continue
> to define TARGET_PAGE_BITS appropriately for the guest
> OS page size.
>
> Machines which want to take advantage of having the page
> size something larger than TARGET_PAGE_BITS_MIN must
> set the MachineClass minimum_page_bits field to a value
> which they guarantee will be no greater than the preferred
> page size for any CPU they create.
>
> Note that changing the target page size by setting
> minimum_page_bits is a migration compatibility break
> for that machine.
>
> For debugging purposes, attempts to use TARGET_PAGE_SIZE
> before it has been finally confirmed will assert.
>
> Signed-off-by: Peter Maydell <address@hidden>
> ---
> exec.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> include/exec/cpu-all.h | 8 ++++++++
> include/hw/boards.h | 7 +++++++
> include/qemu-common.h | 13 +++++++++++++
> vl.c | 10 ++++++++++
> 5 files changed, 80 insertions(+)
>
> diff --git a/exec.c b/exec.c
> index 8eaeb0c..027ce53 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -93,6 +93,11 @@ static MemoryRegion io_mem_unassigned;
>
> #endif
>
> +#ifdef TARGET_PAGE_BITS_VARY
> +int target_page_bits;
> +bool target_page_bits_decided;
> +#endif
> +
> struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
> /* current CPU in the current thread. It is only valid inside
> cpu_exec() */
> @@ -102,8 +107,37 @@ __thread CPUState *current_cpu;
> 2 = Adaptive rate instruction counting. */
> int use_icount;
>
> +bool set_preferred_target_page_bits(int bits)
> +{
> + /* The target page size is the lowest common denominator for all
> + * the CPUs in the system, so we can only make it smaller, never
> + * larger. And we can't make it smaller once we've committed to
> + * a particular size.
> + */
> +#ifdef TARGET_PAGE_BITS_VARY
> + assert(bits >= TARGET_PAGE_BITS_MIN);
> + if (target_page_bits == 0 || target_page_bits > bits) {
> + if (target_page_bits_decided) {
> + return false;
> + }
> + target_page_bits = bits;
> + }
> +#endif
> + return true;
> +}
> +
> #if !defined(CONFIG_USER_ONLY)
>
> +static void finalize_target_page_bits(void)
> +{
> +#ifdef TARGET_PAGE_BITS_VARY
> + if (target_page_bits == 0) {
> + target_page_bits = TARGET_PAGE_BITS_MIN;
> + }
> + target_page_bits_decided = true;
> +#endif
> +}
> +
> typedef struct PhysPageEntry PhysPageEntry;
>
> struct PhysPageEntry {
> @@ -2862,6 +2896,14 @@ void cpu_register_map_client(QEMUBH *bh)
> void cpu_exec_init_all(void)
> {
> qemu_mutex_init(&ram_list.mutex);
> + /* The data structures we set up here depend on knowing the page size,
> + * so no more changes can be made after this point.
> + * In an ideal world, nothing we did before we had finished the
> + * machine setup would care about the target page size, and we could
> + * do this much later, rather than requiring board models to state
> + * up front what their requirements are.
> + */
> + finalize_target_page_bits();
> io_mem_init();
> memory_map_init();
> qemu_mutex_init(&map_client_list_lock);
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 9f38edf..dde3cd4 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -189,6 +189,14 @@ void address_space_stq(AddressSpace *as, hwaddr addr,
> uint64_t val,
>
> /* page related stuff */
>
> +#ifdef TARGET_PAGE_BITS_VARY
> +extern bool target_page_bits_decided;
> +extern int target_page_bits;
> +#define TARGET_PAGE_BITS ({ assert(target_page_bits_decided); \
> + target_page_bits; })
> +
> +#endif
> +
> #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
> #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
> #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) &
> TARGET_PAGE_MASK)
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 3ed6155..11808bc 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -85,6 +85,12 @@ typedef struct {
> * Returns a @HotpluggableCPUList, which describes CPUs objects which
> * could be added with -device/device_add.
> * Caller is responsible for freeing returned list.
> + * @minimum_page_bits:
> + * If non-zero, the board promises never to create a CPU with a page size
> + * smaller than this, so QEMU can use a more efficient larger page
> + * size than the target architecture's minimum. (Attempting to create
> + * such a CPU will fail.) Note that changing this is a migration
> + * compatibility break for the machine.
> */
> struct MachineClass {
> /*< private >*/
> @@ -123,6 +129,7 @@ struct MachineClass {
> ram_addr_t default_ram_size;
> bool option_rom_has_mr;
> bool rom_file_has_mr;
> + int minimum_page_bits;
>
> HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
> DeviceState *dev);
> diff --git a/include/qemu-common.h b/include/qemu-common.h
> index 1f2cb94..fd9d4eb 100644
> --- a/include/qemu-common.h
> +++ b/include/qemu-common.h
> @@ -76,6 +76,19 @@ void tcg_exec_init(unsigned long tb_size);
> bool tcg_enabled(void);
>
> void cpu_exec_init_all(void);
> +void cpu_exec_machine_creation_done(void);
Was the above added here by mistake?
> +
> +/**
> + * set_preferred_target_page_bits:
> + * @bits: number of bits needed to represent an address within the page
> + *
> + * Set the preferred target page size (the actual target page
> + * size may be smaller than any given CPU's preference).
> + * Returns true on success, false on failure (which can only happen
> + * if this is called after the system has already finalized its
> + * choice of page size and the requested page size is smaller than that).
> + */
> +bool set_preferred_target_page_bits(int bits);
>
> /**
> * Sends a (part of) iovec down a socket, yielding when the socket is full,
> or
> diff --git a/vl.c b/vl.c
> index 2f63eb4..61ae073 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -4038,6 +4038,16 @@ int main(int argc, char **argv, char **envp)
> }
> object_property_add_child(object_get_root(), "machine",
> OBJECT(current_machine), &error_abort);
> +
> + if (machine_class->minimum_page_bits) {
> + if
> (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
> + /* This would be a board error: specifying a minimum smaller than
> + * a target's compile-time fixed setting.
> + */
> + g_assert_not_reached();
> + }
> + }
> +
> cpu_exec_init_all();
>
> if (machine_class->hw_version) {
> --
> 1.9.1
>
>
- [Qemu-devel] [PATCH v2 1/6] migration: Remove static allocation of xzblre cache buffer, (continued)
- [Qemu-devel] [PATCH v2 5/6] target-arm: Make page size a runtime setting, Peter Maydell, 2016/06/21
- [Qemu-devel] [PATCH v2 4/6] cpu: Support a target CPU having a variable page size, Peter Maydell, 2016/06/21
- Re: [Qemu-devel] [PATCH v2 4/6] cpu: Support a target CPU having a variable page size,
Andrew Jones <=
- Re: [Qemu-devel] [PATCH v2 0/6] Runtime pagesize computation, Dr. David Alan Gilbert, 2016/06/22
- Re: [Qemu-devel] [Qemu-arm] [PATCH v2 0/6] Runtime pagesize computation, Peter Maydell, 2016/06/28