From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-arm@nongnu.org, qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>,
patches@linaro.org
Subject: [Qemu-arm] [PATCH v2 4/6] cpu: Support a target CPU having a variable page size
Date: Tue, 21 Jun 2016 18:09:32 +0100 [thread overview]
Message-ID: <1466528974-12183-5-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1466528974-12183-1-git-send-email-peter.maydell@linaro.org>
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 <peter.maydell@linaro.org>
---
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);
+
+/**
+ * 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
next prev parent reply other threads:[~2016-06-21 17:09 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-21 17:09 [Qemu-arm] [PATCH v2 0/6] Runtime pagesize computation Peter Maydell
2016-06-21 17:09 ` [Qemu-arm] [PATCH v2 1/6] migration: Remove static allocation of xzblre cache buffer Peter Maydell
2016-06-22 1:44 ` [Qemu-arm] [Qemu-devel] " Richard Henderson
2016-06-21 17:09 ` [Qemu-arm] [PATCH v2 2/6] exec.c: Remove static allocation of sub_section of sub_page Peter Maydell
2016-06-22 1:47 ` [Qemu-arm] [Qemu-devel] " Richard Henderson
[not found] ` <BY1PR0701MB169163D3032F7EF4FB8FD000F22C0@BY1PR0701MB1691.namprd07.prod.outlook.com>
2016-06-22 6:55 ` [Qemu-arm] Fw: " Vijay Kilari
2016-06-22 7:07 ` [Qemu-arm] [Qemu-devel] " Richard Henderson
2016-06-21 17:09 ` [Qemu-arm] [PATCH v2 3/6] translate-all.c: Compute L1 page table properties at runtime Peter Maydell
2016-06-22 6:56 ` [Qemu-devel] " Richard Henderson
2016-06-21 17:09 ` Peter Maydell [this message]
2016-06-21 18:26 ` [Qemu-arm] [Qemu-devel] [PATCH v2 4/6] cpu: Support a target CPU having a variable page size Andrew Jones
2016-06-21 19:46 ` Peter Maydell
2016-06-21 17:09 ` [Qemu-arm] [PATCH v2 5/6] target-arm: Make page size a runtime setting Peter Maydell
2016-06-21 17:09 ` [Qemu-arm] [PATCH v2 6/6] hw/arm/virt: Set minimum_page_bits to 12 Peter Maydell
2016-06-21 18:45 ` [Qemu-arm] [Qemu-devel] " Andrew Jones
2016-06-21 19:47 ` Peter Maydell
2016-06-22 8:02 ` Andrew Jones
2016-06-22 11:35 ` Dr. David Alan Gilbert
2016-06-22 11:38 ` [Qemu-arm] " Peter Maydell
2016-06-22 11:54 ` Dr. David Alan Gilbert
2016-06-22 12:02 ` [Qemu-arm] " Peter Maydell
2016-06-22 12:17 ` Dr. David Alan Gilbert
2016-06-22 12:18 ` [Qemu-arm] " Andrew Jones
2016-06-22 10:24 ` Paolo Bonzini
2016-06-22 11:43 ` [Qemu-devel] [PATCH v2 0/6] Runtime pagesize computation Dr. David Alan Gilbert
2016-06-28 8:16 ` [Qemu-arm] " Peter Maydell
[not found] ` <BLUPR0701MB1684CF1920D922BD00E93EE6F2230@BLUPR0701MB1684.namprd07.prod.outlook.com>
2016-06-29 7:00 ` [Qemu-arm] Fw: " Vijay Kilari
2016-07-19 11:01 ` Vijay Kilari
2016-07-19 11:04 ` Peter Maydell
2016-10-07 14:20 ` [Qemu-devel] Fw: [Qemu-arm] " Peter Maydell
2016-10-08 4:26 ` [Qemu-arm] Fw: " Vijay Kilari
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=1466528974-12183-5-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=Vijaya.Kumar@caviumnetworks.com \
--cc=patches@linaro.org \
--cc=pbonzini@redhat.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/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;
as well as URLs for NNTP newsgroup(s).