Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaa207a0

Browse files
ausyskingregkh
authored andcommitted
mei: add connect with vtag ioctl
This IOCTL is used to associate the current file descriptorwith a FW Client (given by UUID), and virtual tag (vtag).The IOCTL opens a communication channel between a host clientand a FW client on a tagged channel. From this point on,every reader and write will communicate with the associatedFW client on the tagged channel. Upon close() the communicationis terminated.The IOCTL argument is a struct with a union that containsthe input parameter and the output parameter for this IOCTL.The input parameter is UUID of the FW Client, a vtag [0,255]The output parameter is the properties of the FW clientClients that do not support tagged connectionwill respond with -EOPNOTSUPPSigned-off-by: Alexander Usyskin <alexander.usyskin@intel.com>Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>Link:https://lore.kernel.org/r/20200818115147.2567012-12-tomas.winkler@intel.comSigned-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent224ae60 commitaa207a0

File tree

2 files changed

+243
-16
lines changed

2 files changed

+243
-16
lines changed

‎drivers/misc/mei/main.c‎

Lines changed: 194 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -395,36 +395,34 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
395395
* mei_ioctl_connect_client - the connect to fw client IOCTL function
396396
*
397397
* @file: private data of the file object
398-
* @data: IOCTL connect data, input and output parameters
398+
* @in_client_uuid: requested UUID for connection
399+
* @client: IOCTL connect data, output parameters
399400
*
400401
* Locking: called under "dev->device_lock" lock
401402
*
402403
* Return: 0 on success, <0 on failure.
403404
*/
404405
staticintmei_ioctl_connect_client(structfile*file,
405-
structmei_connect_client_data*data)
406+
constuuid_le*in_client_uuid,
407+
structmei_client*client)
406408
{
407409
structmei_device*dev;
408-
structmei_client*client;
409410
structmei_me_client*me_cl;
410411
structmei_cl*cl;
411412
intrets;
412413

413414
cl=file->private_data;
414415
dev=cl->dev;
415416

416-
if (dev->dev_state!=MEI_DEV_ENABLED)
417-
return-ENODEV;
418-
419417
if (cl->state!=MEI_FILE_INITIALIZING&&
420418
cl->state!=MEI_FILE_DISCONNECTED)
421419
return-EBUSY;
422420

423421
/* find ME client we're trying to connect to */
424-
me_cl=mei_me_cl_by_uuid(dev,&data->in_client_uuid);
422+
me_cl=mei_me_cl_by_uuid(dev,in_client_uuid);
425423
if (!me_cl) {
426424
dev_dbg(dev->dev,"Cannot connect to FW Client UUID = %pUl\n",
427-
&data->in_client_uuid);
425+
in_client_uuid);
428426
rets=-ENOTTY;
429427
gotoend;
430428
}
@@ -434,7 +432,7 @@ static int mei_ioctl_connect_client(struct file *file,
434432
!dev->allow_fixed_address : !dev->hbm_f_fa_supported;
435433
if (forbidden) {
436434
dev_dbg(dev->dev,"Connection forbidden to FW Client UUID = %pUl\n",
437-
&data->in_client_uuid);
435+
in_client_uuid);
438436
rets=-ENOTTY;
439437
gotoend;
440438
}
@@ -448,7 +446,6 @@ static int mei_ioctl_connect_client(struct file *file,
448446
me_cl->props.max_msg_length);
449447

450448
/* prepare the output buffer */
451-
client=&data->out_client_properties;
452449
client->max_msg_length=me_cl->props.max_msg_length;
453450
client->protocol_version=me_cl->props.protocol_version;
454451
dev_dbg(dev->dev,"Can connect?\n");
@@ -460,6 +457,135 @@ static int mei_ioctl_connect_client(struct file *file,
460457
returnrets;
461458
}
462459

460+
/**
461+
* mei_vt_support_check - check if client support vtags
462+
*
463+
* Locking: called under "dev->device_lock" lock
464+
*
465+
* @dev: mei_device
466+
* @uuid: client UUID
467+
*
468+
* Return:
469+
*0 - supported
470+
*-ENOTTY - no such client
471+
*-EOPNOTSUPP - vtags are not supported by client
472+
*/
473+
staticintmei_vt_support_check(structmei_device*dev,constuuid_le*uuid)
474+
{
475+
structmei_me_client*me_cl;
476+
intret;
477+
478+
if (!dev->hbm_f_vt_supported)
479+
return-EOPNOTSUPP;
480+
481+
me_cl=mei_me_cl_by_uuid(dev,uuid);
482+
if (!me_cl) {
483+
dev_dbg(dev->dev,"Cannot connect to FW Client UUID = %pUl\n",
484+
uuid);
485+
return-ENOTTY;
486+
}
487+
ret=me_cl->props.vt_supported ?0 :-EOPNOTSUPP;
488+
mei_me_cl_put(me_cl);
489+
490+
returnret;
491+
}
492+
493+
/**
494+
* mei_ioctl_connect_vtag - connect to fw client with vtag IOCTL function
495+
*
496+
* @file: private data of the file object
497+
* @in_client_uuid: requested UUID for connection
498+
* @client: IOCTL connect data, output parameters
499+
* @vtag: vm tag
500+
*
501+
* Locking: called under "dev->device_lock" lock
502+
*
503+
* Return: 0 on success, <0 on failure.
504+
*/
505+
staticintmei_ioctl_connect_vtag(structfile*file,
506+
constuuid_le*in_client_uuid,
507+
structmei_client*client,
508+
u8vtag)
509+
{
510+
structmei_device*dev;
511+
structmei_cl*cl;
512+
structmei_cl*pos;
513+
structmei_cl_vtag*cl_vtag;
514+
515+
cl=file->private_data;
516+
dev=cl->dev;
517+
518+
dev_dbg(dev->dev,"FW Client %pUl vtag %d\n",in_client_uuid,vtag);
519+
520+
switch (cl->state) {
521+
caseMEI_FILE_DISCONNECTED:
522+
if (mei_cl_vtag_by_fp(cl,file)!=vtag) {
523+
dev_err(dev->dev,"reconnect with different vtag\n");
524+
return-EINVAL;
525+
}
526+
break;
527+
caseMEI_FILE_INITIALIZING:
528+
/* malicious connect from another thread may push vtag */
529+
if (!IS_ERR(mei_cl_fp_by_vtag(cl,vtag))) {
530+
dev_err(dev->dev,"vtag already filled\n");
531+
return-EINVAL;
532+
}
533+
534+
list_for_each_entry(pos,&dev->file_list,link) {
535+
if (pos==cl)
536+
continue;
537+
if (!pos->me_cl)
538+
continue;
539+
540+
/* only search for same UUID */
541+
if (uuid_le_cmp(*mei_cl_uuid(pos),*in_client_uuid))
542+
continue;
543+
544+
/* if tag already exist try another fp */
545+
if (!IS_ERR(mei_cl_fp_by_vtag(pos,vtag)))
546+
continue;
547+
548+
/* replace cl with acquired one */
549+
dev_dbg(dev->dev,"replacing with existing cl\n");
550+
mei_cl_unlink(cl);
551+
kfree(cl);
552+
file->private_data=pos;
553+
cl=pos;
554+
break;
555+
}
556+
557+
cl_vtag=mei_cl_vtag_alloc(file,vtag);
558+
if (IS_ERR(cl_vtag))
559+
return-ENOMEM;
560+
561+
list_add_tail(&cl_vtag->list,&cl->vtag_map);
562+
break;
563+
default:
564+
return-EBUSY;
565+
}
566+
567+
while (cl->state!=MEI_FILE_INITIALIZING&&
568+
cl->state!=MEI_FILE_DISCONNECTED&&
569+
cl->state!=MEI_FILE_CONNECTED) {
570+
mutex_unlock(&dev->device_lock);
571+
wait_event_timeout(cl->wait,
572+
(cl->state==MEI_FILE_CONNECTED||
573+
cl->state==MEI_FILE_DISCONNECTED||
574+
cl->state==MEI_FILE_DISCONNECT_REQUIRED||
575+
cl->state==MEI_FILE_DISCONNECT_REPLY),
576+
mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
577+
mutex_lock(&dev->device_lock);
578+
}
579+
580+
if (!mei_cl_is_connected(cl))
581+
returnmei_ioctl_connect_client(file,in_client_uuid,client);
582+
583+
client->max_msg_length=cl->me_cl->props.max_msg_length;
584+
client->protocol_version=cl->me_cl->props.protocol_version;
585+
586+
return0;
587+
}
588+
463589
/**
464590
* mei_ioctl_client_notify_request -
465591
* propagate event notification request to client
@@ -516,7 +642,11 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
516642
{
517643
structmei_device*dev;
518644
structmei_cl*cl=file->private_data;
519-
structmei_connect_client_dataconnect_data;
645+
structmei_connect_client_dataconn;
646+
structmei_connect_client_data_vtagconn_vtag;
647+
constuuid_le*cl_uuid;
648+
structmei_client*props;
649+
u8vtag;
520650
u32notify_get,notify_req;
521651
intrets;
522652

@@ -537,20 +667,68 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
537667
switch (cmd) {
538668
caseIOCTL_MEI_CONNECT_CLIENT:
539669
dev_dbg(dev->dev,": IOCTL_MEI_CONNECT_CLIENT.\n");
540-
if (copy_from_user(&connect_data, (char__user*)data,
541-
sizeof(connect_data))) {
670+
if (copy_from_user(&conn, (char__user*)data,sizeof(conn))) {
671+
dev_dbg(dev->dev,"failed to copy data from userland\n");
672+
rets=-EFAULT;
673+
gotoout;
674+
}
675+
cl_uuid=&conn.in_client_uuid;
676+
props=&conn.out_client_properties;
677+
vtag=0;
678+
679+
rets=mei_vt_support_check(dev,cl_uuid);
680+
if (rets==-ENOTTY)
681+
gotoout;
682+
if (!rets)
683+
rets=mei_ioctl_connect_vtag(file,cl_uuid,props,
684+
vtag);
685+
else
686+
rets=mei_ioctl_connect_client(file,cl_uuid,props);
687+
if (rets)
688+
gotoout;
689+
690+
/* if all is ok, copying the data back to user. */
691+
if (copy_to_user((char__user*)data,&conn,sizeof(conn))) {
692+
dev_dbg(dev->dev,"failed to copy data to userland\n");
693+
rets=-EFAULT;
694+
gotoout;
695+
}
696+
697+
break;
698+
699+
caseIOCTL_MEI_CONNECT_CLIENT_VTAG:
700+
dev_dbg(dev->dev,"IOCTL_MEI_CONNECT_CLIENT_VTAG\n");
701+
if (copy_from_user(&conn_vtag, (char__user*)data,
702+
sizeof(conn_vtag))) {
542703
dev_dbg(dev->dev,"failed to copy data from userland\n");
543704
rets=-EFAULT;
544705
gotoout;
545706
}
546707

547-
rets=mei_ioctl_connect_client(file,&connect_data);
708+
cl_uuid=&conn_vtag.connect.in_client_uuid;
709+
props=&conn_vtag.out_client_properties;
710+
vtag=conn_vtag.connect.vtag;
711+
712+
rets=mei_vt_support_check(dev,cl_uuid);
713+
if (rets==-EOPNOTSUPP)
714+
dev_dbg(dev->dev,"FW Client %pUl does not support vtags\n",
715+
cl_uuid);
716+
if (rets)
717+
gotoout;
718+
719+
if (!vtag) {
720+
dev_dbg(dev->dev,"vtag can't be zero\n");
721+
rets=-EINVAL;
722+
gotoout;
723+
}
724+
725+
rets=mei_ioctl_connect_vtag(file,cl_uuid,props,vtag);
548726
if (rets)
549727
gotoout;
550728

551729
/* if all is ok, copying the data back to user. */
552-
if (copy_to_user((char__user*)data,&connect_data,
553-
sizeof(connect_data))) {
730+
if (copy_to_user((char__user*)data,&conn_vtag,
731+
sizeof(conn_vtag))) {
554732
dev_dbg(dev->dev,"failed to copy data to userland\n");
555733
rets=-EFAULT;
556734
gotoout;

‎include/uapi/linux/mei.h‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,53 @@ struct mei_connect_client_data {
6666
*/
6767
#defineIOCTL_MEI_NOTIFY_GET _IOR('H', 0x03, __u32)
6868

69+
/**
70+
* struct mei_connect_client_vtag - mei client information struct with vtag
71+
*
72+
* @in_client_uuid: UUID of client to connect
73+
* @vtag: virtual tag
74+
* @reserved: reserved for future use
75+
*/
76+
structmei_connect_client_vtag {
77+
uuid_lein_client_uuid;
78+
__u8vtag;
79+
__u8reserved[3];
80+
};
81+
82+
/**
83+
* struct mei_connect_client_data_vtag - IOCTL connect data union
84+
*
85+
* @connect: input connect data
86+
* @out_client_properties: output client data
87+
*/
88+
structmei_connect_client_data_vtag {
89+
union {
90+
structmei_connect_client_vtagconnect;
91+
structmei_clientout_client_properties;
92+
};
93+
};
94+
95+
/**
96+
* DOC:
97+
* This IOCTL is used to associate the current file descriptor with a
98+
* FW Client (given by UUID), and virtual tag (vtag).
99+
* The IOCTL opens a communication channel between a host client and
100+
* a FW client on a tagged channel. From this point on, every read
101+
* and write will communicate with the associated FW client with
102+
* on the tagged channel.
103+
* Upone close() the communication is terminated.
104+
*
105+
* The IOCTL argument is a struct with a union that contains
106+
* the input parameter and the output parameter for this IOCTL.
107+
*
108+
* The input parameter is UUID of the FW Client, a vtag [0,255]
109+
* The output parameter is the properties of the FW client
110+
* (FW protocool version and max message size).
111+
*
112+
* Clients that do not support tagged connection
113+
* will respond with -EOPNOTSUPP.
114+
*/
115+
#defineIOCTL_MEI_CONNECT_CLIENT_VTAG \
116+
_IOWR('H', 0x04, struct mei_connect_client_data_vtag)
117+
69118
#endif/* _LINUX_MEI_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp