xen: fixes and cleanups for 5.4-rc2
-----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQRTLbB6QfY48x44uB6AXGG7T9hjvgUCXZbQhwAKCRCAXGG7T9hj vh03AP9mOLNY8r16u6a+Iy0YVccTaeiQiquG6HgFVEGX2Ki38gD/Xf5u6bPRYBts uSRL/eYDvtfU4YGGMjogn20Fdzhc5Ak= =EkVp -----END PGP SIGNATURE----- Merge tag 'for-linus-5.4-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip Pull xen fixes and cleanups from Juergen Gross: - a fix in the Xen balloon driver avoiding hitting a BUG_ON() in some cases, plus a follow-on cleanup series for that driver - a patch for introducing non-blocking EFI callbacks in Xen's EFI driver, plu a cleanup patch for Xen EFI handling merging the x86 and ARM arch specific initialization into the Xen EFI driver - a fix of the Xen xenbus driver avoiding a self-deadlock when cleaning up after a user process has died - a fix for Xen on ARM after removal of ZONE_DMA - a cleanup patch for avoiding build warnings for Xen on ARM * tag 'for-linus-5.4-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/xenbus: fix self-deadlock after killing user process xen/efi: have a common runtime setup function arm: xen: mm: use __GPF_DMA32 for arm64 xen/balloon: Clear PG_offline in balloon_retrieve() xen/balloon: Mark pages PG_offline in balloon_append() xen/balloon: Drop __balloon_append() xen/balloon: Set pages PageOffline() in balloon_add_region() ARM: xen: unexport HYPERVISOR_platform_op function xen/efi: Set nonblocking callbacks
This commit is contained in:
commit
50dfd03d95
@ -1,6 +0,0 @@
|
|||||||
#ifndef _ASM_XEN_OPS_H
|
|
||||||
#define _ASM_XEN_OPS_H
|
|
||||||
|
|
||||||
void xen_efi_runtime_setup(void);
|
|
||||||
|
|
||||||
#endif /* _ASM_XEN_OPS_H */
|
|
@ -1,3 +1,2 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
obj-y := enlighten.o hypercall.o grant-table.o p2m.o mm.o
|
obj-y := enlighten.o hypercall.o grant-table.o p2m.o mm.o
|
||||||
obj-$(CONFIG_XEN_EFI) += efi.o
|
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2015, Linaro Limited, Shannon Zhao
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/efi.h>
|
|
||||||
#include <xen/xen-ops.h>
|
|
||||||
#include <asm/xen/xen-ops.h>
|
|
||||||
|
|
||||||
/* Set XEN EFI runtime services function pointers. Other fields of struct efi,
|
|
||||||
* e.g. efi.systab, will be set like normal EFI.
|
|
||||||
*/
|
|
||||||
void __init xen_efi_runtime_setup(void)
|
|
||||||
{
|
|
||||||
efi.get_time = xen_efi_get_time;
|
|
||||||
efi.set_time = xen_efi_set_time;
|
|
||||||
efi.get_wakeup_time = xen_efi_get_wakeup_time;
|
|
||||||
efi.set_wakeup_time = xen_efi_set_wakeup_time;
|
|
||||||
efi.get_variable = xen_efi_get_variable;
|
|
||||||
efi.get_next_variable = xen_efi_get_next_variable;
|
|
||||||
efi.set_variable = xen_efi_set_variable;
|
|
||||||
efi.query_variable_info = xen_efi_query_variable_info;
|
|
||||||
efi.update_capsule = xen_efi_update_capsule;
|
|
||||||
efi.query_capsule_caps = xen_efi_query_capsule_caps;
|
|
||||||
efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
|
|
||||||
efi.reset_system = xen_efi_reset_system;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_runtime_setup);
|
|
@ -15,7 +15,6 @@
|
|||||||
#include <xen/xen-ops.h>
|
#include <xen/xen-ops.h>
|
||||||
#include <asm/xen/hypervisor.h>
|
#include <asm/xen/hypervisor.h>
|
||||||
#include <asm/xen/hypercall.h>
|
#include <asm/xen/hypercall.h>
|
||||||
#include <asm/xen/xen-ops.h>
|
|
||||||
#include <asm/system_misc.h>
|
#include <asm/system_misc.h>
|
||||||
#include <asm/efi.h>
|
#include <asm/efi.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
@ -437,7 +436,7 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
|
|||||||
EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
|
EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
|
||||||
EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);
|
EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);
|
||||||
EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op);
|
EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op);
|
||||||
EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op);
|
EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op_raw);
|
||||||
EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
|
EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
|
||||||
EXPORT_SYMBOL_GPL(HYPERVISOR_vm_assist);
|
EXPORT_SYMBOL_GPL(HYPERVISOR_vm_assist);
|
||||||
EXPORT_SYMBOL_GPL(HYPERVISOR_dm_op);
|
EXPORT_SYMBOL_GPL(HYPERVISOR_dm_op);
|
||||||
|
@ -28,7 +28,10 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order)
|
|||||||
|
|
||||||
for_each_memblock(memory, reg) {
|
for_each_memblock(memory, reg) {
|
||||||
if (reg->base < (phys_addr_t)0xffffffff) {
|
if (reg->base < (phys_addr_t)0xffffffff) {
|
||||||
flags |= __GFP_DMA;
|
if (IS_ENABLED(CONFIG_ZONE_DMA32))
|
||||||
|
flags |= __GFP_DMA32;
|
||||||
|
else
|
||||||
|
flags |= __GFP_DMA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef _ASM_XEN_OPS_H
|
|
||||||
#define _ASM_XEN_OPS_H
|
|
||||||
|
|
||||||
void xen_efi_runtime_setup(void);
|
|
||||||
|
|
||||||
#endif /* _ASM_XEN_OPS_H */
|
|
@ -1,4 +1,3 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
xen-arm-y += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o mm.o)
|
xen-arm-y += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o mm.o)
|
||||||
obj-y := xen-arm.o hypercall.o
|
obj-y := xen-arm.o hypercall.o
|
||||||
obj-$(CONFIG_XEN_EFI) += $(addprefix ../../arm/xen/, efi.o)
|
|
||||||
|
@ -57,19 +57,7 @@ static efi_system_table_t __init *xen_efi_probe(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Here we know that Xen runs on EFI platform. */
|
/* Here we know that Xen runs on EFI platform. */
|
||||||
|
xen_efi_runtime_setup();
|
||||||
efi.get_time = xen_efi_get_time;
|
|
||||||
efi.set_time = xen_efi_set_time;
|
|
||||||
efi.get_wakeup_time = xen_efi_get_wakeup_time;
|
|
||||||
efi.set_wakeup_time = xen_efi_set_wakeup_time;
|
|
||||||
efi.get_variable = xen_efi_get_variable;
|
|
||||||
efi.get_next_variable = xen_efi_get_next_variable;
|
|
||||||
efi.set_variable = xen_efi_set_variable;
|
|
||||||
efi.query_variable_info = xen_efi_query_variable_info;
|
|
||||||
efi.update_capsule = xen_efi_update_capsule;
|
|
||||||
efi.query_capsule_caps = xen_efi_query_capsule_caps;
|
|
||||||
efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
|
|
||||||
efi.reset_system = xen_efi_reset_system;
|
|
||||||
|
|
||||||
efi_systab_xen.tables = info->cfg.addr;
|
efi_systab_xen.tables = info->cfg.addr;
|
||||||
efi_systab_xen.nr_tables = info->cfg.nent;
|
efi_systab_xen.nr_tables = info->cfg.nent;
|
||||||
|
@ -156,8 +156,10 @@ static DECLARE_DELAYED_WORK(balloon_worker, balloon_process);
|
|||||||
(GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
|
(GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
|
||||||
|
|
||||||
/* balloon_append: add the given page to the balloon. */
|
/* balloon_append: add the given page to the balloon. */
|
||||||
static void __balloon_append(struct page *page)
|
static void balloon_append(struct page *page)
|
||||||
{
|
{
|
||||||
|
__SetPageOffline(page);
|
||||||
|
|
||||||
/* Lowmem is re-populated first, so highmem pages go at list tail. */
|
/* Lowmem is re-populated first, so highmem pages go at list tail. */
|
||||||
if (PageHighMem(page)) {
|
if (PageHighMem(page)) {
|
||||||
list_add_tail(&page->lru, &ballooned_pages);
|
list_add_tail(&page->lru, &ballooned_pages);
|
||||||
@ -169,11 +171,6 @@ static void __balloon_append(struct page *page)
|
|||||||
wake_up(&balloon_wq);
|
wake_up(&balloon_wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void balloon_append(struct page *page)
|
|
||||||
{
|
|
||||||
__balloon_append(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
|
/* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
|
||||||
static struct page *balloon_retrieve(bool require_lowmem)
|
static struct page *balloon_retrieve(bool require_lowmem)
|
||||||
{
|
{
|
||||||
@ -192,6 +189,7 @@ static struct page *balloon_retrieve(bool require_lowmem)
|
|||||||
else
|
else
|
||||||
balloon_stats.balloon_low--;
|
balloon_stats.balloon_low--;
|
||||||
|
|
||||||
|
__ClearPageOffline(page);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,8 +375,7 @@ static void xen_online_page(struct page *page, unsigned int order)
|
|||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
p = pfn_to_page(start_pfn + i);
|
p = pfn_to_page(start_pfn + i);
|
||||||
__online_page_set_limits(p);
|
__online_page_set_limits(p);
|
||||||
__SetPageOffline(p);
|
balloon_append(p);
|
||||||
__balloon_append(p);
|
|
||||||
}
|
}
|
||||||
mutex_unlock(&balloon_mutex);
|
mutex_unlock(&balloon_mutex);
|
||||||
}
|
}
|
||||||
@ -444,7 +441,6 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
|
|||||||
xenmem_reservation_va_mapping_update(1, &page, &frame_list[i]);
|
xenmem_reservation_va_mapping_update(1, &page, &frame_list[i]);
|
||||||
|
|
||||||
/* Relinquish the page back to the allocator. */
|
/* Relinquish the page back to the allocator. */
|
||||||
__ClearPageOffline(page);
|
|
||||||
free_reserved_page(page);
|
free_reserved_page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +467,6 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
|
|||||||
state = BP_EAGAIN;
|
state = BP_EAGAIN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
__SetPageOffline(page);
|
|
||||||
adjust_managed_page_count(page, -1);
|
adjust_managed_page_count(page, -1);
|
||||||
xenmem_reservation_scrub_page(page);
|
xenmem_reservation_scrub_page(page);
|
||||||
list_add(&page->lru, &pages);
|
list_add(&page->lru, &pages);
|
||||||
@ -611,7 +606,6 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages)
|
|||||||
while (pgno < nr_pages) {
|
while (pgno < nr_pages) {
|
||||||
page = balloon_retrieve(true);
|
page = balloon_retrieve(true);
|
||||||
if (page) {
|
if (page) {
|
||||||
__ClearPageOffline(page);
|
|
||||||
pages[pgno++] = page;
|
pages[pgno++] = page;
|
||||||
#ifdef CONFIG_XEN_HAVE_PVMMU
|
#ifdef CONFIG_XEN_HAVE_PVMMU
|
||||||
/*
|
/*
|
||||||
@ -653,10 +647,8 @@ void free_xenballooned_pages(int nr_pages, struct page **pages)
|
|||||||
mutex_lock(&balloon_mutex);
|
mutex_lock(&balloon_mutex);
|
||||||
|
|
||||||
for (i = 0; i < nr_pages; i++) {
|
for (i = 0; i < nr_pages; i++) {
|
||||||
if (pages[i]) {
|
if (pages[i])
|
||||||
__SetPageOffline(pages[i]);
|
|
||||||
balloon_append(pages[i]);
|
balloon_append(pages[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
balloon_stats.target_unpopulated -= nr_pages;
|
balloon_stats.target_unpopulated -= nr_pages;
|
||||||
@ -674,7 +666,6 @@ static void __init balloon_add_region(unsigned long start_pfn,
|
|||||||
unsigned long pages)
|
unsigned long pages)
|
||||||
{
|
{
|
||||||
unsigned long pfn, extra_pfn_end;
|
unsigned long pfn, extra_pfn_end;
|
||||||
struct page *page;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the amount of usable memory has been limited (e.g., with
|
* If the amount of usable memory has been limited (e.g., with
|
||||||
@ -684,11 +675,10 @@ static void __init balloon_add_region(unsigned long start_pfn,
|
|||||||
extra_pfn_end = min(max_pfn, start_pfn + pages);
|
extra_pfn_end = min(max_pfn, start_pfn + pages);
|
||||||
|
|
||||||
for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) {
|
for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) {
|
||||||
page = pfn_to_page(pfn);
|
|
||||||
/* totalram_pages and totalhigh_pages do not
|
/* totalram_pages and totalhigh_pages do not
|
||||||
include the boot-time balloon extension, so
|
include the boot-time balloon extension, so
|
||||||
don't subtract from it. */
|
don't subtract from it. */
|
||||||
__balloon_append(page);
|
balloon_append(pfn_to_page(pfn));
|
||||||
}
|
}
|
||||||
|
|
||||||
balloon_stats.total_pages += extra_pfn_end - start_pfn;
|
balloon_stats.total_pages += extra_pfn_end - start_pfn;
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
#define efi_data(op) (op.u.efi_runtime_call)
|
#define efi_data(op) (op.u.efi_runtime_call)
|
||||||
|
|
||||||
efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
|
static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(get_time);
|
struct xen_platform_op op = INIT_EFI_OP(get_time);
|
||||||
|
|
||||||
@ -61,9 +61,8 @@ efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_get_time);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_set_time(efi_time_t *tm)
|
static efi_status_t xen_efi_set_time(efi_time_t *tm)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(set_time);
|
struct xen_platform_op op = INIT_EFI_OP(set_time);
|
||||||
|
|
||||||
@ -75,10 +74,10 @@ efi_status_t xen_efi_set_time(efi_time_t *tm)
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_set_time);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
|
static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled,
|
||||||
efi_time_t *tm)
|
efi_bool_t *pending,
|
||||||
|
efi_time_t *tm)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time);
|
struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time);
|
||||||
|
|
||||||
@ -98,9 +97,8 @@ efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_get_wakeup_time);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
|
static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(set_wakeup_time);
|
struct xen_platform_op op = INIT_EFI_OP(set_wakeup_time);
|
||||||
|
|
||||||
@ -117,11 +115,10 @@ efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_set_wakeup_time);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
|
static efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
|
||||||
u32 *attr, unsigned long *data_size,
|
u32 *attr, unsigned long *data_size,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(get_variable);
|
struct xen_platform_op op = INIT_EFI_OP(get_variable);
|
||||||
|
|
||||||
@ -141,11 +138,10 @@ efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_get_variable);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
|
static efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
|
||||||
efi_char16_t *name,
|
efi_char16_t *name,
|
||||||
efi_guid_t *vendor)
|
efi_guid_t *vendor)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(get_next_variable_name);
|
struct xen_platform_op op = INIT_EFI_OP(get_next_variable_name);
|
||||||
|
|
||||||
@ -165,11 +161,10 @@ efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_get_next_variable);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
|
static efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
|
||||||
u32 attr, unsigned long data_size,
|
u32 attr, unsigned long data_size,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(set_variable);
|
struct xen_platform_op op = INIT_EFI_OP(set_variable);
|
||||||
|
|
||||||
@ -186,11 +181,10 @@ efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_set_variable);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
|
static efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
|
||||||
u64 *remaining_space,
|
u64 *remaining_space,
|
||||||
u64 *max_variable_size)
|
u64 *max_variable_size)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(query_variable_info);
|
struct xen_platform_op op = INIT_EFI_OP(query_variable_info);
|
||||||
|
|
||||||
@ -208,9 +202,8 @@ efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_query_variable_info);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
|
static efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count);
|
struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count);
|
||||||
|
|
||||||
@ -221,10 +214,9 @@ efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_get_next_high_mono_count);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
|
static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
|
||||||
unsigned long count, unsigned long sg_list)
|
unsigned long count, unsigned long sg_list)
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(update_capsule);
|
struct xen_platform_op op = INIT_EFI_OP(update_capsule);
|
||||||
|
|
||||||
@ -241,11 +233,9 @@ efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_update_capsule);
|
|
||||||
|
|
||||||
efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
|
static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
|
||||||
unsigned long count, u64 *max_size,
|
unsigned long count, u64 *max_size, int *reset_type)
|
||||||
int *reset_type)
|
|
||||||
{
|
{
|
||||||
struct xen_platform_op op = INIT_EFI_OP(query_capsule_capabilities);
|
struct xen_platform_op op = INIT_EFI_OP(query_capsule_capabilities);
|
||||||
|
|
||||||
@ -264,10 +254,9 @@ efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
|
|||||||
|
|
||||||
return efi_data(op).status;
|
return efi_data(op).status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_query_capsule_caps);
|
|
||||||
|
|
||||||
void xen_efi_reset_system(int reset_type, efi_status_t status,
|
static void xen_efi_reset_system(int reset_type, efi_status_t status,
|
||||||
unsigned long data_size, efi_char16_t *data)
|
unsigned long data_size, efi_char16_t *data)
|
||||||
{
|
{
|
||||||
switch (reset_type) {
|
switch (reset_type) {
|
||||||
case EFI_RESET_COLD:
|
case EFI_RESET_COLD:
|
||||||
@ -281,4 +270,25 @@ void xen_efi_reset_system(int reset_type, efi_status_t status,
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xen_efi_reset_system);
|
|
||||||
|
/*
|
||||||
|
* Set XEN EFI runtime services function pointers. Other fields of struct efi,
|
||||||
|
* e.g. efi.systab, will be set like normal EFI.
|
||||||
|
*/
|
||||||
|
void __init xen_efi_runtime_setup(void)
|
||||||
|
{
|
||||||
|
efi.get_time = xen_efi_get_time;
|
||||||
|
efi.set_time = xen_efi_set_time;
|
||||||
|
efi.get_wakeup_time = xen_efi_get_wakeup_time;
|
||||||
|
efi.set_wakeup_time = xen_efi_set_wakeup_time;
|
||||||
|
efi.get_variable = xen_efi_get_variable;
|
||||||
|
efi.get_next_variable = xen_efi_get_next_variable;
|
||||||
|
efi.set_variable = xen_efi_set_variable;
|
||||||
|
efi.set_variable_nonblocking = xen_efi_set_variable;
|
||||||
|
efi.query_variable_info = xen_efi_query_variable_info;
|
||||||
|
efi.query_variable_info_nonblocking = xen_efi_query_variable_info;
|
||||||
|
efi.update_capsule = xen_efi_update_capsule;
|
||||||
|
efi.query_capsule_caps = xen_efi_query_capsule_caps;
|
||||||
|
efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
|
||||||
|
efi.reset_system = xen_efi_reset_system;
|
||||||
|
}
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/miscdevice.h>
|
#include <linux/miscdevice.h>
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
#include <xen/xenbus.h>
|
#include <xen/xenbus.h>
|
||||||
#include <xen/xen.h>
|
#include <xen/xen.h>
|
||||||
@ -116,6 +117,8 @@ struct xenbus_file_priv {
|
|||||||
wait_queue_head_t read_waitq;
|
wait_queue_head_t read_waitq;
|
||||||
|
|
||||||
struct kref kref;
|
struct kref kref;
|
||||||
|
|
||||||
|
struct work_struct wq;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Read out any raw xenbus messages queued up. */
|
/* Read out any raw xenbus messages queued up. */
|
||||||
@ -300,14 +303,14 @@ static void watch_fired(struct xenbus_watch *watch,
|
|||||||
mutex_unlock(&adap->dev_data->reply_mutex);
|
mutex_unlock(&adap->dev_data->reply_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xenbus_file_free(struct kref *kref)
|
static void xenbus_worker(struct work_struct *wq)
|
||||||
{
|
{
|
||||||
struct xenbus_file_priv *u;
|
struct xenbus_file_priv *u;
|
||||||
struct xenbus_transaction_holder *trans, *tmp;
|
struct xenbus_transaction_holder *trans, *tmp;
|
||||||
struct watch_adapter *watch, *tmp_watch;
|
struct watch_adapter *watch, *tmp_watch;
|
||||||
struct read_buffer *rb, *tmp_rb;
|
struct read_buffer *rb, *tmp_rb;
|
||||||
|
|
||||||
u = container_of(kref, struct xenbus_file_priv, kref);
|
u = container_of(wq, struct xenbus_file_priv, wq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No need for locking here because there are no other users,
|
* No need for locking here because there are no other users,
|
||||||
@ -333,6 +336,18 @@ static void xenbus_file_free(struct kref *kref)
|
|||||||
kfree(u);
|
kfree(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xenbus_file_free(struct kref *kref)
|
||||||
|
{
|
||||||
|
struct xenbus_file_priv *u;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We might be called in xenbus_thread().
|
||||||
|
* Use workqueue to avoid deadlock.
|
||||||
|
*/
|
||||||
|
u = container_of(kref, struct xenbus_file_priv, kref);
|
||||||
|
schedule_work(&u->wq);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xenbus_transaction_holder *xenbus_get_transaction(
|
static struct xenbus_transaction_holder *xenbus_get_transaction(
|
||||||
struct xenbus_file_priv *u, uint32_t tx_id)
|
struct xenbus_file_priv *u, uint32_t tx_id)
|
||||||
{
|
{
|
||||||
@ -650,6 +665,7 @@ static int xenbus_file_open(struct inode *inode, struct file *filp)
|
|||||||
INIT_LIST_HEAD(&u->watches);
|
INIT_LIST_HEAD(&u->watches);
|
||||||
INIT_LIST_HEAD(&u->read_buffers);
|
INIT_LIST_HEAD(&u->read_buffers);
|
||||||
init_waitqueue_head(&u->read_waitq);
|
init_waitqueue_head(&u->read_waitq);
|
||||||
|
INIT_WORK(&u->wq, xenbus_worker);
|
||||||
|
|
||||||
mutex_init(&u->reply_mutex);
|
mutex_init(&u->reply_mutex);
|
||||||
mutex_init(&u->msgbuffer_mutex);
|
mutex_init(&u->msgbuffer_mutex);
|
||||||
|
@ -212,30 +212,7 @@ int xen_xlate_map_ballooned_pages(xen_pfn_t **pfns, void **vaddr,
|
|||||||
|
|
||||||
bool xen_running_on_version_or_later(unsigned int major, unsigned int minor);
|
bool xen_running_on_version_or_later(unsigned int major, unsigned int minor);
|
||||||
|
|
||||||
efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc);
|
void xen_efi_runtime_setup(void);
|
||||||
efi_status_t xen_efi_set_time(efi_time_t *tm);
|
|
||||||
efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
|
|
||||||
efi_time_t *tm);
|
|
||||||
efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm);
|
|
||||||
efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
|
|
||||||
u32 *attr, unsigned long *data_size,
|
|
||||||
void *data);
|
|
||||||
efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
|
|
||||||
efi_char16_t *name, efi_guid_t *vendor);
|
|
||||||
efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
|
|
||||||
u32 attr, unsigned long data_size,
|
|
||||||
void *data);
|
|
||||||
efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
|
|
||||||
u64 *remaining_space,
|
|
||||||
u64 *max_variable_size);
|
|
||||||
efi_status_t xen_efi_get_next_high_mono_count(u32 *count);
|
|
||||||
efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
|
|
||||||
unsigned long count, unsigned long sg_list);
|
|
||||||
efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
|
|
||||||
unsigned long count, u64 *max_size,
|
|
||||||
int *reset_type);
|
|
||||||
void xen_efi_reset_system(int reset_type, efi_status_t status,
|
|
||||||
unsigned long data_size, efi_char16_t *data);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_PREEMPT
|
#ifdef CONFIG_PREEMPT
|
||||||
|
Loading…
Reference in New Issue
Block a user