diff options
-rw-r--r-- | arch/x86/xen/enlighten_pv.c | 8 | ||||
-rw-r--r-- | arch/x86/xen/xen-head.S | 4 | ||||
-rw-r--r-- | drivers/acpi/processor_perflib.c | 11 | ||||
-rw-r--r-- | drivers/xen/xen-acpi-processor.c | 30 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_dev_frontend.c | 16 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_xs.c | 4 | ||||
-rw-r--r-- | include/acpi/processor.h | 2 | ||||
-rw-r--r-- | include/xen/interface/features.h | 23 |
8 files changed, 79 insertions, 19 deletions
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 3c2c2530737e..c36d23aa6c35 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -1259,10 +1259,6 @@ asmlinkage __visible void __init xen_start_kernel(void) */ __userpte_alloc_gfp &= ~__GFP_HIGHMEM; - /* Work out if we support NX */ - get_cpu_cap(&boot_cpu_data); - x86_configure_nx(); - /* Get mfn list */ xen_build_dynamic_phys_to_machine(); @@ -1272,6 +1268,10 @@ asmlinkage __visible void __init xen_start_kernel(void) */ xen_setup_gdt(0); + /* Work out if we support NX */ + get_cpu_cap(&boot_cpu_data); + x86_configure_nx(); + xen_init_irq_ops(); /* Let's presume PV guests always boot on vCPU with id 0. */ diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S index 96f26e026783..5077ead5e59c 100644 --- a/arch/x86/xen/xen-head.S +++ b/arch/x86/xen/xen-head.S @@ -89,7 +89,9 @@ END(hypercall_page) ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .ascii "!writable_page_tables|pae_pgdir_above_4gb") ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES, - .long (1 << XENFEAT_writable_page_tables) | (1 << XENFEAT_dom0)) + .long (1 << XENFEAT_writable_page_tables) | \ + (1 << XENFEAT_dom0) | \ + (1 << XENFEAT_linux_rsdp_unrestricted)) ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes") ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic") ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index c7cf48ad5cb9..a651ab3490d8 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -533,7 +533,7 @@ int acpi_processor_notify_smm(struct module *calling_module) EXPORT_SYMBOL(acpi_processor_notify_smm); -static int acpi_processor_get_psd(struct acpi_processor *pr) +int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain) { int result = 0; acpi_status status = AE_OK; @@ -541,9 +541,8 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"}; struct acpi_buffer state = {0, NULL}; union acpi_object *psd = NULL; - struct acpi_psd_package *pdomain; - status = acpi_evaluate_object(pr->handle, "_PSD", NULL, &buffer); + status = acpi_evaluate_object(handle, "_PSD", NULL, &buffer); if (ACPI_FAILURE(status)) { return -ENODEV; } @@ -561,8 +560,6 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) goto end; } - pdomain = &(pr->performance->domain_info); - state.length = sizeof(struct acpi_psd_package); state.pointer = pdomain; @@ -597,6 +594,7 @@ end: kfree(buffer.pointer); return result; } +EXPORT_SYMBOL(acpi_processor_get_psd); int acpi_processor_preregister_performance( struct acpi_processor_performance __percpu *performance) @@ -645,7 +643,8 @@ int acpi_processor_preregister_performance( pr->performance = per_cpu_ptr(performance, i); cpumask_set_cpu(i, pr->performance->shared_cpu_map); - if (acpi_processor_get_psd(pr)) { + pdomain = &(pr->performance->domain_info); + if (acpi_processor_get_psd(pr->handle, pdomain)) { retval = -EINVAL; continue; } diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 23e391d3ec01..b29f4e40851f 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -53,6 +53,8 @@ static unsigned long *acpi_ids_done; static unsigned long *acpi_id_present; /* And if there is an _CST definition (or a PBLK) for the ACPI IDs */ static unsigned long *acpi_id_cst_present; +/* Which ACPI P-State dependencies for a enumerated processor */ +static struct acpi_psd_package *acpi_psd; static int push_cxx_to_hypervisor(struct acpi_processor *_pr) { @@ -362,9 +364,9 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv) } /* There are more ACPI Processor objects than in x2APIC or MADT. * This can happen with incorrect ACPI SSDT declerations. */ - if (acpi_id > nr_acpi_bits) { - pr_debug("We only have %u, trying to set %u\n", - nr_acpi_bits, acpi_id); + if (acpi_id >= nr_acpi_bits) { + pr_debug("max acpi id %u, trying to set %u\n", + nr_acpi_bits - 1, acpi_id); return AE_OK; } /* OK, There is a ACPI Processor object */ @@ -372,6 +374,13 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv) pr_debug("ACPI CPU%u w/ PBLK:0x%lx\n", acpi_id, (unsigned long)pblk); + /* It has P-state dependencies */ + if (!acpi_processor_get_psd(handle, &acpi_psd[acpi_id])) { + pr_debug("ACPI CPU%u w/ PST:coord_type = %llu domain = %llu\n", + acpi_id, acpi_psd[acpi_id].coord_type, + acpi_psd[acpi_id].domain); + } + status = acpi_evaluate_object(handle, "_CST", NULL, &buffer); if (ACPI_FAILURE(status)) { if (!pblk) @@ -405,6 +414,14 @@ static int check_acpi_ids(struct acpi_processor *pr_backup) return -ENOMEM; } + acpi_psd = kcalloc(nr_acpi_bits, sizeof(struct acpi_psd_package), + GFP_KERNEL); + if (!acpi_psd) { + kfree(acpi_id_present); + kfree(acpi_id_cst_present); + return -ENOMEM; + } + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, read_acpi_id, NULL, NULL, NULL); @@ -417,6 +434,12 @@ upload: pr_backup->acpi_id = i; /* Mask out C-states if there are no _CST or PBLK */ pr_backup->flags.power = test_bit(i, acpi_id_cst_present); + /* num_entries is non-zero if we evaluated _PSD */ + if (acpi_psd[i].num_entries) { + memcpy(&pr_backup->performance->domain_info, + &acpi_psd[i], + sizeof(struct acpi_psd_package)); + } (void)upload_pm_data(pr_backup); } } @@ -566,6 +589,7 @@ static void __exit xen_acpi_processor_exit(void) kfree(acpi_ids_done); kfree(acpi_id_present); kfree(acpi_id_cst_present); + kfree(acpi_psd); for_each_possible_cpu(i) acpi_processor_unregister_performance(i); diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index a493e99bed21..0d6d9264d6a9 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -365,7 +365,7 @@ void xenbus_dev_queue_reply(struct xb_req_data *req) if (WARN_ON(rc)) goto out; } - } else if (req->msg.type == XS_TRANSACTION_END) { + } else if (req->type == XS_TRANSACTION_END) { trans = xenbus_get_transaction(u, req->msg.tx_id); if (WARN_ON(!trans)) goto out; @@ -429,6 +429,10 @@ static int xenbus_write_transaction(unsigned msg_type, { int rc; struct xenbus_transaction_holder *trans = NULL; + struct { + struct xsd_sockmsg hdr; + char body[]; + } *msg = (void *)u->u.buffer; if (msg_type == XS_TRANSACTION_START) { trans = kzalloc(sizeof(*trans), GFP_KERNEL); @@ -437,11 +441,15 @@ static int xenbus_write_transaction(unsigned msg_type, goto out; } list_add(&trans->list, &u->transactions); - } else if (u->u.msg.tx_id != 0 && - !xenbus_get_transaction(u, u->u.msg.tx_id)) + } else if (msg->hdr.tx_id != 0 && + !xenbus_get_transaction(u, msg->hdr.tx_id)) return xenbus_command_reply(u, XS_ERROR, "ENOENT"); + else if (msg_type == XS_TRANSACTION_END && + !(msg->hdr.len == 2 && + (!strcmp(msg->body, "T") || !strcmp(msg->body, "F")))) + return xenbus_command_reply(u, XS_ERROR, "EINVAL"); - rc = xenbus_dev_request_and_reply(&u->u.msg, u); + rc = xenbus_dev_request_and_reply(&msg->hdr, u); if (rc && trans) { list_del(&trans->list); kfree(trans); diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index 3f3b29398ab8..49a3874ae6bb 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -140,7 +140,9 @@ void xs_request_exit(struct xb_req_data *req) spin_lock(&xs_state_lock); xs_state_users--; if ((req->type == XS_TRANSACTION_START && req->msg.type == XS_ERROR) || - req->type == XS_TRANSACTION_END) + (req->type == XS_TRANSACTION_END && + !WARN_ON_ONCE(req->msg.type == XS_ERROR && + !strcmp(req->body, "ENOENT")))) xs_state_users--; spin_unlock(&xs_state_lock); diff --git a/include/acpi/processor.h b/include/acpi/processor.h index d591bb77f592..40a916efd7c0 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -254,6 +254,8 @@ int acpi_processor_pstate_control(void); /* note: this locks both the calling module and the processor module if a _PPC object exists, rmmod is disallowed then */ int acpi_processor_notify_smm(struct module *calling_module); +int acpi_processor_get_psd(acpi_handle handle, + struct acpi_psd_package *pdomain); /* parsing the _P* objects. */ extern int acpi_processor_get_performance_info(struct acpi_processor *pr); diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h index 9b0eb574f0d1..6d1384abfbdf 100644 --- a/include/xen/interface/features.h +++ b/include/xen/interface/features.h @@ -42,6 +42,9 @@ /* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */ #define XENFEAT_mmu_pt_update_preserve_ad 5 +/* x86: Does this Xen host support the MMU_{CLEAR,COPY}_PAGE hypercall? */ +#define XENFEAT_highmem_assist 6 + /* * If set, GNTTABOP_map_grant_ref honors flags to be placed into guest kernel * available pte bits. @@ -60,6 +63,26 @@ /* operation as Dom0 is supported */ #define XENFEAT_dom0 11 +/* Xen also maps grant references at pfn = mfn. + * This feature flag is deprecated and should not be used. +#define XENFEAT_grant_map_identity 12 + */ + +/* Guest can use XENMEMF_vnode to specify virtual node for memory op. */ +#define XENFEAT_memory_op_vnode_supported 13 + +/* arm: Hypervisor supports ARM SMC calling convention. */ +#define XENFEAT_ARM_SMCCC_supported 14 + +/* + * x86/PVH: If set, ACPI RSDP can be placed at any address. Otherwise RSDP + * must be located in lower 1MB, as required by ACPI Specification for IA-PC + * systems. + * This feature flag is only consulted if XEN_ELFNOTE_GUEST_OS contains + * the "linux" string. + */ +#define XENFEAT_linux_rsdp_unrestricted 15 + #define XENFEAT_NR_SUBMAPS 1 #endif /* __XEN_PUBLIC_FEATURES_H__ */ |