Browse Source

Merge tag 'for-linus-4.17-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen fixes from Juergen Gross:
 "A few fixes of Xen related core code and drivers"

* tag 'for-linus-4.17-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen/pvh: Indicate XENFEAT_linux_rsdp_unrestricted to Xen
  xen/acpi: off by one in read_acpi_id()
  xen/acpi: upload _PSD info for non Dom0 CPUs too
  x86/xen: Delay get_cpu_cap until stack canary is established
  xen: xenbus_dev_frontend: Verify body of XS_TRANSACTION_END
  xen: xenbus: Catch closing of non existent transactions
  xen: xenbus_dev_frontend: Fix XS_TRANSACTION_END handling
Linus Torvalds 7 years ago
parent
commit
67a7a8fff8

+ 4 - 4
arch/x86/xen/enlighten_pv.c

@@ -1259,10 +1259,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
 	 */
 	 */
 	__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
 	__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
 
 
-	/* Work out if we support NX */
-	get_cpu_cap(&boot_cpu_data);
-	x86_configure_nx();
-
 	/* Get mfn list */
 	/* Get mfn list */
 	xen_build_dynamic_phys_to_machine();
 	xen_build_dynamic_phys_to_machine();
 
 
@@ -1272,6 +1268,10 @@ asmlinkage __visible void __init xen_start_kernel(void)
 	 */
 	 */
 	xen_setup_gdt(0);
 	xen_setup_gdt(0);
 
 
+	/* Work out if we support NX */
+	get_cpu_cap(&boot_cpu_data);
+	x86_configure_nx();
+
 	xen_init_irq_ops();
 	xen_init_irq_ops();
 
 
 	/* Let's presume PV guests always boot on vCPU with id 0. */
 	/* Let's presume PV guests always boot on vCPU with id 0. */

+ 3 - 1
arch/x86/xen/xen-head.S

@@ -89,7 +89,9 @@ END(hypercall_page)
 	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,
 	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,
 		.ascii "!writable_page_tables|pae_pgdir_above_4gb")
 		.ascii "!writable_page_tables|pae_pgdir_above_4gb")
 	ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES,
 	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_PAE_MODE,       .asciz "yes")
 	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")
 	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")
 	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,
 	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,

+ 5 - 6
drivers/acpi/processor_perflib.c

@@ -533,7 +533,7 @@ int acpi_processor_notify_smm(struct module *calling_module)
 
 
 EXPORT_SYMBOL(acpi_processor_notify_smm);
 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;
 	int result = 0;
 	acpi_status status = AE_OK;
 	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 format = {sizeof("NNNNN"), "NNNNN"};
 	struct acpi_buffer state = {0, NULL};
 	struct acpi_buffer state = {0, NULL};
 	union acpi_object  *psd = 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)) {
 	if (ACPI_FAILURE(status)) {
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
@@ -561,8 +560,6 @@ static int acpi_processor_get_psd(struct acpi_processor	*pr)
 		goto end;
 		goto end;
 	}
 	}
 
 
-	pdomain = &(pr->performance->domain_info);
-
 	state.length = sizeof(struct acpi_psd_package);
 	state.length = sizeof(struct acpi_psd_package);
 	state.pointer = pdomain;
 	state.pointer = pdomain;
 
 
@@ -597,6 +594,7 @@ end:
 	kfree(buffer.pointer);
 	kfree(buffer.pointer);
 	return result;
 	return result;
 }
 }
+EXPORT_SYMBOL(acpi_processor_get_psd);
 
 
 int acpi_processor_preregister_performance(
 int acpi_processor_preregister_performance(
 		struct acpi_processor_performance __percpu *performance)
 		struct acpi_processor_performance __percpu *performance)
@@ -645,7 +643,8 @@ int acpi_processor_preregister_performance(
 
 
 		pr->performance = per_cpu_ptr(performance, i);
 		pr->performance = per_cpu_ptr(performance, i);
 		cpumask_set_cpu(i, pr->performance->shared_cpu_map);
 		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;
 			retval = -EINVAL;
 			continue;
 			continue;
 		}
 		}

+ 27 - 3
drivers/xen/xen-acpi-processor.c

@@ -53,6 +53,8 @@ static unsigned long *acpi_ids_done;
 static unsigned long *acpi_id_present;
 static unsigned long *acpi_id_present;
 /* And if there is an _CST definition (or a PBLK) for the ACPI IDs */
 /* And if there is an _CST definition (or a PBLK) for the ACPI IDs */
 static unsigned long *acpi_id_cst_present;
 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)
 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.
 	/* There are more ACPI Processor objects than in x2APIC or MADT.
 	 * This can happen with incorrect ACPI SSDT declerations. */
 	 * 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;
 		return AE_OK;
 	}
 	}
 	/* OK, There is a ACPI Processor object */
 	/* 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);
 	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);
 	status = acpi_evaluate_object(handle, "_CST", NULL, &buffer);
 	if (ACPI_FAILURE(status)) {
 	if (ACPI_FAILURE(status)) {
 		if (!pblk)
 		if (!pblk)
@@ -405,6 +414,14 @@ static int check_acpi_ids(struct acpi_processor *pr_backup)
 		return -ENOMEM;
 		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_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
 			    ACPI_UINT32_MAX,
 			    read_acpi_id, NULL, NULL, NULL);
 			    read_acpi_id, NULL, NULL, NULL);
@@ -417,6 +434,12 @@ upload:
 			pr_backup->acpi_id = i;
 			pr_backup->acpi_id = i;
 			/* Mask out C-states if there are no _CST or PBLK */
 			/* Mask out C-states if there are no _CST or PBLK */
 			pr_backup->flags.power = test_bit(i, acpi_id_cst_present);
 			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);
 			(void)upload_pm_data(pr_backup);
 		}
 		}
 	}
 	}
@@ -566,6 +589,7 @@ static void __exit xen_acpi_processor_exit(void)
 	kfree(acpi_ids_done);
 	kfree(acpi_ids_done);
 	kfree(acpi_id_present);
 	kfree(acpi_id_present);
 	kfree(acpi_id_cst_present);
 	kfree(acpi_id_cst_present);
+	kfree(acpi_psd);
 	for_each_possible_cpu(i)
 	for_each_possible_cpu(i)
 		acpi_processor_unregister_performance(i);
 		acpi_processor_unregister_performance(i);
 
 

+ 12 - 4
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))
 			if (WARN_ON(rc))
 				goto out;
 				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);
 		trans = xenbus_get_transaction(u, req->msg.tx_id);
 		if (WARN_ON(!trans))
 		if (WARN_ON(!trans))
 			goto out;
 			goto out;
@@ -429,6 +429,10 @@ static int xenbus_write_transaction(unsigned msg_type,
 {
 {
 	int rc;
 	int rc;
 	struct xenbus_transaction_holder *trans = NULL;
 	struct xenbus_transaction_holder *trans = NULL;
+	struct {
+		struct xsd_sockmsg hdr;
+		char body[];
+	} *msg = (void *)u->u.buffer;
 
 
 	if (msg_type == XS_TRANSACTION_START) {
 	if (msg_type == XS_TRANSACTION_START) {
 		trans = kzalloc(sizeof(*trans), GFP_KERNEL);
 		trans = kzalloc(sizeof(*trans), GFP_KERNEL);
@@ -437,11 +441,15 @@ static int xenbus_write_transaction(unsigned msg_type,
 			goto out;
 			goto out;
 		}
 		}
 		list_add(&trans->list, &u->transactions);
 		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");
 		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) {
 	if (rc && trans) {
 		list_del(&trans->list);
 		list_del(&trans->list);
 		kfree(trans);
 		kfree(trans);

+ 3 - 1
drivers/xen/xenbus/xenbus_xs.c

@@ -140,7 +140,9 @@ void xs_request_exit(struct xb_req_data *req)
 	spin_lock(&xs_state_lock);
 	spin_lock(&xs_state_lock);
 	xs_state_users--;
 	xs_state_users--;
 	if ((req->type == XS_TRANSACTION_START && req->msg.type == XS_ERROR) ||
 	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--;
 		xs_state_users--;
 	spin_unlock(&xs_state_lock);
 	spin_unlock(&xs_state_lock);
 
 

+ 2 - 0
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
 /* note: this locks both the calling module and the processor module
          if a _PPC object exists, rmmod is disallowed then */
          if a _PPC object exists, rmmod is disallowed then */
 int acpi_processor_notify_smm(struct module *calling_module);
 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. */
 /* parsing the _P* objects. */
 extern int acpi_processor_get_performance_info(struct acpi_processor *pr);
 extern int acpi_processor_get_performance_info(struct acpi_processor *pr);

+ 23 - 0
include/xen/interface/features.h

@@ -42,6 +42,9 @@
 /* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */
 /* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */
 #define XENFEAT_mmu_pt_update_preserve_ad  5
 #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
  * If set, GNTTABOP_map_grant_ref honors flags to be placed into guest kernel
  * available pte bits.
  * available pte bits.
@@ -60,6 +63,26 @@
 /* operation as Dom0 is supported */
 /* operation as Dom0 is supported */
 #define XENFEAT_dom0                      11
 #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
 #define XENFEAT_NR_SUBMAPS 1
 
 
 #endif /* __XEN_PUBLIC_FEATURES_H__ */
 #endif /* __XEN_PUBLIC_FEATURES_H__ */