61f3c91a67
There is no "version 2" of the "Lesser" General Public License. It is either "GPL version 2.0" or "Lesser GPL version 2.1". This patch replaces all occurrences of "Lesser GPL version 2" with "Lesser GPL version 2.1" in comment section. This patch contains all the files, whose maintainer I could not get from ‘get_maintainer.pl’ script. Signed-off-by: Chetan Pant <chetan4windows@gmail.com> Message-Id: <20201023124424.20177-1-chetan4windows@gmail.com> Reviewed-by: Thomas Huth <thuth@redhat.com> [thuth: Adapted exec.c and qdev-monitor.c to new location] Signed-off-by: Thomas Huth <thuth@redhat.com>
109 lines
3.5 KiB
C
109 lines
3.5 KiB
C
/*
|
|
* Variable page size handling
|
|
*
|
|
* Copyright (c) 2003 Fabrice Bellard
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qemu-common.h"
|
|
|
|
#define IN_EXEC_VARY 1
|
|
|
|
#include "exec/exec-all.h"
|
|
|
|
#ifdef TARGET_PAGE_BITS_VARY
|
|
# ifdef CONFIG_ATTRIBUTE_ALIAS
|
|
/*
|
|
* We want to declare the "target_page" variable as const, which tells
|
|
* the compiler that it can cache any value that it reads across calls.
|
|
* This avoids multiple assertions and multiple reads within any one user.
|
|
*
|
|
* This works because we finish initializing the data before we ever read
|
|
* from the "target_page" symbol.
|
|
*
|
|
* This also requires that we have a non-constant symbol by which we can
|
|
* perform the actual initialization, and which forces the data to be
|
|
* allocated within writable memory. Thus "init_target_page", and we use
|
|
* that symbol exclusively in the two functions that initialize this value.
|
|
*
|
|
* The "target_page" symbol is created as an alias of "init_target_page".
|
|
*/
|
|
static TargetPageBits init_target_page;
|
|
|
|
/*
|
|
* Note that this is *not* a redundant decl, this is the definition of
|
|
* the "target_page" symbol. The syntax for this definition requires
|
|
* the use of the extern keyword. This seems to be a GCC bug in
|
|
* either the syntax for the alias attribute or in -Wredundant-decls.
|
|
*
|
|
* See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91765
|
|
*/
|
|
# pragma GCC diagnostic push
|
|
# pragma GCC diagnostic ignored "-Wredundant-decls"
|
|
|
|
extern const TargetPageBits target_page
|
|
__attribute__((alias("init_target_page")));
|
|
|
|
# pragma GCC diagnostic pop
|
|
# else
|
|
/*
|
|
* When aliases are not supported then we force two different declarations,
|
|
* by way of suppressing the header declaration with IN_EXEC_VARY.
|
|
* We assume that on such an old compiler, LTO cannot be used, and so the
|
|
* compiler cannot not detect the mismatched declarations, and all is well.
|
|
*/
|
|
TargetPageBits target_page;
|
|
# define init_target_page target_page
|
|
# endif
|
|
#endif
|
|
|
|
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 (init_target_page.bits == 0 || init_target_page.bits > bits) {
|
|
if (init_target_page.decided) {
|
|
return false;
|
|
}
|
|
init_target_page.bits = bits;
|
|
}
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
void finalize_target_page_bits(void)
|
|
{
|
|
#ifdef TARGET_PAGE_BITS_VARY
|
|
if (init_target_page.bits == 0) {
|
|
init_target_page.bits = TARGET_PAGE_BITS_MIN;
|
|
}
|
|
init_target_page.mask = (target_long)-1 << init_target_page.bits;
|
|
init_target_page.decided = true;
|
|
|
|
/*
|
|
* For the benefit of an -flto build, prevent the compiler from
|
|
* hoisting a read from target_page before we finish initializing.
|
|
*/
|
|
barrier();
|
|
#endif
|
|
}
|